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