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	        /* foxconn, CSW @ chec whether the pr iv */
476		if ( (lp_browseable(snum) ||  p->conn->admin_user )
477		      && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
478		     num_entries++;
479	}
480
481	*total_entries = num_entries;
482	ctr->num_entries2 = ctr->num_entries = num_entries;
483	ctr->ptr_share_info = ctr->ptr_entries = 1;
484
485	if (!num_entries)
486		return True;
487
488	switch (info_level) {
489	case 0:
490	{
491		SRV_SHARE_INFO_0 *info0 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_0, num_entries);
492		int i = 0;
493
494		if (!info0) {
495			return False;
496		}
497
498		for (snum = *resume_hnd; snum < num_services; snum++) {
499			if ( (lp_browseable(snum) ||  p->conn->admin_user )
500			     && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
501	  	             init_srv_share_info_0(p, &info0[i++], snum);
502			}
503		}
504
505		ctr->share.info0 = info0;
506		break;
507
508	}
509
510	case 1:
511	{
512		SRV_SHARE_INFO_1 *info1 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1, num_entries);
513		int i = 0;
514
515		if (!info1) {
516			return False;
517		}
518
519		for (snum = *resume_hnd; snum < num_services; snum++) {
520			if ( (lp_browseable(snum) ||  p->conn->admin_user )
521			      && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
522				init_srv_share_info_1(p, &info1[i++], snum);
523			}
524		}
525
526		ctr->share.info1 = info1;
527		break;
528	}
529
530	case 2:
531	{
532		SRV_SHARE_INFO_2 *info2 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_2, num_entries);
533		int i = 0;
534
535		if (!info2) {
536			return False;
537		}
538
539		for (snum = *resume_hnd; snum < num_services; snum++) {
540			if ( (lp_browseable(snum) ||  p->conn->admin_user )
541			     && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
542			     init_srv_share_info_2(p, &info2[i++], snum);
543			}
544		}
545
546		ctr->share.info2 = info2;
547		break;
548	}
549
550	case 501:
551	{
552		SRV_SHARE_INFO_501 *info501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_501, num_entries);
553		int i = 0;
554
555		if (!info501) {
556			return False;
557		}
558
559		for (snum = *resume_hnd; snum < num_services; snum++) {
560			if ( (lp_browseable(snum) ||  p->conn->admin_user )
561			    && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
562				init_srv_share_info_501(p, &info501[i++], snum);
563			}
564		}
565
566		ctr->share.info501 = info501;
567		break;
568	}
569
570	case 502:
571	{
572		SRV_SHARE_INFO_502 *info502 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_502, num_entries);
573		int i = 0;
574
575		if (!info502) {
576			return False;
577		}
578
579		for (snum = *resume_hnd; snum < num_services; snum++) {
580			if ( (lp_browseable(snum) ||  p->conn->admin_user )
581			     && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
582				init_srv_share_info_502(p, &info502[i++], snum);
583			}
584		}
585
586		ctr->share.info502 = info502;
587		break;
588	}
589
590	/* here for completeness but not currently used with enum (1004 - 1501)*/
591
592	case 1004:
593	{
594		SRV_SHARE_INFO_1004 *info1004 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1004, num_entries);
595		int i = 0;
596
597		if (!info1004) {
598			return False;
599		}
600
601		for (snum = *resume_hnd; snum < num_services; snum++) {
602			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
603				init_srv_share_info_1004(p, &info1004[i++], snum);
604			}
605		}
606
607		ctr->share.info1004 = info1004;
608		break;
609	}
610
611	case 1005:
612	{
613		SRV_SHARE_INFO_1005 *info1005 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1005, num_entries);
614		int i = 0;
615
616		if (!info1005) {
617			return False;
618		}
619
620		for (snum = *resume_hnd; snum < num_services; snum++) {
621			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
622				init_srv_share_info_1005(p, &info1005[i++], snum);
623			}
624		}
625
626		ctr->share.info1005 = info1005;
627		break;
628	}
629
630	case 1006:
631	{
632		SRV_SHARE_INFO_1006 *info1006 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1006, num_entries);
633		int i = 0;
634
635		if (!info1006) {
636			return False;
637		}
638
639		for (snum = *resume_hnd; snum < num_services; snum++) {
640			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
641				init_srv_share_info_1006(p, &info1006[i++], snum);
642			}
643		}
644
645		ctr->share.info1006 = info1006;
646		break;
647	}
648
649	case 1007:
650	{
651		SRV_SHARE_INFO_1007 *info1007 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1007, num_entries);
652		int i = 0;
653
654		if (!info1007) {
655			return False;
656		}
657
658		for (snum = *resume_hnd; snum < num_services; snum++) {
659			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
660				init_srv_share_info_1007(p, &info1007[i++], snum);
661			}
662		}
663
664		ctr->share.info1007 = info1007;
665		break;
666	}
667
668	case 1501:
669	{
670		SRV_SHARE_INFO_1501 *info1501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1501, num_entries);
671		int i = 0;
672
673		if (!info1501) {
674			return False;
675		}
676
677		for (snum = *resume_hnd; snum < num_services; snum++) {
678			if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
679				init_srv_share_info_1501(p, &info1501[i++], snum);
680			}
681		}
682
683		ctr->share.info1501 = info1501;
684		break;
685	}
686	default:
687		DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
688		return False;
689	}
690
691	return True;
692}
693
694/*******************************************************************
695 Inits a SRV_R_NET_SHARE_ENUM structure.
696********************************************************************/
697
698static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
699				      uint32 info_level, uint32 resume_hnd, BOOL all)
700{
701	DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
702
703	if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
704				    &resume_hnd, &r_n->total_entries, all)) {
705		r_n->status = WERR_OK;
706	} else {
707		r_n->status = WERR_UNKNOWN_LEVEL;
708	}
709
710	init_enum_hnd(&r_n->enum_hnd, resume_hnd);
711}
712
713/*******************************************************************
714 Inits a SRV_R_NET_SHARE_GET_INFO structure.
715********************************************************************/
716
717static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
718				  char *share_name, uint32 info_level)
719{
720	WERROR status = WERR_OK;
721	int snum;
722
723	DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
724
725	r_n->info.switch_value = info_level;
726
727	snum = find_service(share_name);
728
729	if (snum >= 0) {
730		switch (info_level) {
731		case 0:
732			init_srv_share_info_0(p, &r_n->info.share.info0, snum);
733			break;
734		case 1:
735			init_srv_share_info_1(p, &r_n->info.share.info1, snum);
736			break;
737		case 2:
738			init_srv_share_info_2(p, &r_n->info.share.info2, snum);
739			break;
740		case 501:
741			init_srv_share_info_501(p, &r_n->info.share.info501, snum);
742			break;
743		case 502:
744			init_srv_share_info_502(p, &r_n->info.share.info502, snum);
745			break;
746
747			/* here for completeness */
748		case 1004:
749			init_srv_share_info_1004(p, &r_n->info.share.info1004, snum);
750			break;
751		case 1005:
752			init_srv_share_info_1005(p, &r_n->info.share.info1005, snum);
753			break;
754
755			/* here for completeness 1006 - 1501 */
756		case 1006:
757			init_srv_share_info_1006(p, &r_n->info.share.info1006, snum);
758			break;
759		case 1007:
760			init_srv_share_info_1007(p, &r_n->info.share.info1007, snum);
761			break;
762		case 1501:
763			init_srv_share_info_1501(p, &r_n->info.share.info1501, snum);
764			break;
765		default:
766			DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
767			status = WERR_UNKNOWN_LEVEL;
768			break;
769		}
770	} else {
771		status = WERR_INVALID_NAME;
772	}
773
774	r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
775	r_n->status = status;
776}
777
778/*******************************************************************
779 fill in a sess info level 0 structure.
780 ********************************************************************/
781
782static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
783{
784	struct sessionid *session_list;
785	uint32 num_entries = 0;
786	(*stot) = list_sessions(&session_list);
787
788	if (ss0 == NULL) {
789		if (snum) {
790			(*snum) = 0;
791		}
792		SAFE_FREE(session_list);
793		return;
794	}
795
796	DEBUG(5,("init_srv_sess_0_ss0\n"));
797
798	if (snum) {
799		for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
800			init_srv_sess_info0( &ss0->info_0[num_entries], session_list[(*snum)].remote_machine);
801			num_entries++;
802		}
803
804		ss0->num_entries_read  = num_entries;
805		ss0->ptr_sess_info     = num_entries > 0 ? 1 : 0;
806		ss0->num_entries_read2 = num_entries;
807
808		if ((*snum) >= (*stot)) {
809			(*snum) = 0;
810		}
811
812	} else {
813		ss0->num_entries_read = 0;
814		ss0->ptr_sess_info = 0;
815		ss0->num_entries_read2 = 0;
816	}
817	SAFE_FREE(session_list);
818}
819
820/*******************************************************************
821********************************************************************/
822
823/* global needed to make use of the share_mode_forall() callback */
824static struct sess_file_count s_file_cnt;
825
826static void sess_file_fn( const struct share_mode_entry *e,
827                          const char *sharepath, const char *fname, void *state )
828{
829	struct sess_file_count *sess = &s_file_cnt;
830
831	if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
832		sess->count++;
833	}
834
835	return;
836}
837
838/*******************************************************************
839********************************************************************/
840
841static int net_count_files( uid_t uid, pid_t pid )
842{
843	s_file_cnt.count = 0;
844	s_file_cnt.uid = uid;
845	s_file_cnt.pid = pid;
846
847	share_mode_forall( sess_file_fn, NULL );
848
849	return s_file_cnt.count;
850}
851
852/*******************************************************************
853 fill in a sess info level 1 structure.
854 ********************************************************************/
855
856static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
857{
858	struct sessionid *session_list;
859	uint32 num_entries = 0;
860	time_t now = time(NULL);
861
862	if ( !snum ) {
863		ss1->num_entries_read = 0;
864		ss1->ptr_sess_info = 0;
865		ss1->num_entries_read2 = 0;
866
867		(*stot) = 0;
868
869		return;
870	}
871
872	if (ss1 == NULL) {
873		(*snum) = 0;
874		return;
875	}
876
877	(*stot) = list_sessions(&session_list);
878
879
880	for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
881		uint32 num_files;
882		uint32 connect_time;
883		struct passwd *pw = sys_getpwnam(session_list[*snum].username);
884		BOOL guest;
885
886		if ( !pw ) {
887			DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
888				session_list[*snum].username));
889			continue;
890		}
891
892		connect_time = (uint32)(now - session_list[*snum].connect_start);
893		num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
894		guest = strequal( session_list[*snum].username, lp_guestaccount() );
895
896		init_srv_sess_info1( &ss1->info_1[num_entries],
897		                     session_list[*snum].remote_machine,
898				     session_list[*snum].username,
899				     num_files,
900				     connect_time,
901				     0,
902				     guest);
903		num_entries++;
904	}
905
906	ss1->num_entries_read  = num_entries;
907	ss1->ptr_sess_info     = num_entries > 0 ? 1 : 0;
908	ss1->num_entries_read2 = num_entries;
909
910	if ((*snum) >= (*stot)) {
911		(*snum) = 0;
912	}
913
914	SAFE_FREE(session_list);
915}
916
917/*******************************************************************
918 makes a SRV_R_NET_SESS_ENUM structure.
919********************************************************************/
920
921static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
922				int switch_value, uint32 *resume_hnd, uint32 *total_entries)
923{
924	WERROR status = WERR_OK;
925	DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
926
927	ctr->switch_value = switch_value;
928
929	switch (switch_value) {
930	case 0:
931		init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
932		ctr->ptr_sess_ctr = 1;
933		break;
934	case 1:
935		init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
936		ctr->ptr_sess_ctr = 1;
937		break;
938	default:
939		DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
940		(*resume_hnd) = 0;
941		(*total_entries) = 0;
942		ctr->ptr_sess_ctr = 0;
943		status = WERR_UNKNOWN_LEVEL;
944		break;
945	}
946
947	return status;
948}
949
950/*******************************************************************
951 makes a SRV_R_NET_SESS_ENUM structure.
952********************************************************************/
953
954static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
955				uint32 resume_hnd, int sess_level, int switch_value)
956{
957	DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
958
959	r_n->sess_level  = sess_level;
960
961	if (sess_level == -1)
962		r_n->status = WERR_UNKNOWN_LEVEL;
963	else
964		r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
965
966	if (!W_ERROR_IS_OK(r_n->status))
967		resume_hnd = 0;
968
969	init_enum_hnd(&r_n->enum_hnd, resume_hnd);
970}
971
972/*******************************************************************
973 fill in a conn info level 0 structure.
974 ********************************************************************/
975
976static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
977{
978	uint32 num_entries = 0;
979	(*stot) = 1;
980
981	if (ss0 == NULL) {
982		(*snum) = 0;
983		return;
984	}
985
986	DEBUG(5,("init_srv_conn_0_ss0\n"));
987
988	if (snum) {
989		for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
990
991			init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
992
993			/* move on to creating next connection */
994			/* move on to creating next conn */
995			num_entries++;
996		}
997
998		ss0->num_entries_read  = num_entries;
999		ss0->ptr_conn_info     = num_entries > 0 ? 1 : 0;
1000		ss0->num_entries_read2 = num_entries;
1001
1002		if ((*snum) >= (*stot)) {
1003			(*snum) = 0;
1004		}
1005
1006	} else {
1007		ss0->num_entries_read = 0;
1008		ss0->ptr_conn_info = 0;
1009		ss0->num_entries_read2 = 0;
1010
1011		(*stot) = 0;
1012	}
1013}
1014
1015/*******************************************************************
1016 fill in a conn info level 1 structure.
1017 ********************************************************************/
1018
1019static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1020				uint32 id, uint32 type,
1021				uint32 num_opens, uint32 num_users, uint32 open_time,
1022				const char *usr_name, const char *net_name)
1023{
1024	init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1025	init_srv_conn_info1_str(str1, usr_name, net_name);
1026}
1027
1028/*******************************************************************
1029 fill in a conn info level 1 structure.
1030 ********************************************************************/
1031
1032static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1033{
1034	uint32 num_entries = 0;
1035	(*stot) = 1;
1036
1037	if (ss1 == NULL) {
1038		(*snum) = 0;
1039		return;
1040	}
1041
1042	DEBUG(5,("init_srv_conn_1_ss1\n"));
1043
1044	if (snum) {
1045		for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1046			init_srv_conn_1_info(&ss1->info_1[num_entries],
1047								 &ss1->info_1_str[num_entries],
1048			                     (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1049
1050			/* move on to creating next connection */
1051			/* move on to creating next conn */
1052			num_entries++;
1053		}
1054
1055		ss1->num_entries_read  = num_entries;
1056		ss1->ptr_conn_info     = num_entries > 0 ? 1 : 0;
1057		ss1->num_entries_read2 = num_entries;
1058
1059
1060		if ((*snum) >= (*stot)) {
1061			(*snum) = 0;
1062		}
1063
1064	} else {
1065		ss1->num_entries_read = 0;
1066		ss1->ptr_conn_info = 0;
1067		ss1->num_entries_read2 = 0;
1068
1069		(*stot) = 0;
1070	}
1071}
1072
1073/*******************************************************************
1074 makes a SRV_R_NET_CONN_ENUM structure.
1075********************************************************************/
1076
1077static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1078				int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1079{
1080	WERROR status = WERR_OK;
1081	DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1082
1083	ctr->switch_value = switch_value;
1084
1085	switch (switch_value) {
1086	case 0:
1087		init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1088		ctr->ptr_conn_ctr = 1;
1089		break;
1090	case 1:
1091		init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1092		ctr->ptr_conn_ctr = 1;
1093		break;
1094	default:
1095		DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1096		(*resume_hnd = 0);
1097		(*total_entries) = 0;
1098		ctr->ptr_conn_ctr = 0;
1099		status = WERR_UNKNOWN_LEVEL;
1100		break;
1101	}
1102
1103	return status;
1104}
1105
1106/*******************************************************************
1107 makes a SRV_R_NET_CONN_ENUM structure.
1108********************************************************************/
1109
1110static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1111				uint32 resume_hnd, int conn_level, int switch_value)
1112{
1113	DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1114
1115	r_n->conn_level  = conn_level;
1116	if (conn_level == -1)
1117		r_n->status = WERR_UNKNOWN_LEVEL;
1118	else
1119		r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1120
1121	if (!W_ERROR_IS_OK(r_n->status))
1122		resume_hnd = 0;
1123
1124	init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1125}
1126
1127/*******************************************************************
1128 makes a SRV_R_NET_FILE_ENUM structure.
1129********************************************************************/
1130
1131static WERROR net_file_enum_3( SRV_R_NET_FILE_ENUM *r, uint32 resume_hnd )
1132{
1133	TALLOC_CTX *ctx = get_talloc_ctx();
1134	SRV_FILE_INFO_CTR *ctr = &r->ctr;
1135
1136	/* TODO -- Windows enumerates
1137	   (b) active pipes
1138	   (c) open directories and files */
1139
1140	r->status = net_enum_files( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
1141	if ( !W_ERROR_IS_OK(r->status))
1142		goto done;
1143
1144	r->status = net_enum_pipes( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
1145	if ( !W_ERROR_IS_OK(r->status))
1146		goto done;
1147
1148	r->level = ctr->level = 3;
1149	r->total_entries = ctr->num_entries;
1150	/* ctr->num_entries = r->total_entries - resume_hnd; */
1151	ctr->num_entries2 = ctr->num_entries;
1152	ctr->ptr_file_info = 1;
1153
1154	r->status = WERR_OK;
1155
1156done:
1157	if ( ctr->num_entries > 0 )
1158		ctr->ptr_entries = 1;
1159
1160	init_enum_hnd(&r->enum_hnd, 0);
1161
1162	return r->status;
1163}
1164
1165/*******************************************************************
1166*******************************************************************/
1167
1168WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1169{
1170	switch ( q_u->level ) {
1171	case 3:
1172		return net_file_enum_3( r_u, get_enum_hnd(&q_u->enum_hnd) );
1173	default:
1174		return WERR_UNKNOWN_LEVEL;
1175	}
1176
1177	return WERR_OK;
1178}
1179
1180/*******************************************************************
1181net server get info
1182********************************************************************/
1183
1184WERROR _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u)
1185{
1186	WERROR status = WERR_OK;
1187	SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR);
1188
1189	if (!ctr)
1190		return WERR_NOMEM;
1191
1192	ZERO_STRUCTP(ctr);
1193
1194	DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1195
1196	if (!pipe_access_check(p)) {
1197		DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1198		return WERR_ACCESS_DENIED;
1199	}
1200
1201	switch (q_u->switch_value) {
1202
1203		/* Technically level 102 should only be available to
1204		   Administrators but there isn't anything super-secret
1205		   here, as most of it is made up. */
1206
1207	case 102:
1208		init_srv_info_102(&ctr->srv.sv102,
1209		                  500, global_myname(),
1210				  string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1211		                  lp_major_announce_version(), lp_minor_announce_version(),
1212		                  lp_default_server_announce(),
1213		                  0xffffffff, /* users */
1214		                  0xf, /* disc */
1215		                  0, /* hidden */
1216		                  240, /* announce */
1217		                  3000, /* announce delta */
1218		                  100000, /* licenses */
1219		                  "c:\\"); /* user path */
1220		break;
1221	case 101:
1222		init_srv_info_101(&ctr->srv.sv101,
1223		                  500, global_myname(),
1224		                  lp_major_announce_version(), lp_minor_announce_version(),
1225		                  lp_default_server_announce(),
1226		                  string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1227		break;
1228	case 100:
1229		init_srv_info_100(&ctr->srv.sv100, 500, global_myname());
1230		break;
1231	default:
1232		status = WERR_UNKNOWN_LEVEL;
1233		break;
1234	}
1235
1236	/* set up the net server get info structure */
1237	init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1238
1239	DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1240
1241	return r_u->status;
1242}
1243
1244/*******************************************************************
1245net server set info
1246********************************************************************/
1247
1248WERROR _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u)
1249{
1250	WERROR status = WERR_OK;
1251
1252	DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1253
1254	/* Set up the net server set info structure. */
1255
1256	init_srv_r_net_srv_set_info(r_u, 0x0, status);
1257
1258	DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1259
1260	return r_u->status;
1261}
1262
1263/*******************************************************************
1264net conn enum
1265********************************************************************/
1266
1267WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1268{
1269	DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1270
1271	r_u->ctr = TALLOC_P(p->mem_ctx, SRV_CONN_INFO_CTR);
1272	if (!r_u->ctr)
1273		return WERR_NOMEM;
1274
1275	ZERO_STRUCTP(r_u->ctr);
1276
1277	/* set up the */
1278	init_srv_r_net_conn_enum(r_u,
1279				get_enum_hnd(&q_u->enum_hnd),
1280				q_u->conn_level,
1281				q_u->ctr->switch_value);
1282
1283	DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1284
1285	return r_u->status;
1286}
1287
1288/*******************************************************************
1289net sess enum
1290********************************************************************/
1291
1292WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1293{
1294	DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1295
1296	r_u->ctr = TALLOC_P(p->mem_ctx, SRV_SESS_INFO_CTR);
1297	if (!r_u->ctr)
1298		return WERR_NOMEM;
1299
1300	ZERO_STRUCTP(r_u->ctr);
1301
1302	/* set up the */
1303	init_srv_r_net_sess_enum(r_u,
1304				get_enum_hnd(&q_u->enum_hnd),
1305				q_u->sess_level,
1306				q_u->ctr->switch_value);
1307
1308	DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1309
1310	return r_u->status;
1311}
1312
1313/*******************************************************************
1314net sess del
1315********************************************************************/
1316
1317WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u)
1318{
1319	struct sessionid *session_list;
1320	struct current_user user;
1321	int num_sessions, snum;
1322	fstring username;
1323	fstring machine;
1324	BOOL not_root = False;
1325
1326	rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name);
1327	rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name);
1328
1329	/* strip leading backslashes if any */
1330	while (machine[0] == '\\') {
1331		memmove(machine, &machine[1], strlen(machine));
1332	}
1333
1334	num_sessions = list_sessions(&session_list);
1335
1336	DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1337
1338	r_u->status = WERR_ACCESS_DENIED;
1339
1340	get_current_user(&user, p);
1341
1342	/* fail out now if you are not root or not a domain admin */
1343
1344	if ((user.ut.uid != sec_initial_uid()) &&
1345		( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1346
1347		goto done;
1348	}
1349
1350	for (snum = 0; snum < num_sessions; snum++) {
1351
1352		if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1353		    strequal(session_list[snum].remote_machine, machine)) {
1354
1355			if (user.ut.uid != sec_initial_uid()) {
1356				not_root = True;
1357				become_root();
1358			}
1359
1360			if (NT_STATUS_IS_OK(message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False)))
1361				r_u->status = WERR_OK;
1362
1363			if (not_root)
1364				unbecome_root();
1365		}
1366	}
1367
1368	DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1369
1370
1371done:
1372	SAFE_FREE(session_list);
1373
1374	return r_u->status;
1375}
1376
1377/*******************************************************************
1378 Net share enum all.
1379********************************************************************/
1380
1381WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1382{
1383	DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1384
1385	if (!pipe_access_check(p)) {
1386		DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1387		return WERR_ACCESS_DENIED;
1388	}
1389
1390	/* Create the list of shares for the response. */
1391	init_srv_r_net_share_enum(p, r_u,
1392				q_u->ctr.info_level,
1393				get_enum_hnd(&q_u->enum_hnd), True);
1394
1395	DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1396
1397	return r_u->status;
1398}
1399
1400/*******************************************************************
1401 Net share enum.
1402********************************************************************/
1403
1404WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1405{
1406	DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1407
1408	if (!pipe_access_check(p)) {
1409		DEBUG(3, ("access denied to srv_net_share_enum\n"));
1410		return WERR_ACCESS_DENIED;
1411	}
1412
1413	/* Create the list of shares for the response. */
1414	init_srv_r_net_share_enum(p, r_u,
1415				  q_u->ctr.info_level,
1416				  get_enum_hnd(&q_u->enum_hnd), False);
1417
1418	DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1419
1420	return r_u->status;
1421}
1422
1423/*******************************************************************
1424 Net share get info.
1425********************************************************************/
1426
1427WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u)
1428{
1429	fstring share_name;
1430
1431	DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1432
1433	/* Create the list of shares for the response. */
1434	unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1435	init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1436
1437	DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1438
1439	return r_u->status;
1440}
1441
1442/*******************************************************************
1443 Check a given DOS pathname is valid for a share.
1444********************************************************************/
1445
1446char *valid_share_pathname(char *dos_pathname)
1447{
1448	char *ptr;
1449
1450	/* Convert any '\' paths to '/' */
1451	unix_format(dos_pathname);
1452	unix_clean_name(dos_pathname);
1453
1454	/* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1455	ptr = dos_pathname;
1456	if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1457		ptr += 2;
1458
1459	/* Only absolute paths allowed. */
1460	if (*ptr != '/')
1461		return NULL;
1462
1463	return ptr;
1464}
1465
1466/*******************************************************************
1467 Net share set info. Modify share details.
1468********************************************************************/
1469
1470WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u)
1471{
1472	struct current_user user;
1473	pstring command;
1474	fstring share_name;
1475	fstring comment;
1476	pstring pathname;
1477	int type;
1478	int snum;
1479	int ret;
1480	char *path;
1481	SEC_DESC *psd = NULL;
1482	SE_PRIV se_diskop = SE_DISK_OPERATOR;
1483	BOOL is_disk_op = False;
1484	int max_connections = 0;
1485
1486	DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1487
1488	unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1489
1490	r_u->parm_error = 0;
1491
1492	if ( strequal(share_name,"IPC$")
1493		|| ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1494		|| strequal(share_name,"global") )
1495	{
1496		return WERR_ACCESS_DENIED;
1497	}
1498
1499	snum = find_service(share_name);
1500
1501	/* Does this share exist ? */
1502	if (snum < 0)
1503		return WERR_NET_NAME_NOT_FOUND;
1504
1505	/* No change to printer shares. */
1506	if (lp_print_ok(snum))
1507		return WERR_ACCESS_DENIED;
1508
1509	get_current_user(&user,p);
1510
1511	is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1512
1513	/* fail out now if you are not root and not a disk op */
1514
1515	if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1516		return WERR_ACCESS_DENIED;
1517
1518	switch (q_u->info_level) {
1519	case 1:
1520		pstrcpy(pathname, lp_pathname(snum));
1521		unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1522		type = q_u->info.share.info2.info_2.type;
1523		psd = NULL;
1524		break;
1525	case 2:
1526		unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1527		unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1528		type = q_u->info.share.info2.info_2.type;
1529		max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1530		psd = NULL;
1531		break;
1532#if 0
1533		/* not supported on set but here for completeness */
1534	case 501:
1535		unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1536		type = q_u->info.share.info501.info_501.type;
1537		psd = NULL;
1538		break;
1539#endif
1540	case 502:
1541		unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1542		unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1543		type = q_u->info.share.info502.info_502.type;
1544		psd = q_u->info.share.info502.info_502_str.sd;
1545		map_generic_share_sd_bits(psd);
1546		break;
1547	case 1004:
1548		pstrcpy(pathname, lp_pathname(snum));
1549		unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1550		type = STYPE_DISKTREE;
1551		break;
1552	case 1005:
1553                /* XP re-sets the csc policy even if it wasn't changed by the
1554		   user, so we must compare it to see if it's what is set in
1555		   smb.conf, so that we can contine other ops like setting
1556		   ACLs on a share */
1557		if (((q_u->info.share.info1005.share_info_flags &
1558		      SHARE_1005_CSC_POLICY_MASK) >>
1559		     SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1560			return WERR_OK;
1561		else {
1562			DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1563			return WERR_ACCESS_DENIED;
1564		}
1565	case 1006:
1566	case 1007:
1567		return WERR_ACCESS_DENIED;
1568	case 1501:
1569		pstrcpy(pathname, lp_pathname(snum));
1570		fstrcpy(comment, lp_comment(snum));
1571		psd = q_u->info.share.info1501.sdb->sec;
1572		map_generic_share_sd_bits(psd);
1573		type = STYPE_DISKTREE;
1574		break;
1575	default:
1576		DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1577		return WERR_UNKNOWN_LEVEL;
1578	}
1579
1580	/* We can only modify disk shares. */
1581	if (type != STYPE_DISKTREE)
1582		return WERR_ACCESS_DENIED;
1583
1584	/* Check if the pathname is valid. */
1585	if (!(path = valid_share_pathname( pathname )))
1586		return WERR_OBJECT_PATH_INVALID;
1587
1588	/* Ensure share name, pathname and comment don't contain '"' characters. */
1589	string_replace(share_name, '"', ' ');
1590	string_replace(path, '"', ' ');
1591	string_replace(comment, '"', ' ');
1592
1593	DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1594		lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1595
1596	/* Only call modify function if something changed. */
1597
1598	if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1599		|| (lp_max_connections(snum) != max_connections) )
1600	{
1601		if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1602			DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1603			return WERR_ACCESS_DENIED;
1604		}
1605
1606		slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1607				lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections );
1608
1609		DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1610
1611		/********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1612
1613		if ( is_disk_op )
1614			become_root();
1615
1616		if ( (ret = smbrun(command, NULL)) == 0 ) {
1617			/* Tell everyone we updated smb.conf. */
1618			message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1619		}
1620
1621		if ( is_disk_op )
1622			unbecome_root();
1623
1624		/********* END SeDiskOperatorPrivilege BLOCK *********/
1625
1626		DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1627
1628		if ( ret != 0 )
1629			return WERR_ACCESS_DENIED;
1630	} else {
1631		DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1632	}
1633
1634	/* Replace SD if changed. */
1635	if (psd) {
1636		SEC_DESC *old_sd;
1637		size_t sd_size;
1638
1639		old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1640
1641		if (old_sd && !sec_desc_equal(old_sd, psd)) {
1642			if (!set_share_security(share_name, psd))
1643				DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1644					share_name ));
1645		}
1646	}
1647
1648	DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1649
1650	return WERR_OK;
1651}
1652
1653/*******************************************************************
1654 Net share add. Call 'add_share_command "sharename" "pathname"
1655 "comment" "max connections = "
1656********************************************************************/
1657
1658WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1659{
1660	struct current_user user;
1661	pstring command;
1662	fstring share_name;
1663	fstring comment;
1664	pstring pathname;
1665	int type;
1666	int snum;
1667	int ret;
1668	char *path;
1669	SEC_DESC *psd = NULL;
1670	SE_PRIV se_diskop = SE_DISK_OPERATOR;
1671	BOOL is_disk_op;
1672	int max_connections = 0;
1673
1674	DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1675
1676	r_u->parm_error = 0;
1677
1678	get_current_user(&user,p);
1679
1680	is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1681
1682	if (user.ut.uid != sec_initial_uid()  && !is_disk_op )
1683		return WERR_ACCESS_DENIED;
1684
1685	if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1686		DEBUG(10,("_srv_net_share_add: No add share command\n"));
1687		return WERR_ACCESS_DENIED;
1688	}
1689
1690	switch (q_u->info_level) {
1691	case 0:
1692		/* No path. Not enough info in a level 0 to do anything. */
1693		return WERR_ACCESS_DENIED;
1694	case 1:
1695		/* Not enough info in a level 1 to do anything. */
1696		return WERR_ACCESS_DENIED;
1697	case 2:
1698		unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1699		unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1700		unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1701		max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1702		type = q_u->info.share.info2.info_2.type;
1703		break;
1704	case 501:
1705		/* No path. Not enough info in a level 501 to do anything. */
1706		return WERR_ACCESS_DENIED;
1707	case 502:
1708		unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1709		unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1710		unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1711		type = q_u->info.share.info502.info_502.type;
1712		psd = q_u->info.share.info502.info_502_str.sd;
1713		map_generic_share_sd_bits(psd);
1714		break;
1715
1716		/* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */
1717
1718	case 1004:
1719	case 1005:
1720	case 1006:
1721	case 1007:
1722		return WERR_ACCESS_DENIED;
1723	case 1501:
1724		/* DFS only level. */
1725		return WERR_ACCESS_DENIED;
1726	default:
1727		DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1728		return WERR_UNKNOWN_LEVEL;
1729	}
1730
1731	/* check for invalid share names */
1732
1733	if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1734		DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1735		return WERR_INVALID_NAME;
1736	}
1737
1738	if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1739		|| ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1740	{
1741		return WERR_ACCESS_DENIED;
1742	}
1743
1744	snum = find_service(share_name);
1745
1746	/* Share already exists. */
1747	if (snum >= 0)
1748		return WERR_ALREADY_EXISTS;
1749
1750	/* We can only add disk shares. */
1751	if (type != STYPE_DISKTREE)
1752		return WERR_ACCESS_DENIED;
1753
1754	/* Check if the pathname is valid. */
1755	if (!(path = valid_share_pathname( pathname )))
1756		return WERR_OBJECT_PATH_INVALID;
1757
1758	/* Ensure share name, pathname and comment don't contain '"' characters. */
1759	string_replace(share_name, '"', ' ');
1760	string_replace(path, '"', ' ');
1761	string_replace(comment, '"', ' ');
1762
1763	slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1764			lp_add_share_cmd(),
1765			dyn_CONFIGFILE,
1766			share_name,
1767			path,
1768			comment,
1769			max_connections);
1770
1771	DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1772
1773	/********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1774
1775	if ( is_disk_op )
1776		become_root();
1777
1778	if ( (ret = smbrun(command, NULL)) == 0 ) {
1779		/* Tell everyone we updated smb.conf. */
1780		message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1781	}
1782
1783	if ( is_disk_op )
1784		unbecome_root();
1785
1786	/********* END SeDiskOperatorPrivilege BLOCK *********/
1787
1788	DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1789
1790	if ( ret != 0 )
1791		return WERR_ACCESS_DENIED;
1792
1793	if (psd) {
1794		if (!set_share_security(share_name, psd)) {
1795			DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1796		}
1797	}
1798
1799	/*
1800	 * We don't call reload_services() here, the message will
1801	 * cause this to be done before the next packet is read
1802	 * from the client. JRA.
1803	 */
1804
1805	DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1806
1807	return WERR_OK;
1808}
1809
1810/*******************************************************************
1811 Net share delete. Call "delete share command" with the share name as
1812 a parameter.
1813********************************************************************/
1814
1815WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1816{
1817	struct current_user user;
1818	pstring command;
1819	fstring share_name;
1820	int ret;
1821	int snum;
1822	SE_PRIV se_diskop = SE_DISK_OPERATOR;
1823	BOOL is_disk_op;
1824	struct share_params *params;
1825
1826	DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1827
1828	unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1829
1830	if ( strequal(share_name,"IPC$")
1831		|| ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1832		|| strequal(share_name,"global") )
1833	{
1834		return WERR_ACCESS_DENIED;
1835	}
1836
1837        if (!(params = get_share_params(p->mem_ctx, share_name))) {
1838                return WERR_NO_SUCH_SHARE;
1839        }
1840
1841	snum = find_service(share_name);
1842
1843	/* No change to printer shares. */
1844	if (lp_print_ok(snum))
1845		return WERR_ACCESS_DENIED;
1846
1847	get_current_user(&user,p);
1848
1849	is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1850
1851	if (user.ut.uid != sec_initial_uid()  && !is_disk_op )
1852		return WERR_ACCESS_DENIED;
1853
1854	if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1855		DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1856		return WERR_ACCESS_DENIED;
1857	}
1858
1859	slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1860			lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1861
1862	DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1863
1864	/********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1865
1866	if ( is_disk_op )
1867		become_root();
1868
1869	if ( (ret = smbrun(command, NULL)) == 0 ) {
1870		/* Tell everyone we updated smb.conf. */
1871		message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1872	}
1873
1874	if ( is_disk_op )
1875		unbecome_root();
1876
1877	/********* END SeDiskOperatorPrivilege BLOCK *********/
1878
1879	DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1880
1881	if ( ret != 0 )
1882		return WERR_ACCESS_DENIED;
1883
1884	/* Delete the SD in the database. */
1885	delete_share_security(params);
1886
1887	lp_killservice(params->service);
1888
1889	return WERR_OK;
1890}
1891
1892WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1893{
1894	DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1895
1896	return _srv_net_share_del(p, q_u, r_u);
1897}
1898
1899/*******************************************************************
1900time of day
1901********************************************************************/
1902
1903WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1904{
1905	TIME_OF_DAY_INFO *tod;
1906	struct tm *t;
1907	time_t unixdate = time(NULL);
1908
1909	/* We do this call first as if we do it *after* the gmtime call
1910	   it overwrites the pointed-to values. JRA */
1911
1912	uint32 zone = get_time_zone(unixdate)/60;
1913
1914	DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1915
1916	if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) )
1917		return WERR_NOMEM;
1918
1919	r_u->tod = tod;
1920	r_u->ptr_srv_tod = 0x1;
1921	r_u->status = WERR_OK;
1922
1923	DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1924
1925	t = gmtime(&unixdate);
1926
1927	/* set up the */
1928	init_time_of_day_info(tod,
1929	                      unixdate,
1930	                      0,
1931	                      t->tm_hour,
1932	                      t->tm_min,
1933	                      t->tm_sec,
1934	                      0,
1935	                      zone,
1936	                      10000,
1937	                      t->tm_mday,
1938	                      t->tm_mon + 1,
1939	                      1900+t->tm_year,
1940	                      t->tm_wday);
1941
1942	DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1943
1944	return r_u->status;
1945}
1946
1947/***********************************************************************************
1948 Win9x NT tools get security descriptor.
1949***********************************************************************************/
1950
1951WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1952			SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1953{
1954	SEC_DESC *psd = NULL;
1955	size_t sd_size;
1956	DATA_BLOB null_pw;
1957	pstring filename;
1958	pstring qualname;
1959	files_struct *fsp = NULL;
1960	SMB_STRUCT_STAT st;
1961	NTSTATUS nt_status;
1962	struct current_user user;
1963	connection_struct *conn = NULL;
1964	BOOL became_user = False;
1965
1966	ZERO_STRUCT(st);
1967
1968	r_u->status = WERR_OK;
1969
1970	unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1971
1972	/* Null password is ok - we are already an authenticated user... */
1973	null_pw = data_blob(NULL, 0);
1974
1975	get_current_user(&user, p);
1976
1977	become_root();
1978	conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1979	unbecome_root();
1980
1981	if (conn == NULL) {
1982		DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1983		r_u->status = ntstatus_to_werror(nt_status);
1984		goto error_exit;
1985	}
1986
1987	if (!become_user(conn, conn->vuid)) {
1988		DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1989		r_u->status = WERR_ACCESS_DENIED;
1990		goto error_exit;
1991	}
1992	became_user = True;
1993
1994	unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1995	nt_status = unix_convert(conn, filename, False, NULL, &st);
1996	if (!NT_STATUS_IS_OK(nt_status)) {
1997		DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
1998		r_u->status = WERR_ACCESS_DENIED;
1999		goto error_exit;
2000	}
2001
2002	nt_status = check_name(conn, filename);
2003	if (!NT_STATUS_IS_OK(nt_status)) {
2004		DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
2005		r_u->status = WERR_ACCESS_DENIED;
2006		goto error_exit;
2007	}
2008
2009	nt_status = open_file_stat(conn, filename, &st, &fsp);
2010	if ( !NT_STATUS_IS_OK(nt_status)) {
2011		/* Perhaps it is a directory */
2012		if (errno == EISDIR)
2013			nt_status = open_directory(conn, filename, &st,
2014					READ_CONTROL_ACCESS,
2015					FILE_SHARE_READ|FILE_SHARE_WRITE,
2016					FILE_OPEN,
2017					0,
2018					FILE_ATTRIBUTE_DIRECTORY,
2019					NULL, &fsp);
2020
2021		if (!NT_STATUS_IS_OK(nt_status)) {
2022			DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
2023			r_u->status = ntstatus_to_werror(nt_status);
2024			goto error_exit;
2025		}
2026	}
2027
2028	sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2029
2030	if (sd_size == 0) {
2031		DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
2032		r_u->status = WERR_ACCESS_DENIED;
2033		goto error_exit;
2034	}
2035
2036	r_u->ptr_response = 1;
2037	r_u->size_response = sd_size;
2038	r_u->ptr_secdesc = 1;
2039	r_u->size_secdesc = sd_size;
2040	r_u->sec_desc = psd;
2041
2042	psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2043
2044	close_file(fsp, NORMAL_CLOSE);
2045	unbecome_user();
2046	close_cnum(conn, user.vuid);
2047	return r_u->status;
2048
2049error_exit:
2050
2051	if(fsp) {
2052		close_file(fsp, NORMAL_CLOSE);
2053	}
2054
2055	if (became_user)
2056		unbecome_user();
2057
2058	if (conn)
2059		close_cnum(conn, user.vuid);
2060
2061	return r_u->status;
2062}
2063
2064/***********************************************************************************
2065 Win9x NT tools set security descriptor.
2066***********************************************************************************/
2067
2068WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
2069									SRV_R_NET_FILE_SET_SECDESC *r_u)
2070{
2071	BOOL ret;
2072	pstring filename;
2073	pstring qualname;
2074	DATA_BLOB null_pw;
2075	files_struct *fsp = NULL;
2076	SMB_STRUCT_STAT st;
2077	NTSTATUS nt_status;
2078	struct current_user user;
2079	connection_struct *conn = NULL;
2080	BOOL became_user = False;
2081
2082	ZERO_STRUCT(st);
2083
2084	r_u->status = WERR_OK;
2085
2086	unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2087
2088	/* Null password is ok - we are already an authenticated user... */
2089	null_pw = data_blob(NULL, 0);
2090
2091	get_current_user(&user, p);
2092
2093	become_root();
2094	conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2095	unbecome_root();
2096
2097	if (conn == NULL) {
2098		DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2099		r_u->status = ntstatus_to_werror(nt_status);
2100		goto error_exit;
2101	}
2102
2103	if (!become_user(conn, conn->vuid)) {
2104		DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2105		r_u->status = WERR_ACCESS_DENIED;
2106		goto error_exit;
2107	}
2108	became_user = True;
2109
2110	unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2111	nt_status = unix_convert(conn, filename, False, NULL, &st);
2112	if (!NT_STATUS_IS_OK(nt_status)) {
2113		DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2114		r_u->status = WERR_ACCESS_DENIED;
2115		goto error_exit;
2116	}
2117
2118	nt_status = check_name(conn, filename);
2119	if (!NT_STATUS_IS_OK(nt_status)) {
2120		DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2121		r_u->status = WERR_ACCESS_DENIED;
2122		goto error_exit;
2123	}
2124
2125
2126	nt_status = open_file_stat(conn, filename, &st, &fsp);
2127
2128	if ( !NT_STATUS_IS_OK(nt_status) ) {
2129		/* Perhaps it is a directory */
2130		if (errno == EISDIR)
2131			nt_status = open_directory(conn, filename, &st,
2132						FILE_READ_ATTRIBUTES,
2133						FILE_SHARE_READ|FILE_SHARE_WRITE,
2134						FILE_OPEN,
2135						0,
2136						FILE_ATTRIBUTE_DIRECTORY,
2137						NULL, &fsp);
2138
2139		if ( !NT_STATUS_IS_OK(nt_status) ) {
2140			DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2141			r_u->status = ntstatus_to_werror(nt_status);
2142			goto error_exit;
2143		}
2144	}
2145
2146	ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2147
2148	if (ret == False) {
2149		DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2150		r_u->status = WERR_ACCESS_DENIED;
2151		goto error_exit;
2152	}
2153
2154	close_file(fsp, NORMAL_CLOSE);
2155	unbecome_user();
2156	close_cnum(conn, user.vuid);
2157	return r_u->status;
2158
2159error_exit:
2160
2161	if(fsp) {
2162		close_file(fsp, NORMAL_CLOSE);
2163	}
2164
2165	if (became_user) {
2166		unbecome_user();
2167	}
2168
2169	if (conn) {
2170		close_cnum(conn, user.vuid);
2171	}
2172
2173	return r_u->status;
2174}
2175
2176/***********************************************************************************
2177 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2178 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2179 These disks would the disks listed by this function.
2180 Users could then create shares relative to these disks.  Watch out for moving these disks around.
2181 "Nigel Williams" <nigel@veritas.com>.
2182***********************************************************************************/
2183
2184static const char *server_disks[] = {"C:"};
2185
2186static uint32 get_server_disk_count(void)
2187{
2188	return sizeof(server_disks)/sizeof(server_disks[0]);
2189}
2190
2191static uint32 init_server_disk_enum(uint32 *resume)
2192{
2193	uint32 server_disk_count = get_server_disk_count();
2194
2195	/*resume can be an offset into the list for now*/
2196
2197	if(*resume & 0x80000000)
2198		*resume = 0;
2199
2200	if(*resume > server_disk_count)
2201		*resume = server_disk_count;
2202
2203	return server_disk_count - *resume;
2204}
2205
2206static const char *next_server_disk_enum(uint32 *resume)
2207{
2208	const char *disk;
2209
2210	if(init_server_disk_enum(resume) == 0)
2211		return NULL;
2212
2213	disk = server_disks[*resume];
2214
2215	(*resume)++;
2216
2217	DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2218
2219	return disk;
2220}
2221
2222WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2223{
2224	uint32 i;
2225	const char *disk_name;
2226	TALLOC_CTX *ctx = p->mem_ctx;
2227	uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2228
2229	r_u->status=WERR_OK;
2230
2231	r_u->total_entries = init_server_disk_enum(&resume);
2232
2233	r_u->disk_enum_ctr.unknown = 0;
2234
2235	if(!(r_u->disk_enum_ctr.disk_info =  TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2236		return WERR_NOMEM;
2237	}
2238
2239	r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2240
2241	/*allow one DISK_INFO for null terminator*/
2242
2243	for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2244
2245		r_u->disk_enum_ctr.entries_read++;
2246
2247		/*copy disk name into a unicode string*/
2248
2249		init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2250	}
2251
2252	/* add a terminating null string.  Is this there if there is more data to come? */
2253
2254	r_u->disk_enum_ctr.entries_read++;
2255
2256	init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2257
2258	init_enum_hnd(&r_u->enum_hnd, resume);
2259
2260	return r_u->status;
2261}
2262
2263/********************************************************************
2264********************************************************************/
2265
2266WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2267{
2268	fstring sharename;
2269
2270	switch ( q_u->type ) {
2271	case 0x9:
2272		rpcstr_pull(sharename, q_u->sharename.buffer, sizeof(sharename), q_u->sharename.uni_str_len*2, 0);
2273		if ( !validate_net_name( sharename, INVALID_SHARENAME_CHARS, sizeof(sharename) ) ) {
2274			DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", sharename));
2275			return WERR_INVALID_NAME;
2276		}
2277		break;
2278
2279	default:
2280		return WERR_UNKNOWN_LEVEL;
2281	}
2282
2283	return WERR_OK;
2284}
2285
2286
2287/********************************************************************
2288********************************************************************/
2289
2290WERROR _srv_net_file_close(pipes_struct *p, SRV_Q_NET_FILE_CLOSE *q_u, SRV_R_NET_FILE_CLOSE *r_u)
2291{
2292	return WERR_ACCESS_DENIED;
2293}
2294
2295