• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/samba-3.0.25b/source/rpc_server/
1/*
2 *  Unix SMB/CIFS implementation.
3 *  RPC Pipe client / server routines
4 *  Copyright (C) Andrew Tridgell              1992-1997,
5 *  Copyright (C) Jeremy Allison               2001.
6 *  Copyright (C) Nigel Williams               2001.
7 *  Copyright (C) Gerald (Jerry) Carter        2006.
8 *
9 *  This program is free software; you can redistribute it and/or modify
10 *  it under the terms of the GNU General Public License as published by
11 *  the Free Software Foundation; either version 2 of the License, or
12 *  (at your option) any later version.
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24/* This is the implementation of the srvsvc pipe. */
25
26#include "includes.h"
27
28extern struct generic_mapping file_generic_mapping;
29
30#undef DBGC_CLASS
31#define DBGC_CLASS DBGC_RPC_SRV
32
33/* Use for enumerating connections, pipes, & files */
34
35struct file_enum_count {
36	TALLOC_CTX *ctx;
37	int count;
38	FILE_INFO_3 *info;
39};
40
41struct sess_file_count {
42	pid_t pid;
43	uid_t uid;
44	int count;
45};
46
47/****************************************************************************
48 Count the entries belonging to a service in the connection db.
49****************************************************************************/
50
51static int pipe_enum_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p)
52{
53	struct pipe_open_rec prec;
54	struct file_enum_count *fenum = (struct file_enum_count *)p;
55
56	if (dbuf.dsize != sizeof(struct pipe_open_rec))
57		return 0;
58
59	memcpy(&prec, dbuf.dptr, sizeof(struct pipe_open_rec));
60
61	if ( process_exists(prec.pid) ) {
62		FILE_INFO_3 *f;
63		int i = fenum->count;
64		pstring fullpath;
65
66		snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
67
68		f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, FILE_INFO_3, i+1 );
69		if ( !f ) {
70			DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
71			return 1;
72		}
73		fenum->info = f;
74
75
76		init_srv_file_info3( &fenum->info[i],
77			(uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum),
78			(FILE_READ_DATA|FILE_WRITE_DATA),
79			0,
80			uidtoname( prec.uid ),
81			fullpath );
82
83		fenum->count++;
84	}
85
86	return 0;
87}
88
89/*******************************************************************
90********************************************************************/
91
92static WERROR net_enum_pipes( TALLOC_CTX *ctx, FILE_INFO_3 **info,
93                              uint32 *count, uint32 resume )
94{
95	struct file_enum_count fenum;
96	TDB_CONTEXT *conn_tdb = conn_tdb_ctx();
97
98	if ( !conn_tdb ) {
99		DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
100		return WERR_ACCESS_DENIED;
101	}
102
103	fenum.ctx = ctx;
104	fenum.count = *count;
105	fenum.info = *info;
106
107	if (tdb_traverse(conn_tdb, pipe_enum_fn, &fenum) == -1) {
108		DEBUG(0,("net_enum_pipes: traverse of connections.tdb failed with error %s.\n",
109			tdb_errorstr(conn_tdb) ));
110		return WERR_NOMEM;
111	}
112
113	*info  = fenum.info;
114	*count = fenum.count;
115
116	return WERR_OK;}
117
118/*******************************************************************
119********************************************************************/
120
121/* global needed to make use of the share_mode_forall() callback */
122static struct file_enum_count f_enum_cnt;
123
124static void enum_file_fn( const struct share_mode_entry *e,
125                          const char *sharepath, const char *fname, void *state )
126{
127	struct file_enum_count *fenum = &f_enum_cnt;
128
129	/* If the pid was not found delete the entry from connections.tdb */
130
131	if ( process_exists(e->pid) ) {
132		FILE_INFO_3 *f;
133		int i = fenum->count;
134		files_struct fsp;
135		struct byte_range_lock *brl;
136		int num_locks = 0;
137		pstring fullpath;
138		uint32 permissions;
139
140		f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, FILE_INFO_3, i+1 );
141		if ( !f ) {
142			DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
143			return;
144		}
145		fenum->info = f;
146
147		/* need to count the number of locks on a file */
148
149		ZERO_STRUCT( fsp );
150		fsp.dev   = e->dev;
151		fsp.inode = e->inode;
152
153		if ( (brl = brl_get_locks(NULL,&fsp)) != NULL ) {
154			num_locks = brl->num_locks;
155			TALLOC_FREE( brl );
156		}
157
158		if ( strcmp( fname, "." ) == 0 ) {
159			pstr_sprintf( fullpath, "C:%s", sharepath );
160		} else {
161			pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
162		}
163		string_replace( fullpath, '/', '\\' );
164
165		/* mask out create (what ever that is) */
166		permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
167
168		/* now fill in the FILE_INFO_3 struct */
169		init_srv_file_info3( &fenum->info[i],
170			e->share_file_id,
171			permissions,
172			num_locks,
173			uidtoname(e->uid),
174			fullpath );
175
176		fenum->count++;
177	}
178
179	return;
180
181}
182
183/*******************************************************************
184********************************************************************/
185
186static WERROR net_enum_files( TALLOC_CTX *ctx, FILE_INFO_3 **info,
187                              uint32 *count, uint32 resume )
188{
189	f_enum_cnt.ctx = ctx;
190	f_enum_cnt.count = *count;
191	f_enum_cnt.info = *info;
192
193	share_mode_forall( enum_file_fn, NULL );
194
195	*info  = f_enum_cnt.info;
196	*count = f_enum_cnt.count;
197
198	return WERR_OK;
199}
200
201/*******************************************************************
202 Utility function to get the 'type' of a share from an snum.
203 ********************************************************************/
204static uint32 get_share_type(int snum)
205{
206	char *net_name = lp_servicename(snum);
207	int len_net_name = strlen(net_name);
208
209	/* work out the share type */
210	uint32 type = STYPE_DISKTREE;
211
212	if (lp_print_ok(snum))
213		type = STYPE_PRINTQ;
214	if (strequal(lp_fstype(snum), "IPC"))
215		type = STYPE_IPC;
216	if (net_name[len_net_name-1] == '$')
217		type |= STYPE_HIDDEN;
218
219	return type;
220}
221
222/*******************************************************************
223 Fill in a share info level 0 structure.
224 ********************************************************************/
225
226static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum)
227{
228	pstring net_name;
229
230	pstrcpy(net_name, lp_servicename(snum));
231
232	init_srv_share_info0(&sh0->info_0, net_name);
233	init_srv_share_info0_str(&sh0->info_0_str, net_name);
234}
235
236/*******************************************************************
237 Fill in a share info level 1 structure.
238 ********************************************************************/
239
240static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
241{
242	pstring remark;
243
244	char *net_name = lp_servicename(snum);
245	pstrcpy(remark, lp_comment(snum));
246	standard_sub_conn(p->conn, remark,sizeof(remark));
247
248	init_srv_share_info1(&sh1->info_1, net_name, get_share_type(snum), remark);
249	init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
250}
251
252/*******************************************************************
253 Fill in a share info level 2 structure.
254 ********************************************************************/
255
256static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
257{
258	pstring remark;
259	pstring path;
260	pstring passwd;
261	int max_connections = lp_max_connections(snum);
262	uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
263	int count = 0;
264	char *net_name = lp_servicename(snum);
265
266	pstrcpy(remark, lp_comment(snum));
267	standard_sub_conn(p->conn, remark,sizeof(remark));
268	pstrcpy(path, "C:");
269	pstrcat(path, lp_pathname(snum));
270
271	/*
272	 * Change / to \\ so that win2k will see it as a valid path.  This was added to
273	 * enable use of browsing in win2k add share dialog.
274	 */
275
276	string_replace(path, '/', '\\');
277
278	pstrcpy(passwd, "");
279
280	count = count_current_connections( net_name, False  );
281	init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum),
282		remark, 0, max_uses, count, path, passwd);
283
284	init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
285}
286
287/*******************************************************************
288 Map any generic bits to file specific bits.
289********************************************************************/
290
291static void map_generic_share_sd_bits(SEC_DESC *psd)
292{
293	int i;
294	SEC_ACL *ps_dacl = NULL;
295
296	if (!psd)
297		return;
298
299	ps_dacl = psd->dacl;
300	if (!ps_dacl)
301		return;
302
303	for (i = 0; i < ps_dacl->num_aces; i++) {
304		SEC_ACE *psa = &ps_dacl->aces[i];
305		uint32 orig_mask = psa->access_mask;
306
307		se_map_generic(&psa->access_mask, &file_generic_mapping);
308		psa->access_mask |= orig_mask;
309	}
310}
311
312/*******************************************************************
313 Fill in a share info level 501 structure.
314********************************************************************/
315
316static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
317{
318	pstring remark;
319
320	const char *net_name = lp_servicename(snum);
321	pstrcpy(remark, lp_comment(snum));
322	standard_sub_conn(p->conn, remark, sizeof(remark));
323
324	init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
325	init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
326}
327
328/*******************************************************************
329 Fill in a share info level 502 structure.
330 ********************************************************************/
331
332static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
333{
334	pstring net_name;
335	pstring remark;
336	pstring path;
337	pstring passwd;
338	SEC_DESC *sd;
339	size_t sd_size;
340	TALLOC_CTX *ctx = p->mem_ctx;
341
342
343	ZERO_STRUCTP(sh502);
344
345	pstrcpy(net_name, lp_servicename(snum));
346	pstrcpy(remark, lp_comment(snum));
347	standard_sub_conn(p->conn, remark,sizeof(remark));
348	pstrcpy(path, "C:");
349	pstrcat(path, lp_pathname(snum));
350
351	/*
352	 * Change / to \\ so that win2k will see it as a valid path.  This was added to
353	 * enable use of browsing in win2k add share dialog.
354	 */
355
356	string_replace(path, '/', '\\');
357
358	pstrcpy(passwd, "");
359
360	sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
361
362	init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
363	init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size);
364}
365
366/***************************************************************************
367 Fill in a share info level 1004 structure.
368 ***************************************************************************/
369
370static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
371{
372        pstring remark;
373
374	pstrcpy(remark, lp_comment(snum));
375	standard_sub_conn(p->conn, remark, sizeof(remark));
376
377	ZERO_STRUCTP(sh1004);
378
379	init_srv_share_info1004(&sh1004->info_1004, remark);
380	init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
381}
382
383/***************************************************************************
384 Fill in a share info level 1005 structure.
385 ***************************************************************************/
386
387static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum)
388{
389	sh1005->share_info_flags = 0;
390
391	if(lp_host_msdfs() && lp_msdfs_root(snum))
392		sh1005->share_info_flags |=
393			SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
394	sh1005->share_info_flags |=
395		lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
396}
397/***************************************************************************
398 Fill in a share info level 1006 structure.
399 ***************************************************************************/
400
401static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
402{
403	sh1006->max_uses = -1;
404}
405
406/***************************************************************************
407 Fill in a share info level 1007 structure.
408 ***************************************************************************/
409
410static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
411{
412        pstring alternate_directory_name = "";
413	uint32 flags = 0;
414
415	ZERO_STRUCTP(sh1007);
416
417	init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name);
418	init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name);
419}
420
421/*******************************************************************
422 Fill in a share info level 1501 structure.
423 ********************************************************************/
424
425static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
426{
427	SEC_DESC *sd;
428	size_t sd_size;
429	TALLOC_CTX *ctx = p->mem_ctx;
430
431	ZERO_STRUCTP(sh1501);
432
433	sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
434
435	sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
436}
437
438/*******************************************************************
439 True if it ends in '$'.
440 ********************************************************************/
441
442static BOOL is_hidden_share(int snum)
443{
444	const char *net_name = lp_servicename(snum);
445
446	return (net_name[strlen(net_name) - 1] == '$') ? True : False;
447}
448
449/*******************************************************************
450 Fill in a share info structure.
451 ********************************************************************/
452
453static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
454	       uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
455{
456	int num_entries = 0;
457	int num_services = 0;
458	int snum;
459	TALLOC_CTX *ctx = p->mem_ctx;
460
461	DEBUG(5,("init_srv_share_info_ctr\n"));
462
463	ZERO_STRUCTPN(ctr);
464
465	ctr->info_level = ctr->switch_value = info_level;
466	*resume_hnd = 0;
467
468	/* Ensure all the usershares are loaded. */
469	become_root();
470	num_services = load_usershare_shares();
471	unbecome_root();
472
473	/* Count the number of entries. */
474	for (snum = 0; snum < num_services; snum++) {
475		if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
476			num_entries++;
477	}
478
479	*total_entries = num_entries;
480	ctr->num_entries2 = ctr->num_entries = num_entries;
481	ctr->ptr_share_info = ctr->ptr_entries = 1;
482
483	if (!num_entries)
484		return True;
485
486	switch (info_level) {
487	case 0:
488	{
489		SRV_SHARE_INFO_0 *info0 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_0, num_entries);
490		int i = 0;
491
492		if (!info0) {
493			return False;
494		}
495
496		for (snum = *resume_hnd; snum < num_services; snum++) {
497			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
498				init_srv_share_info_0(p, &info0[i++], snum);
499			}
500		}
501
502		ctr->share.info0 = info0;
503		break;
504
505	}
506
507	case 1:
508	{
509		SRV_SHARE_INFO_1 *info1 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1, num_entries);
510		int i = 0;
511
512		if (!info1) {
513			return False;
514		}
515
516		for (snum = *resume_hnd; snum < num_services; snum++) {
517			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
518				init_srv_share_info_1(p, &info1[i++], snum);
519			}
520		}
521
522		ctr->share.info1 = info1;
523		break;
524	}
525
526	case 2:
527	{
528		SRV_SHARE_INFO_2 *info2 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_2, num_entries);
529		int i = 0;
530
531		if (!info2) {
532			return False;
533		}
534
535		for (snum = *resume_hnd; snum < num_services; snum++) {
536			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
537				init_srv_share_info_2(p, &info2[i++], snum);
538			}
539		}
540
541		ctr->share.info2 = info2;
542		break;
543	}
544
545	case 501:
546	{
547		SRV_SHARE_INFO_501 *info501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_501, num_entries);
548		int i = 0;
549
550		if (!info501) {
551			return False;
552		}
553
554		for (snum = *resume_hnd; snum < num_services; snum++) {
555			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
556				init_srv_share_info_501(p, &info501[i++], snum);
557			}
558		}
559
560		ctr->share.info501 = info501;
561		break;
562	}
563
564	case 502:
565	{
566		SRV_SHARE_INFO_502 *info502 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_502, num_entries);
567		int i = 0;
568
569		if (!info502) {
570			return False;
571		}
572
573		for (snum = *resume_hnd; snum < num_services; snum++) {
574			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
575				init_srv_share_info_502(p, &info502[i++], snum);
576			}
577		}
578
579		ctr->share.info502 = info502;
580		break;
581	}
582
583	/* here for completeness but not currently used with enum (1004 - 1501)*/
584
585	case 1004:
586	{
587		SRV_SHARE_INFO_1004 *info1004 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1004, num_entries);
588		int i = 0;
589
590		if (!info1004) {
591			return False;
592		}
593
594		for (snum = *resume_hnd; snum < num_services; snum++) {
595			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
596				init_srv_share_info_1004(p, &info1004[i++], snum);
597			}
598		}
599
600		ctr->share.info1004 = info1004;
601		break;
602	}
603
604	case 1005:
605	{
606		SRV_SHARE_INFO_1005 *info1005 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1005, num_entries);
607		int i = 0;
608
609		if (!info1005) {
610			return False;
611		}
612
613		for (snum = *resume_hnd; snum < num_services; snum++) {
614			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
615				init_srv_share_info_1005(p, &info1005[i++], snum);
616			}
617		}
618
619		ctr->share.info1005 = info1005;
620		break;
621	}
622
623	case 1006:
624	{
625		SRV_SHARE_INFO_1006 *info1006 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1006, num_entries);
626		int i = 0;
627
628		if (!info1006) {
629			return False;
630		}
631
632		for (snum = *resume_hnd; snum < num_services; snum++) {
633			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
634				init_srv_share_info_1006(p, &info1006[i++], snum);
635			}
636		}
637
638		ctr->share.info1006 = info1006;
639		break;
640	}
641
642	case 1007:
643	{
644		SRV_SHARE_INFO_1007 *info1007 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1007, num_entries);
645		int i = 0;
646
647		if (!info1007) {
648			return False;
649		}
650
651		for (snum = *resume_hnd; snum < num_services; snum++) {
652			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
653				init_srv_share_info_1007(p, &info1007[i++], snum);
654			}
655		}
656
657		ctr->share.info1007 = info1007;
658		break;
659	}
660
661	case 1501:
662	{
663		SRV_SHARE_INFO_1501 *info1501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1501, num_entries);
664		int i = 0;
665
666		if (!info1501) {
667			return False;
668		}
669
670		for (snum = *resume_hnd; snum < num_services; snum++) {
671			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
672				init_srv_share_info_1501(p, &info1501[i++], snum);
673			}
674		}
675
676		ctr->share.info1501 = info1501;
677		break;
678	}
679	default:
680		DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
681		return False;
682	}
683
684	return True;
685}
686
687/*******************************************************************
688 Inits a SRV_R_NET_SHARE_ENUM structure.
689********************************************************************/
690
691static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
692				      uint32 info_level, uint32 resume_hnd, BOOL all)
693{
694	DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
695
696	if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
697				    &resume_hnd, &r_n->total_entries, all)) {
698		r_n->status = WERR_OK;
699	} else {
700		r_n->status = WERR_UNKNOWN_LEVEL;
701	}
702
703	init_enum_hnd(&r_n->enum_hnd, resume_hnd);
704}
705
706/*******************************************************************
707 Inits a SRV_R_NET_SHARE_GET_INFO structure.
708********************************************************************/
709
710static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
711				  char *share_name, uint32 info_level)
712{
713	WERROR status = WERR_OK;
714	int snum;
715
716	DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
717
718	r_n->info.switch_value = info_level;
719
720	snum = find_service(share_name);
721
722	if (snum >= 0) {
723		switch (info_level) {
724		case 0:
725			init_srv_share_info_0(p, &r_n->info.share.info0, snum);
726			break;
727		case 1:
728			init_srv_share_info_1(p, &r_n->info.share.info1, snum);
729			break;
730		case 2:
731			init_srv_share_info_2(p, &r_n->info.share.info2, snum);
732			break;
733		case 501:
734			init_srv_share_info_501(p, &r_n->info.share.info501, snum);
735			break;
736		case 502:
737			init_srv_share_info_502(p, &r_n->info.share.info502, snum);
738			break;
739
740			/* here for completeness */
741		case 1004:
742			init_srv_share_info_1004(p, &r_n->info.share.info1004, snum);
743			break;
744		case 1005:
745			init_srv_share_info_1005(p, &r_n->info.share.info1005, snum);
746			break;
747
748			/* here for completeness 1006 - 1501 */
749		case 1006:
750			init_srv_share_info_1006(p, &r_n->info.share.info1006, snum);
751			break;
752		case 1007:
753			init_srv_share_info_1007(p, &r_n->info.share.info1007, snum);
754			break;
755		case 1501:
756			init_srv_share_info_1501(p, &r_n->info.share.info1501, snum);
757			break;
758		default:
759			DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
760			status = WERR_UNKNOWN_LEVEL;
761			break;
762		}
763	} else {
764		status = WERR_INVALID_NAME;
765	}
766
767	r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
768	r_n->status = status;
769}
770
771/*******************************************************************
772 fill in a sess info level 0 structure.
773 ********************************************************************/
774
775static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
776{
777	struct sessionid *session_list;
778	uint32 num_entries = 0;
779	(*stot) = list_sessions(&session_list);
780
781	if (ss0 == NULL) {
782		if (snum) {
783			(*snum) = 0;
784		}
785		SAFE_FREE(session_list);
786		return;
787	}
788
789	DEBUG(5,("init_srv_sess_0_ss0\n"));
790
791	if (snum) {
792		for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
793			init_srv_sess_info0( &ss0->info_0[num_entries], session_list[(*snum)].remote_machine);
794			num_entries++;
795		}
796
797		ss0->num_entries_read  = num_entries;
798		ss0->ptr_sess_info     = num_entries > 0 ? 1 : 0;
799		ss0->num_entries_read2 = num_entries;
800
801		if ((*snum) >= (*stot)) {
802			(*snum) = 0;
803		}
804
805	} else {
806		ss0->num_entries_read = 0;
807		ss0->ptr_sess_info = 0;
808		ss0->num_entries_read2 = 0;
809	}
810	SAFE_FREE(session_list);
811}
812
813/*******************************************************************
814********************************************************************/
815
816/* global needed to make use of the share_mode_forall() callback */
817static struct sess_file_count s_file_cnt;
818
819static void sess_file_fn( const struct share_mode_entry *e,
820                          const char *sharepath, const char *fname, void *state )
821{
822	struct sess_file_count *sess = &s_file_cnt;
823
824	if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
825		sess->count++;
826	}
827
828	return;
829}
830
831/*******************************************************************
832********************************************************************/
833
834static int net_count_files( uid_t uid, pid_t pid )
835{
836	s_file_cnt.count = 0;
837	s_file_cnt.uid = uid;
838	s_file_cnt.pid = pid;
839
840	share_mode_forall( sess_file_fn, NULL );
841
842	return s_file_cnt.count;
843}
844
845/*******************************************************************
846 fill in a sess info level 1 structure.
847 ********************************************************************/
848
849static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
850{
851	struct sessionid *session_list;
852	uint32 num_entries = 0;
853	time_t now = time(NULL);
854
855	if ( !snum ) {
856		ss1->num_entries_read = 0;
857		ss1->ptr_sess_info = 0;
858		ss1->num_entries_read2 = 0;
859
860		(*stot) = 0;
861
862		return;
863	}
864
865	if (ss1 == NULL) {
866		(*snum) = 0;
867		return;
868	}
869
870	(*stot) = list_sessions(&session_list);
871
872
873	for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
874		uint32 num_files;
875		uint32 connect_time;
876		struct passwd *pw = sys_getpwnam(session_list[*snum].username);
877		BOOL guest;
878
879		if ( !pw ) {
880			DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
881				session_list[*snum].username));
882			continue;
883		}
884
885		connect_time = (uint32)(now - session_list[*snum].connect_start);
886		num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
887		guest = strequal( session_list[*snum].username, lp_guestaccount() );
888
889		init_srv_sess_info1( &ss1->info_1[num_entries],
890		                     session_list[*snum].remote_machine,
891				     session_list[*snum].username,
892				     num_files,
893				     connect_time,
894				     0,
895				     guest);
896		num_entries++;
897	}
898
899	ss1->num_entries_read  = num_entries;
900	ss1->ptr_sess_info     = num_entries > 0 ? 1 : 0;
901	ss1->num_entries_read2 = num_entries;
902
903	if ((*snum) >= (*stot)) {
904		(*snum) = 0;
905	}
906
907	SAFE_FREE(session_list);
908}
909
910/*******************************************************************
911 makes a SRV_R_NET_SESS_ENUM structure.
912********************************************************************/
913
914static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
915				int switch_value, uint32 *resume_hnd, uint32 *total_entries)
916{
917	WERROR status = WERR_OK;
918	DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
919
920	ctr->switch_value = switch_value;
921
922	switch (switch_value) {
923	case 0:
924		init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
925		ctr->ptr_sess_ctr = 1;
926		break;
927	case 1:
928		init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
929		ctr->ptr_sess_ctr = 1;
930		break;
931	default:
932		DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
933		(*resume_hnd) = 0;
934		(*total_entries) = 0;
935		ctr->ptr_sess_ctr = 0;
936		status = WERR_UNKNOWN_LEVEL;
937		break;
938	}
939
940	return status;
941}
942
943/*******************************************************************
944 makes a SRV_R_NET_SESS_ENUM structure.
945********************************************************************/
946
947static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
948				uint32 resume_hnd, int sess_level, int switch_value)
949{
950	DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
951
952	r_n->sess_level  = sess_level;
953
954	if (sess_level == -1)
955		r_n->status = WERR_UNKNOWN_LEVEL;
956	else
957		r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
958
959	if (!W_ERROR_IS_OK(r_n->status))
960		resume_hnd = 0;
961
962	init_enum_hnd(&r_n->enum_hnd, resume_hnd);
963}
964
965/*******************************************************************
966 fill in a conn info level 0 structure.
967 ********************************************************************/
968
969static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
970{
971	uint32 num_entries = 0;
972	(*stot) = 1;
973
974	if (ss0 == NULL) {
975		(*snum) = 0;
976		return;
977	}
978
979	DEBUG(5,("init_srv_conn_0_ss0\n"));
980
981	if (snum) {
982		for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
983
984			init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
985
986			/* move on to creating next connection */
987			/* move on to creating next conn */
988			num_entries++;
989		}
990
991		ss0->num_entries_read  = num_entries;
992		ss0->ptr_conn_info     = num_entries > 0 ? 1 : 0;
993		ss0->num_entries_read2 = num_entries;
994
995		if ((*snum) >= (*stot)) {
996			(*snum) = 0;
997		}
998
999	} else {
1000		ss0->num_entries_read = 0;
1001		ss0->ptr_conn_info = 0;
1002		ss0->num_entries_read2 = 0;
1003
1004		(*stot) = 0;
1005	}
1006}
1007
1008/*******************************************************************
1009 fill in a conn info level 1 structure.
1010 ********************************************************************/
1011
1012static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1013				uint32 id, uint32 type,
1014				uint32 num_opens, uint32 num_users, uint32 open_time,
1015				const char *usr_name, const char *net_name)
1016{
1017	init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1018	init_srv_conn_info1_str(str1, usr_name, net_name);
1019}
1020
1021/*******************************************************************
1022 fill in a conn info level 1 structure.
1023 ********************************************************************/
1024
1025static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1026{
1027	uint32 num_entries = 0;
1028	(*stot) = 1;
1029
1030	if (ss1 == NULL) {
1031		(*snum) = 0;
1032		return;
1033	}
1034
1035	DEBUG(5,("init_srv_conn_1_ss1\n"));
1036
1037	if (snum) {
1038		for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1039			init_srv_conn_1_info(&ss1->info_1[num_entries],
1040								 &ss1->info_1_str[num_entries],
1041			                     (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1042
1043			/* move on to creating next connection */
1044			/* move on to creating next conn */
1045			num_entries++;
1046		}
1047
1048		ss1->num_entries_read  = num_entries;
1049		ss1->ptr_conn_info     = num_entries > 0 ? 1 : 0;
1050		ss1->num_entries_read2 = num_entries;
1051
1052
1053		if ((*snum) >= (*stot)) {
1054			(*snum) = 0;
1055		}
1056
1057	} else {
1058		ss1->num_entries_read = 0;
1059		ss1->ptr_conn_info = 0;
1060		ss1->num_entries_read2 = 0;
1061
1062		(*stot) = 0;
1063	}
1064}
1065
1066/*******************************************************************
1067 makes a SRV_R_NET_CONN_ENUM structure.
1068********************************************************************/
1069
1070static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1071				int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1072{
1073	WERROR status = WERR_OK;
1074	DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1075
1076	ctr->switch_value = switch_value;
1077
1078	switch (switch_value) {
1079	case 0:
1080		init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1081		ctr->ptr_conn_ctr = 1;
1082		break;
1083	case 1:
1084		init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1085		ctr->ptr_conn_ctr = 1;
1086		break;
1087	default:
1088		DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1089		(*resume_hnd = 0);
1090		(*total_entries) = 0;
1091		ctr->ptr_conn_ctr = 0;
1092		status = WERR_UNKNOWN_LEVEL;
1093		break;
1094	}
1095
1096	return status;
1097}
1098
1099/*******************************************************************
1100 makes a SRV_R_NET_CONN_ENUM structure.
1101********************************************************************/
1102
1103static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1104				uint32 resume_hnd, int conn_level, int switch_value)
1105{
1106	DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1107
1108	r_n->conn_level  = conn_level;
1109	if (conn_level == -1)
1110		r_n->status = WERR_UNKNOWN_LEVEL;
1111	else
1112		r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1113
1114	if (!W_ERROR_IS_OK(r_n->status))
1115		resume_hnd = 0;
1116
1117	init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1118}
1119
1120/*******************************************************************
1121 makes a SRV_R_NET_FILE_ENUM structure.
1122********************************************************************/
1123
1124static WERROR net_file_enum_3( SRV_R_NET_FILE_ENUM *r, uint32 resume_hnd )
1125{
1126	TALLOC_CTX *ctx = get_talloc_ctx();
1127	SRV_FILE_INFO_CTR *ctr = &r->ctr;
1128
1129	/* TODO -- Windows enumerates
1130	   (b) active pipes
1131	   (c) open directories and files */
1132
1133	r->status = net_enum_files( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
1134	if ( !W_ERROR_IS_OK(r->status))
1135		goto done;
1136
1137	r->status = net_enum_pipes( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
1138	if ( !W_ERROR_IS_OK(r->status))
1139		goto done;
1140
1141	r->level = ctr->level = 3;
1142	r->total_entries = ctr->num_entries;
1143	/* ctr->num_entries = r->total_entries - resume_hnd; */
1144	ctr->num_entries2 = ctr->num_entries;
1145	ctr->ptr_file_info = 1;
1146
1147	r->status = WERR_OK;
1148
1149done:
1150	if ( ctr->num_entries > 0 )
1151		ctr->ptr_entries = 1;
1152
1153	init_enum_hnd(&r->enum_hnd, 0);
1154
1155	return r->status;
1156}
1157
1158/*******************************************************************
1159*******************************************************************/
1160
1161WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1162{
1163	switch ( q_u->level ) {
1164	case 3:
1165		return net_file_enum_3( r_u, get_enum_hnd(&q_u->enum_hnd) );
1166	default:
1167		return WERR_UNKNOWN_LEVEL;
1168	}
1169
1170	return WERR_OK;
1171}
1172
1173/*******************************************************************
1174net server get info
1175********************************************************************/
1176
1177WERROR _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u)
1178{
1179	WERROR status = WERR_OK;
1180	SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR);
1181
1182	if (!ctr)
1183		return WERR_NOMEM;
1184
1185	ZERO_STRUCTP(ctr);
1186
1187	DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1188
1189	if (!pipe_access_check(p)) {
1190		DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1191		return WERR_ACCESS_DENIED;
1192	}
1193
1194	switch (q_u->switch_value) {
1195
1196		/* Technically level 102 should only be available to
1197		   Administrators but there isn't anything super-secret
1198		   here, as most of it is made up. */
1199
1200	case 102:
1201		init_srv_info_102(&ctr->srv.sv102,
1202		                  500, global_myname(),
1203				  string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1204		                  lp_major_announce_version(), lp_minor_announce_version(),
1205		                  lp_default_server_announce(),
1206		                  0xffffffff, /* users */
1207		                  0xf, /* disc */
1208		                  0, /* hidden */
1209		                  240, /* announce */
1210		                  3000, /* announce delta */
1211		                  100000, /* licenses */
1212		                  "c:\\"); /* user path */
1213		break;
1214	case 101:
1215		init_srv_info_101(&ctr->srv.sv101,
1216		                  500, global_myname(),
1217		                  lp_major_announce_version(), lp_minor_announce_version(),
1218		                  lp_default_server_announce(),
1219		                  string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1220		break;
1221	case 100:
1222		init_srv_info_100(&ctr->srv.sv100, 500, global_myname());
1223		break;
1224	default:
1225		status = WERR_UNKNOWN_LEVEL;
1226		break;
1227	}
1228
1229	/* set up the net server get info structure */
1230	init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1231
1232	DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1233
1234	return r_u->status;
1235}
1236
1237/*******************************************************************
1238net server set info
1239********************************************************************/
1240
1241WERROR _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u)
1242{
1243	WERROR status = WERR_OK;
1244
1245	DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1246
1247	/* Set up the net server set info structure. */
1248
1249	init_srv_r_net_srv_set_info(r_u, 0x0, status);
1250
1251	DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1252
1253	return r_u->status;
1254}
1255
1256/*******************************************************************
1257net conn enum
1258********************************************************************/
1259
1260WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1261{
1262	DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1263
1264	r_u->ctr = TALLOC_P(p->mem_ctx, SRV_CONN_INFO_CTR);
1265	if (!r_u->ctr)
1266		return WERR_NOMEM;
1267
1268	ZERO_STRUCTP(r_u->ctr);
1269
1270	/* set up the */
1271	init_srv_r_net_conn_enum(r_u,
1272				get_enum_hnd(&q_u->enum_hnd),
1273				q_u->conn_level,
1274				q_u->ctr->switch_value);
1275
1276	DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1277
1278	return r_u->status;
1279}
1280
1281/*******************************************************************
1282net sess enum
1283********************************************************************/
1284
1285WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1286{
1287	DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1288
1289	r_u->ctr = TALLOC_P(p->mem_ctx, SRV_SESS_INFO_CTR);
1290	if (!r_u->ctr)
1291		return WERR_NOMEM;
1292
1293	ZERO_STRUCTP(r_u->ctr);
1294
1295	/* set up the */
1296	init_srv_r_net_sess_enum(r_u,
1297				get_enum_hnd(&q_u->enum_hnd),
1298				q_u->sess_level,
1299				q_u->ctr->switch_value);
1300
1301	DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1302
1303	return r_u->status;
1304}
1305
1306/*******************************************************************
1307net sess del
1308********************************************************************/
1309
1310WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u)
1311{
1312	struct sessionid *session_list;
1313	struct current_user user;
1314	int num_sessions, snum;
1315	fstring username;
1316	fstring machine;
1317	BOOL not_root = False;
1318
1319	rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name);
1320	rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name);
1321
1322	/* strip leading backslashes if any */
1323	while (machine[0] == '\\') {
1324		memmove(machine, &machine[1], strlen(machine));
1325	}
1326
1327	num_sessions = list_sessions(&session_list);
1328
1329	DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1330
1331	r_u->status = WERR_ACCESS_DENIED;
1332
1333	get_current_user(&user, p);
1334
1335	/* fail out now if you are not root or not a domain admin */
1336
1337	if ((user.ut.uid != sec_initial_uid()) &&
1338		( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1339
1340		goto done;
1341	}
1342
1343	for (snum = 0; snum < num_sessions; snum++) {
1344
1345		if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1346		    strequal(session_list[snum].remote_machine, machine)) {
1347
1348			if (user.ut.uid != sec_initial_uid()) {
1349				not_root = True;
1350				become_root();
1351			}
1352
1353			if (NT_STATUS_IS_OK(message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False)))
1354				r_u->status = WERR_OK;
1355
1356			if (not_root)
1357				unbecome_root();
1358		}
1359	}
1360
1361	DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1362
1363
1364done:
1365	SAFE_FREE(session_list);
1366
1367	return r_u->status;
1368}
1369
1370/*******************************************************************
1371 Net share enum all.
1372********************************************************************/
1373
1374WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1375{
1376	DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1377
1378	if (!pipe_access_check(p)) {
1379		DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1380		return WERR_ACCESS_DENIED;
1381	}
1382
1383	/* Create the list of shares for the response. */
1384	init_srv_r_net_share_enum(p, r_u,
1385				q_u->ctr.info_level,
1386				get_enum_hnd(&q_u->enum_hnd), True);
1387
1388	DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1389
1390	return r_u->status;
1391}
1392
1393/*******************************************************************
1394 Net share enum.
1395********************************************************************/
1396
1397WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1398{
1399	DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1400
1401	if (!pipe_access_check(p)) {
1402		DEBUG(3, ("access denied to srv_net_share_enum\n"));
1403		return WERR_ACCESS_DENIED;
1404	}
1405
1406	/* Create the list of shares for the response. */
1407	init_srv_r_net_share_enum(p, r_u,
1408				  q_u->ctr.info_level,
1409				  get_enum_hnd(&q_u->enum_hnd), False);
1410
1411	DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1412
1413	return r_u->status;
1414}
1415
1416/*******************************************************************
1417 Net share get info.
1418********************************************************************/
1419
1420WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u)
1421{
1422	fstring share_name;
1423
1424	DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1425
1426	/* Create the list of shares for the response. */
1427	unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1428	init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1429
1430	DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1431
1432	return r_u->status;
1433}
1434
1435/*******************************************************************
1436 Check a given DOS pathname is valid for a share.
1437********************************************************************/
1438
1439char *valid_share_pathname(char *dos_pathname)
1440{
1441	char *ptr;
1442
1443	/* Convert any '\' paths to '/' */
1444	unix_format(dos_pathname);
1445	unix_clean_name(dos_pathname);
1446
1447	/* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1448	ptr = dos_pathname;
1449	if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1450		ptr += 2;
1451
1452	/* Only absolute paths allowed. */
1453	if (*ptr != '/')
1454		return NULL;
1455
1456	return ptr;
1457}
1458
1459/*******************************************************************
1460 Net share set info. Modify share details.
1461********************************************************************/
1462
1463WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u)
1464{
1465	struct current_user user;
1466	pstring command;
1467	fstring share_name;
1468	fstring comment;
1469	pstring pathname;
1470	int type;
1471	int snum;
1472	int ret;
1473	char *path;
1474	SEC_DESC *psd = NULL;
1475	SE_PRIV se_diskop = SE_DISK_OPERATOR;
1476	BOOL is_disk_op = False;
1477	int max_connections = 0;
1478
1479	DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1480
1481	unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1482
1483	r_u->parm_error = 0;
1484
1485	if ( strequal(share_name,"IPC$")
1486		|| ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1487		|| strequal(share_name,"global") )
1488	{
1489		return WERR_ACCESS_DENIED;
1490	}
1491
1492	snum = find_service(share_name);
1493
1494	/* Does this share exist ? */
1495	if (snum < 0)
1496		return WERR_NET_NAME_NOT_FOUND;
1497
1498	/* No change to printer shares. */
1499	if (lp_print_ok(snum))
1500		return WERR_ACCESS_DENIED;
1501
1502	get_current_user(&user,p);
1503
1504	is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1505
1506	/* fail out now if you are not root and not a disk op */
1507
1508	if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1509		return WERR_ACCESS_DENIED;
1510
1511	switch (q_u->info_level) {
1512	case 1:
1513		pstrcpy(pathname, lp_pathname(snum));
1514		unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1515		type = q_u->info.share.info2.info_2.type;
1516		psd = NULL;
1517		break;
1518	case 2:
1519		unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1520		unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1521		type = q_u->info.share.info2.info_2.type;
1522		max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1523		psd = NULL;
1524		break;
1525#if 0
1526		/* not supported on set but here for completeness */
1527	case 501:
1528		unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1529		type = q_u->info.share.info501.info_501.type;
1530		psd = NULL;
1531		break;
1532#endif
1533	case 502:
1534		unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1535		unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1536		type = q_u->info.share.info502.info_502.type;
1537		psd = q_u->info.share.info502.info_502_str.sd;
1538		map_generic_share_sd_bits(psd);
1539		break;
1540	case 1004:
1541		pstrcpy(pathname, lp_pathname(snum));
1542		unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1543		type = STYPE_DISKTREE;
1544		break;
1545	case 1005:
1546                /* XP re-sets the csc policy even if it wasn't changed by the
1547		   user, so we must compare it to see if it's what is set in
1548		   smb.conf, so that we can contine other ops like setting
1549		   ACLs on a share */
1550		if (((q_u->info.share.info1005.share_info_flags &
1551		      SHARE_1005_CSC_POLICY_MASK) >>
1552		     SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1553			return WERR_OK;
1554		else {
1555			DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1556			return WERR_ACCESS_DENIED;
1557		}
1558	case 1006:
1559	case 1007:
1560		return WERR_ACCESS_DENIED;
1561	case 1501:
1562		pstrcpy(pathname, lp_pathname(snum));
1563		fstrcpy(comment, lp_comment(snum));
1564		psd = q_u->info.share.info1501.sdb->sec;
1565		map_generic_share_sd_bits(psd);
1566		type = STYPE_DISKTREE;
1567		break;
1568	default:
1569		DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1570		return WERR_UNKNOWN_LEVEL;
1571	}
1572
1573	/* We can only modify disk shares. */
1574	if (type != STYPE_DISKTREE)
1575		return WERR_ACCESS_DENIED;
1576
1577	/* Check if the pathname is valid. */
1578	if (!(path = valid_share_pathname( pathname )))
1579		return WERR_OBJECT_PATH_INVALID;
1580
1581	/* Ensure share name, pathname and comment don't contain '"' characters. */
1582	string_replace(share_name, '"', ' ');
1583	string_replace(path, '"', ' ');
1584	string_replace(comment, '"', ' ');
1585
1586	DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1587		lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1588
1589	/* Only call modify function if something changed. */
1590
1591	if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1592		|| (lp_max_connections(snum) != max_connections) )
1593	{
1594		if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1595			DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1596			return WERR_ACCESS_DENIED;
1597		}
1598
1599		slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1600				lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections );
1601
1602		DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1603
1604		/********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1605
1606		if ( is_disk_op )
1607			become_root();
1608
1609		if ( (ret = smbrun(command, NULL)) == 0 ) {
1610			/* Tell everyone we updated smb.conf. */
1611			message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1612		}
1613
1614		if ( is_disk_op )
1615			unbecome_root();
1616
1617		/********* END SeDiskOperatorPrivilege BLOCK *********/
1618
1619		DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1620
1621		if ( ret != 0 )
1622			return WERR_ACCESS_DENIED;
1623	} else {
1624		DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1625	}
1626
1627	/* Replace SD if changed. */
1628	if (psd) {
1629		SEC_DESC *old_sd;
1630		size_t sd_size;
1631
1632		old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1633
1634		if (old_sd && !sec_desc_equal(old_sd, psd)) {
1635			if (!set_share_security(share_name, psd))
1636				DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1637					share_name ));
1638		}
1639	}
1640
1641	DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1642
1643	return WERR_OK;
1644}
1645
1646/*******************************************************************
1647 Net share add. Call 'add_share_command "sharename" "pathname"
1648 "comment" "max connections = "
1649********************************************************************/
1650
1651WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1652{
1653	struct current_user user;
1654	pstring command;
1655	fstring share_name;
1656	fstring comment;
1657	pstring pathname;
1658	int type;
1659	int snum;
1660	int ret;
1661	char *path;
1662	SEC_DESC *psd = NULL;
1663	SE_PRIV se_diskop = SE_DISK_OPERATOR;
1664	BOOL is_disk_op;
1665	int max_connections = 0;
1666
1667	DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1668
1669	r_u->parm_error = 0;
1670
1671	get_current_user(&user,p);
1672
1673	is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1674
1675	if (user.ut.uid != sec_initial_uid()  && !is_disk_op )
1676		return WERR_ACCESS_DENIED;
1677
1678	if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1679		DEBUG(10,("_srv_net_share_add: No add share command\n"));
1680		return WERR_ACCESS_DENIED;
1681	}
1682
1683	switch (q_u->info_level) {
1684	case 0:
1685		/* No path. Not enough info in a level 0 to do anything. */
1686		return WERR_ACCESS_DENIED;
1687	case 1:
1688		/* Not enough info in a level 1 to do anything. */
1689		return WERR_ACCESS_DENIED;
1690	case 2:
1691		unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1692		unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1693		unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1694		max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1695		type = q_u->info.share.info2.info_2.type;
1696		break;
1697	case 501:
1698		/* No path. Not enough info in a level 501 to do anything. */
1699		return WERR_ACCESS_DENIED;
1700	case 502:
1701		unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1702		unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1703		unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1704		type = q_u->info.share.info502.info_502.type;
1705		psd = q_u->info.share.info502.info_502_str.sd;
1706		map_generic_share_sd_bits(psd);
1707		break;
1708
1709		/* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */
1710
1711	case 1004:
1712	case 1005:
1713	case 1006:
1714	case 1007:
1715		return WERR_ACCESS_DENIED;
1716	case 1501:
1717		/* DFS only level. */
1718		return WERR_ACCESS_DENIED;
1719	default:
1720		DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1721		return WERR_UNKNOWN_LEVEL;
1722	}
1723
1724	/* check for invalid share names */
1725
1726	if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1727		DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1728		return WERR_INVALID_NAME;
1729	}
1730
1731	if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1732		|| ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1733	{
1734		return WERR_ACCESS_DENIED;
1735	}
1736
1737	snum = find_service(share_name);
1738
1739	/* Share already exists. */
1740	if (snum >= 0)
1741		return WERR_ALREADY_EXISTS;
1742
1743	/* We can only add disk shares. */
1744	if (type != STYPE_DISKTREE)
1745		return WERR_ACCESS_DENIED;
1746
1747	/* Check if the pathname is valid. */
1748	if (!(path = valid_share_pathname( pathname )))
1749		return WERR_OBJECT_PATH_INVALID;
1750
1751	/* Ensure share name, pathname and comment don't contain '"' characters. */
1752	string_replace(share_name, '"', ' ');
1753	string_replace(path, '"', ' ');
1754	string_replace(comment, '"', ' ');
1755
1756	slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1757			lp_add_share_cmd(),
1758			dyn_CONFIGFILE,
1759			share_name,
1760			path,
1761			comment,
1762			max_connections);
1763
1764	DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1765
1766	/********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1767
1768	if ( is_disk_op )
1769		become_root();
1770
1771	if ( (ret = smbrun(command, NULL)) == 0 ) {
1772		/* Tell everyone we updated smb.conf. */
1773		message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1774	}
1775
1776	if ( is_disk_op )
1777		unbecome_root();
1778
1779	/********* END SeDiskOperatorPrivilege BLOCK *********/
1780
1781	DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1782
1783	if ( ret != 0 )
1784		return WERR_ACCESS_DENIED;
1785
1786	if (psd) {
1787		if (!set_share_security(share_name, psd)) {
1788			DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1789		}
1790	}
1791
1792	/*
1793	 * We don't call reload_services() here, the message will
1794	 * cause this to be done before the next packet is read
1795	 * from the client. JRA.
1796	 */
1797
1798	DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1799
1800	return WERR_OK;
1801}
1802
1803/*******************************************************************
1804 Net share delete. Call "delete share command" with the share name as
1805 a parameter.
1806********************************************************************/
1807
1808WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1809{
1810	struct current_user user;
1811	pstring command;
1812	fstring share_name;
1813	int ret;
1814	int snum;
1815	SE_PRIV se_diskop = SE_DISK_OPERATOR;
1816	BOOL is_disk_op;
1817	struct share_params *params;
1818
1819	DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1820
1821	unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1822
1823	if ( strequal(share_name,"IPC$")
1824		|| ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1825		|| strequal(share_name,"global") )
1826	{
1827		return WERR_ACCESS_DENIED;
1828	}
1829
1830        if (!(params = get_share_params(p->mem_ctx, share_name))) {
1831                return WERR_NO_SUCH_SHARE;
1832        }
1833
1834	snum = find_service(share_name);
1835
1836	/* No change to printer shares. */
1837	if (lp_print_ok(snum))
1838		return WERR_ACCESS_DENIED;
1839
1840	get_current_user(&user,p);
1841
1842	is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1843
1844	if (user.ut.uid != sec_initial_uid()  && !is_disk_op )
1845		return WERR_ACCESS_DENIED;
1846
1847	if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1848		DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1849		return WERR_ACCESS_DENIED;
1850	}
1851
1852	slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1853			lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1854
1855	DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1856
1857	/********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1858
1859	if ( is_disk_op )
1860		become_root();
1861
1862	if ( (ret = smbrun(command, NULL)) == 0 ) {
1863		/* Tell everyone we updated smb.conf. */
1864		message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1865	}
1866
1867	if ( is_disk_op )
1868		unbecome_root();
1869
1870	/********* END SeDiskOperatorPrivilege BLOCK *********/
1871
1872	DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1873
1874	if ( ret != 0 )
1875		return WERR_ACCESS_DENIED;
1876
1877	/* Delete the SD in the database. */
1878	delete_share_security(params);
1879
1880	lp_killservice(params->service);
1881
1882	return WERR_OK;
1883}
1884
1885WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1886{
1887	DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1888
1889	return _srv_net_share_del(p, q_u, r_u);
1890}
1891
1892/*******************************************************************
1893time of day
1894********************************************************************/
1895
1896WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1897{
1898	TIME_OF_DAY_INFO *tod;
1899	struct tm *t;
1900	time_t unixdate = time(NULL);
1901
1902	/* We do this call first as if we do it *after* the gmtime call
1903	   it overwrites the pointed-to values. JRA */
1904
1905	uint32 zone = get_time_zone(unixdate)/60;
1906
1907	DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1908
1909	if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) )
1910		return WERR_NOMEM;
1911
1912	r_u->tod = tod;
1913	r_u->ptr_srv_tod = 0x1;
1914	r_u->status = WERR_OK;
1915
1916	DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1917
1918	t = gmtime(&unixdate);
1919
1920	/* set up the */
1921	init_time_of_day_info(tod,
1922	                      unixdate,
1923	                      0,
1924	                      t->tm_hour,
1925	                      t->tm_min,
1926	                      t->tm_sec,
1927	                      0,
1928	                      zone,
1929	                      10000,
1930	                      t->tm_mday,
1931	                      t->tm_mon + 1,
1932	                      1900+t->tm_year,
1933	                      t->tm_wday);
1934
1935	DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1936
1937	return r_u->status;
1938}
1939
1940/***********************************************************************************
1941 Win9x NT tools get security descriptor.
1942***********************************************************************************/
1943
1944WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1945			SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1946{
1947	SEC_DESC *psd = NULL;
1948	size_t sd_size;
1949	DATA_BLOB null_pw;
1950	pstring filename;
1951	pstring qualname;
1952	files_struct *fsp = NULL;
1953	SMB_STRUCT_STAT st;
1954	NTSTATUS nt_status;
1955	struct current_user user;
1956	connection_struct *conn = NULL;
1957	BOOL became_user = False;
1958
1959	ZERO_STRUCT(st);
1960
1961	r_u->status = WERR_OK;
1962
1963	unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1964
1965	/* Null password is ok - we are already an authenticated user... */
1966	null_pw = data_blob(NULL, 0);
1967
1968	get_current_user(&user, p);
1969
1970	become_root();
1971	conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1972	unbecome_root();
1973
1974	if (conn == NULL) {
1975		DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1976		r_u->status = ntstatus_to_werror(nt_status);
1977		goto error_exit;
1978	}
1979
1980	if (!become_user(conn, conn->vuid)) {
1981		DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1982		r_u->status = WERR_ACCESS_DENIED;
1983		goto error_exit;
1984	}
1985	became_user = True;
1986
1987	unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1988	nt_status = unix_convert(conn, filename, False, NULL, &st);
1989	if (!NT_STATUS_IS_OK(nt_status)) {
1990		DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
1991		r_u->status = WERR_ACCESS_DENIED;
1992		goto error_exit;
1993	}
1994
1995	nt_status = check_name(conn, filename);
1996	if (!NT_STATUS_IS_OK(nt_status)) {
1997		DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
1998		r_u->status = WERR_ACCESS_DENIED;
1999		goto error_exit;
2000	}
2001
2002	nt_status = open_file_stat(conn, filename, &st, &fsp);
2003	if ( !NT_STATUS_IS_OK(nt_status)) {
2004		/* Perhaps it is a directory */
2005		if (errno == EISDIR)
2006			nt_status = open_directory(conn, filename, &st,
2007					READ_CONTROL_ACCESS,
2008					FILE_SHARE_READ|FILE_SHARE_WRITE,
2009					FILE_OPEN,
2010					0,
2011					FILE_ATTRIBUTE_DIRECTORY,
2012					NULL, &fsp);
2013
2014		if (!NT_STATUS_IS_OK(nt_status)) {
2015			DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
2016			r_u->status = ntstatus_to_werror(nt_status);
2017			goto error_exit;
2018		}
2019	}
2020
2021	sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2022
2023	if (sd_size == 0) {
2024		DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
2025		r_u->status = WERR_ACCESS_DENIED;
2026		goto error_exit;
2027	}
2028
2029	r_u->ptr_response = 1;
2030	r_u->size_response = sd_size;
2031	r_u->ptr_secdesc = 1;
2032	r_u->size_secdesc = sd_size;
2033	r_u->sec_desc = psd;
2034
2035	psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2036
2037	close_file(fsp, NORMAL_CLOSE);
2038	unbecome_user();
2039	close_cnum(conn, user.vuid);
2040	return r_u->status;
2041
2042error_exit:
2043
2044	if(fsp) {
2045		close_file(fsp, NORMAL_CLOSE);
2046	}
2047
2048	if (became_user)
2049		unbecome_user();
2050
2051	if (conn)
2052		close_cnum(conn, user.vuid);
2053
2054	return r_u->status;
2055}
2056
2057/***********************************************************************************
2058 Win9x NT tools set security descriptor.
2059***********************************************************************************/
2060
2061WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
2062									SRV_R_NET_FILE_SET_SECDESC *r_u)
2063{
2064	BOOL ret;
2065	pstring filename;
2066	pstring qualname;
2067	DATA_BLOB null_pw;
2068	files_struct *fsp = NULL;
2069	SMB_STRUCT_STAT st;
2070	NTSTATUS nt_status;
2071	struct current_user user;
2072	connection_struct *conn = NULL;
2073	BOOL became_user = False;
2074
2075	ZERO_STRUCT(st);
2076
2077	r_u->status = WERR_OK;
2078
2079	unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2080
2081	/* Null password is ok - we are already an authenticated user... */
2082	null_pw = data_blob(NULL, 0);
2083
2084	get_current_user(&user, p);
2085
2086	become_root();
2087	conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2088	unbecome_root();
2089
2090	if (conn == NULL) {
2091		DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2092		r_u->status = ntstatus_to_werror(nt_status);
2093		goto error_exit;
2094	}
2095
2096	if (!become_user(conn, conn->vuid)) {
2097		DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2098		r_u->status = WERR_ACCESS_DENIED;
2099		goto error_exit;
2100	}
2101	became_user = True;
2102
2103	unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2104	nt_status = unix_convert(conn, filename, False, NULL, &st);
2105	if (!NT_STATUS_IS_OK(nt_status)) {
2106		DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2107		r_u->status = WERR_ACCESS_DENIED;
2108		goto error_exit;
2109	}
2110
2111	nt_status = check_name(conn, filename);
2112	if (!NT_STATUS_IS_OK(nt_status)) {
2113		DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2114		r_u->status = WERR_ACCESS_DENIED;
2115		goto error_exit;
2116	}
2117
2118
2119	nt_status = open_file_stat(conn, filename, &st, &fsp);
2120
2121	if ( !NT_STATUS_IS_OK(nt_status) ) {
2122		/* Perhaps it is a directory */
2123		if (errno == EISDIR)
2124			nt_status = open_directory(conn, filename, &st,
2125						FILE_READ_ATTRIBUTES,
2126						FILE_SHARE_READ|FILE_SHARE_WRITE,
2127						FILE_OPEN,
2128						0,
2129						FILE_ATTRIBUTE_DIRECTORY,
2130						NULL, &fsp);
2131
2132		if ( !NT_STATUS_IS_OK(nt_status) ) {
2133			DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2134			r_u->status = ntstatus_to_werror(nt_status);
2135			goto error_exit;
2136		}
2137	}
2138
2139	ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2140
2141	if (ret == False) {
2142		DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2143		r_u->status = WERR_ACCESS_DENIED;
2144		goto error_exit;
2145	}
2146
2147	close_file(fsp, NORMAL_CLOSE);
2148	unbecome_user();
2149	close_cnum(conn, user.vuid);
2150	return r_u->status;
2151
2152error_exit:
2153
2154	if(fsp) {
2155		close_file(fsp, NORMAL_CLOSE);
2156	}
2157
2158	if (became_user) {
2159		unbecome_user();
2160	}
2161
2162	if (conn) {
2163		close_cnum(conn, user.vuid);
2164	}
2165
2166	return r_u->status;
2167}
2168
2169/***********************************************************************************
2170 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2171 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2172 These disks would the disks listed by this function.
2173 Users could then create shares relative to these disks.  Watch out for moving these disks around.
2174 "Nigel Williams" <nigel@veritas.com>.
2175***********************************************************************************/
2176
2177static const char *server_disks[] = {"C:"};
2178
2179static uint32 get_server_disk_count(void)
2180{
2181	return sizeof(server_disks)/sizeof(server_disks[0]);
2182}
2183
2184static uint32 init_server_disk_enum(uint32 *resume)
2185{
2186	uint32 server_disk_count = get_server_disk_count();
2187
2188	/*resume can be an offset into the list for now*/
2189
2190	if(*resume & 0x80000000)
2191		*resume = 0;
2192
2193	if(*resume > server_disk_count)
2194		*resume = server_disk_count;
2195
2196	return server_disk_count - *resume;
2197}
2198
2199static const char *next_server_disk_enum(uint32 *resume)
2200{
2201	const char *disk;
2202
2203	if(init_server_disk_enum(resume) == 0)
2204		return NULL;
2205
2206	disk = server_disks[*resume];
2207
2208	(*resume)++;
2209
2210	DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2211
2212	return disk;
2213}
2214
2215WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2216{
2217	uint32 i;
2218	const char *disk_name;
2219	TALLOC_CTX *ctx = p->mem_ctx;
2220	uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2221
2222	r_u->status=WERR_OK;
2223
2224	r_u->total_entries = init_server_disk_enum(&resume);
2225
2226	r_u->disk_enum_ctr.unknown = 0;
2227
2228	if(!(r_u->disk_enum_ctr.disk_info =  TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2229		return WERR_NOMEM;
2230	}
2231
2232	r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2233
2234	/*allow one DISK_INFO for null terminator*/
2235
2236	for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2237
2238		r_u->disk_enum_ctr.entries_read++;
2239
2240		/*copy disk name into a unicode string*/
2241
2242		init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2243	}
2244
2245	/* add a terminating null string.  Is this there if there is more data to come? */
2246
2247	r_u->disk_enum_ctr.entries_read++;
2248
2249	init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2250
2251	init_enum_hnd(&r_u->enum_hnd, resume);
2252
2253	return r_u->status;
2254}
2255
2256/********************************************************************
2257********************************************************************/
2258
2259WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2260{
2261	fstring sharename;
2262
2263	switch ( q_u->type ) {
2264	case 0x9:
2265		rpcstr_pull(sharename, q_u->sharename.buffer, sizeof(sharename), q_u->sharename.uni_str_len*2, 0);
2266		if ( !validate_net_name( sharename, INVALID_SHARENAME_CHARS, sizeof(sharename) ) ) {
2267			DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", sharename));
2268			return WERR_INVALID_NAME;
2269		}
2270		break;
2271
2272	default:
2273		return WERR_UNKNOWN_LEVEL;
2274	}
2275
2276	return WERR_OK;
2277}
2278
2279
2280/********************************************************************
2281********************************************************************/
2282
2283WERROR _srv_net_file_close(pipes_struct *p, SRV_Q_NET_FILE_CLOSE *q_u, SRV_R_NET_FILE_CLOSE *r_u)
2284{
2285	return WERR_ACCESS_DENIED;
2286}
2287
2288