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