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