r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need
[ira/wip.git] / source / 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, 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, 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, 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, snum, &sd_size);
1688
1689                 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1690                         if (!set_share_security(p->mem_ctx, share_name, psd))
1691                                 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1692                                         share_name ));
1693                 }
1694         }
1695                         
1696         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1697
1698         return WERR_OK;
1699 }
1700
1701 /*******************************************************************
1702  Net share add. Call 'add_share_command "sharename" "pathname" 
1703  "comment" "max connections = "
1704 ********************************************************************/
1705
1706 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1707 {
1708         pstring command;
1709         fstring share_name;
1710         fstring comment;
1711         pstring pathname;
1712         int type;
1713         int snum;
1714         int ret;
1715         char *path;
1716         SEC_DESC *psd = NULL;
1717         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1718         BOOL is_disk_op;
1719         int max_connections = 0;
1720
1721         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1722
1723         r_u->parm_error = 0;
1724
1725         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1726
1727         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1728                 return WERR_ACCESS_DENIED;
1729
1730         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1731                 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1732                 return WERR_ACCESS_DENIED;
1733         }
1734         
1735         switch (q_u->info_level) {
1736         case 0:
1737                 /* No path. Not enough info in a level 0 to do anything. */
1738                 return WERR_ACCESS_DENIED;
1739         case 1:
1740                 /* Not enough info in a level 1 to do anything. */
1741                 return WERR_ACCESS_DENIED;
1742         case 2:
1743                 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1744                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1745                 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1746                 max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1747                 type = q_u->info.share.info2.info_2.type;
1748                 break;
1749         case 501:
1750                 /* No path. Not enough info in a level 501 to do anything. */
1751                 return WERR_ACCESS_DENIED;
1752         case 502:
1753                 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1754                 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1755                 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1756                 type = q_u->info.share.info502.info_502.type;
1757                 psd = q_u->info.share.info502.info_502_str.sd;
1758                 map_generic_share_sd_bits(psd);
1759                 break;
1760
1761                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */ 
1762
1763         case 1004:
1764         case 1005:
1765         case 1006:
1766         case 1007:
1767                 return WERR_ACCESS_DENIED;
1768         case 1501:
1769                 /* DFS only level. */
1770                 return WERR_ACCESS_DENIED;
1771         default:
1772                 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1773                 return WERR_UNKNOWN_LEVEL;
1774         }
1775
1776         /* check for invalid share names */
1777
1778         if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1779                 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1780                 return WERR_INVALID_NAME;
1781         }
1782
1783         if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1784                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1785         {
1786                 return WERR_ACCESS_DENIED;
1787         }
1788
1789         snum = find_service(share_name);
1790
1791         /* Share already exists. */
1792         if (snum >= 0)
1793                 return WERR_ALREADY_EXISTS;
1794
1795         /* We can only add disk shares. */
1796         if (type != STYPE_DISKTREE)
1797                 return WERR_ACCESS_DENIED;
1798                 
1799         /* Check if the pathname is valid. */
1800         if (!(path = valid_share_pathname( pathname )))
1801                 return WERR_OBJECT_PATH_INVALID;
1802
1803         /* Ensure share name, pathname and comment don't contain '"' characters. */
1804         string_replace(share_name, '"', ' ');
1805         string_replace(path, '"', ' ');
1806         string_replace(comment, '"', ' ');
1807
1808         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1809                         lp_add_share_cmd(), 
1810                         dyn_CONFIGFILE, 
1811                         share_name, 
1812                         path, 
1813                         comment, 
1814                         max_connections);
1815                         
1816         DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1817         
1818         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1819         
1820         if ( is_disk_op )
1821                 become_root();
1822
1823         if ( (ret = smbrun(command, NULL)) == 0 ) {
1824                 /* Tell everyone we updated smb.conf. */
1825                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1826         }
1827
1828         if ( is_disk_op )
1829                 unbecome_root();
1830                 
1831         /********* END SeDiskOperatorPrivilege BLOCK *********/
1832
1833         DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1834
1835         if ( ret != 0 )
1836                 return WERR_ACCESS_DENIED;
1837
1838         if (psd) {
1839                 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1840                         DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1841                 }
1842         }
1843
1844         /*
1845          * We don't call reload_services() here, the message will
1846          * cause this to be done before the next packet is read
1847          * from the client. JRA.
1848          */
1849
1850         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1851
1852         return WERR_OK;
1853 }
1854
1855 /*******************************************************************
1856  Net share delete. Call "delete share command" with the share name as
1857  a parameter.
1858 ********************************************************************/
1859
1860 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1861 {
1862         pstring command;
1863         fstring share_name;
1864         int ret;
1865         int snum;
1866         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1867         BOOL is_disk_op;
1868
1869         DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1870
1871         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1872
1873         if ( strequal(share_name,"IPC$") 
1874                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1875                 || strequal(share_name,"global") )
1876         {
1877                 return WERR_ACCESS_DENIED;
1878         }
1879
1880         snum = find_service(share_name);
1881
1882         if (snum < 0)
1883                 return WERR_NO_SUCH_SHARE;
1884
1885         /* No change to printer shares. */
1886         if (lp_print_ok(snum))
1887                 return WERR_ACCESS_DENIED;
1888
1889         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1890
1891         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1892                 return WERR_ACCESS_DENIED;
1893
1894         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1895                 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1896                 return WERR_ACCESS_DENIED;
1897         }
1898                 
1899         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1900                         lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1901
1902         DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1903
1904         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1905         
1906         if ( is_disk_op )
1907                 become_root();
1908
1909         if ( (ret = smbrun(command, NULL)) == 0 ) {
1910                 /* Tell everyone we updated smb.conf. */
1911                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1912         }
1913
1914         if ( is_disk_op )
1915                 unbecome_root();
1916                 
1917         /********* END SeDiskOperatorPrivilege BLOCK *********/
1918
1919         DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1920
1921         if ( ret != 0 )
1922                 return WERR_ACCESS_DENIED;
1923
1924         /* Delete the SD in the database. */
1925         delete_share_security(snum);
1926
1927         lp_killservice(snum);
1928
1929         return WERR_OK;
1930 }
1931
1932 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1933 {
1934         DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1935
1936         return _srv_net_share_del(p, q_u, r_u);
1937 }
1938
1939 /*******************************************************************
1940 time of day
1941 ********************************************************************/
1942
1943 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1944 {
1945         TIME_OF_DAY_INFO *tod;
1946         struct tm *t;
1947         time_t unixdate = time(NULL);
1948
1949         /* We do this call first as if we do it *after* the gmtime call
1950            it overwrites the pointed-to values. JRA */
1951
1952         uint32 zone = get_time_zone(unixdate)/60;
1953
1954         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1955
1956         if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) )
1957                 return WERR_NOMEM;
1958
1959         r_u->tod = tod;
1960         r_u->ptr_srv_tod = 0x1;
1961         r_u->status = WERR_OK;
1962
1963         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1964
1965         t = gmtime(&unixdate);
1966
1967         /* set up the */
1968         init_time_of_day_info(tod,
1969                               unixdate,
1970                               0,
1971                               t->tm_hour,
1972                               t->tm_min,
1973                               t->tm_sec,
1974                               0,
1975                               zone,
1976                               10000,
1977                               t->tm_mday,
1978                               t->tm_mon + 1,
1979                               1900+t->tm_year,
1980                               t->tm_wday);
1981         
1982         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1983
1984         return r_u->status;
1985 }
1986
1987 /***********************************************************************************
1988  Win9x NT tools get security descriptor.
1989 ***********************************************************************************/
1990
1991 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1992                         SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1993 {
1994         SEC_DESC *psd = NULL;
1995         size_t sd_size;
1996         DATA_BLOB null_pw;
1997         pstring filename;
1998         pstring qualname;
1999         files_struct *fsp = NULL;
2000         SMB_STRUCT_STAT st;
2001         BOOL bad_path;
2002         NTSTATUS nt_status;
2003         connection_struct *conn = NULL;
2004         BOOL became_user = False; 
2005
2006         ZERO_STRUCT(st);
2007
2008         r_u->status = WERR_OK;
2009
2010         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2011
2012         /* Null password is ok - we are already an authenticated user... */
2013         null_pw = data_blob(NULL, 0);
2014
2015         become_root();
2016         conn = make_connection(qualname, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2017         unbecome_root();
2018
2019         if (conn == NULL) {
2020                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
2021                 r_u->status = ntstatus_to_werror(nt_status);
2022                 goto error_exit;
2023         }
2024
2025         if (!become_user(conn, conn->vuid)) {
2026                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2027                 r_u->status = WERR_ACCESS_DENIED;
2028                 goto error_exit;
2029         }
2030         became_user = True;
2031
2032         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2033         unix_convert(filename, conn, NULL, &bad_path, &st);
2034         if (bad_path) {
2035                 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
2036                 r_u->status = WERR_ACCESS_DENIED;
2037                 goto error_exit;
2038         }
2039
2040         if (!check_name(filename,conn)) {
2041                 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
2042                 r_u->status = WERR_ACCESS_DENIED;
2043                 goto error_exit;
2044         }
2045
2046         nt_status = open_file_stat(conn, filename, &st, &fsp);
2047         if (!NT_STATUS_IS_OK(nt_status)) {
2048                 /* Perhaps it is a directory */
2049                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2050                         nt_status = open_directory(conn, filename, &st,
2051                                         READ_CONTROL_ACCESS,
2052                                         FILE_SHARE_READ|FILE_SHARE_WRITE,
2053                                         FILE_OPEN,
2054                                         0,
2055                                         NULL, &fsp);
2056
2057                 if (!NT_STATUS_IS_OK(nt_status)) {
2058                         DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
2059                         r_u->status = WERR_ACCESS_DENIED;
2060                         goto error_exit;
2061                 }
2062         }
2063
2064         sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2065
2066         if (sd_size == 0) {
2067                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
2068                 r_u->status = WERR_ACCESS_DENIED;
2069                 goto error_exit;
2070         }
2071
2072         r_u->ptr_response = 1;
2073         r_u->size_response = sd_size;
2074         r_u->ptr_secdesc = 1;
2075         r_u->size_secdesc = sd_size;
2076         r_u->sec_desc = psd;
2077
2078         psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2079
2080         close_file(fsp, NORMAL_CLOSE);
2081         unbecome_user();
2082         close_cnum(conn, p->pipe_user.vuid);
2083         return r_u->status;
2084
2085 error_exit:
2086
2087         if(fsp) {
2088                 close_file(fsp, NORMAL_CLOSE);
2089         }
2090
2091         if (became_user)
2092                 unbecome_user();
2093
2094         if (conn) 
2095                 close_cnum(conn, p->pipe_user.vuid);
2096
2097         return r_u->status;
2098 }
2099
2100 /***********************************************************************************
2101  Win9x NT tools set security descriptor.
2102 ***********************************************************************************/
2103
2104 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
2105                                                                         SRV_R_NET_FILE_SET_SECDESC *r_u)
2106 {
2107         BOOL ret;
2108         pstring filename;
2109         pstring qualname;
2110         DATA_BLOB null_pw;
2111         files_struct *fsp = NULL;
2112         SMB_STRUCT_STAT st;
2113         BOOL bad_path;
2114         NTSTATUS nt_status;
2115         connection_struct *conn = NULL;
2116         BOOL became_user = False;
2117
2118         ZERO_STRUCT(st);
2119
2120         r_u->status = WERR_OK;
2121
2122         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2123
2124         /* Null password is ok - we are already an authenticated user... */
2125         null_pw = data_blob(NULL, 0);
2126
2127         become_root();
2128         conn = make_connection(qualname, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2129         unbecome_root();
2130
2131         if (conn == NULL) {
2132                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2133                 r_u->status = ntstatus_to_werror(nt_status);
2134                 goto error_exit;
2135         }
2136
2137         if (!become_user(conn, conn->vuid)) {
2138                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2139                 r_u->status = WERR_ACCESS_DENIED;
2140                 goto error_exit;
2141         }
2142         became_user = True;
2143
2144         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2145         unix_convert(filename, conn, NULL, &bad_path, &st);
2146         if (bad_path) {
2147                 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2148                 r_u->status = WERR_ACCESS_DENIED;
2149                 goto error_exit;
2150         }
2151
2152         if (!check_name(filename,conn)) {
2153                 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2154                 r_u->status = WERR_ACCESS_DENIED;
2155                 goto error_exit;
2156         }
2157
2158
2159         nt_status = open_file_stat(conn, filename, &st, &fsp);
2160
2161         if (!NT_STATUS_IS_OK(nt_status)) {
2162                 /* Perhaps it is a directory */
2163                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2164                         nt_status = open_directory(conn, filename, &st,
2165                                                 FILE_READ_ATTRIBUTES,
2166                                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
2167                                                 FILE_OPEN,
2168                                                 0,
2169                                                 NULL, &fsp);
2170
2171                 if (!NT_STATUS_IS_OK(nt_status)) {
2172                         DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2173                         r_u->status = WERR_ACCESS_DENIED;
2174                         goto error_exit;
2175                 }
2176         }
2177
2178         ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2179
2180         if (ret == False) {
2181                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2182                 r_u->status = WERR_ACCESS_DENIED;
2183                 goto error_exit;
2184         }
2185
2186         close_file(fsp, NORMAL_CLOSE);
2187         unbecome_user();
2188         close_cnum(conn, p->pipe_user.vuid);
2189         return r_u->status;
2190
2191 error_exit:
2192
2193         if(fsp) {
2194                 close_file(fsp, NORMAL_CLOSE);
2195         }
2196
2197         if (became_user) {
2198                 unbecome_user();
2199         }
2200
2201         if (conn) {
2202                 close_cnum(conn, p->pipe_user.vuid);
2203         }
2204
2205         return r_u->status;
2206 }
2207
2208 /***********************************************************************************
2209  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2210  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2211  These disks would the disks listed by this function.
2212  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2213  "Nigel Williams" <nigel@veritas.com>.
2214 ***********************************************************************************/
2215
2216 static const char *server_disks[] = {"C:"};
2217
2218 static uint32 get_server_disk_count(void)
2219 {
2220         return sizeof(server_disks)/sizeof(server_disks[0]);
2221 }
2222
2223 static uint32 init_server_disk_enum(uint32 *resume)
2224 {
2225         uint32 server_disk_count = get_server_disk_count();
2226
2227         /*resume can be an offset into the list for now*/
2228
2229         if(*resume & 0x80000000)
2230                 *resume = 0;
2231
2232         if(*resume > server_disk_count)
2233                 *resume = server_disk_count;
2234
2235         return server_disk_count - *resume;
2236 }
2237
2238 static const char *next_server_disk_enum(uint32 *resume)
2239 {
2240         const char *disk;
2241
2242         if(init_server_disk_enum(resume) == 0)
2243                 return NULL;
2244
2245         disk = server_disks[*resume];
2246
2247         (*resume)++;
2248
2249         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2250
2251         return disk;
2252 }
2253
2254 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2255 {
2256         uint32 i;
2257         const char *disk_name;
2258         TALLOC_CTX *ctx = p->mem_ctx;
2259         uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2260
2261         r_u->status=WERR_OK;
2262
2263         r_u->total_entries = init_server_disk_enum(&resume);
2264
2265         r_u->disk_enum_ctr.unknown = 0; 
2266
2267         if(!(r_u->disk_enum_ctr.disk_info =  TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2268                 return WERR_NOMEM;
2269         }
2270
2271         r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2272
2273         /*allow one DISK_INFO for null terminator*/
2274
2275         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2276
2277                 r_u->disk_enum_ctr.entries_read++;
2278
2279                 /*copy disk name into a unicode string*/
2280
2281                 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);    
2282         }
2283
2284         /* add a terminating null string.  Is this there if there is more data to come? */
2285
2286         r_u->disk_enum_ctr.entries_read++;
2287
2288         init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2289
2290         init_enum_hnd(&r_u->enum_hnd, resume);
2291
2292         return r_u->status;
2293 }
2294
2295 /********************************************************************
2296 ********************************************************************/
2297
2298 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2299 {
2300         fstring sharename;
2301
2302         switch ( q_u->type ) {
2303         case 0x9:
2304                 rpcstr_pull(sharename, q_u->sharename.buffer, sizeof(sharename), q_u->sharename.uni_str_len*2, 0);
2305                 if ( !validate_net_name( sharename, INVALID_SHARENAME_CHARS, sizeof(sharename) ) ) {
2306                         DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", sharename));
2307                         return WERR_INVALID_NAME;
2308                 }
2309                 break;
2310
2311         default:
2312                 return WERR_UNKNOWN_LEVEL;
2313         }
2314
2315         return WERR_OK;
2316 }
2317
2318
2319 /********************************************************************
2320 ********************************************************************/
2321
2322 WERROR _srv_net_file_close(pipes_struct *p, SRV_Q_NET_FILE_CLOSE *q_u, SRV_R_NET_FILE_CLOSE *r_u)
2323 {
2324         return WERR_ACCESS_DENIED;
2325 }
2326