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