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