r17293: After the results from the cluster tests in Germany,
[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
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 (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))
1335                                 r_u->status = WERR_OK;
1336                 }
1337         }
1338
1339         DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1340
1341
1342 done:
1343         SAFE_FREE(session_list);
1344
1345         return r_u->status;
1346 }
1347
1348 /*******************************************************************
1349  Net share enum all.
1350 ********************************************************************/
1351
1352 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1353 {
1354         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1355
1356         if (!pipe_access_check(p)) {
1357                 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1358                 return WERR_ACCESS_DENIED;
1359         }
1360
1361         /* Create the list of shares for the response. */
1362         init_srv_r_net_share_enum(p, r_u,
1363                                 q_u->ctr.info_level,
1364                                 get_enum_hnd(&q_u->enum_hnd), True);
1365
1366         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1367
1368         return r_u->status;
1369 }
1370
1371 /*******************************************************************
1372  Net share enum.
1373 ********************************************************************/
1374
1375 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1376 {
1377         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1378
1379         if (!pipe_access_check(p)) {
1380                 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1381                 return WERR_ACCESS_DENIED;
1382         }
1383
1384         /* Create the list of shares for the response. */
1385         init_srv_r_net_share_enum(p, r_u,
1386                                   q_u->ctr.info_level,
1387                                   get_enum_hnd(&q_u->enum_hnd), False);
1388
1389         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1390
1391         return r_u->status;
1392 }
1393
1394 /*******************************************************************
1395  Net share get info.
1396 ********************************************************************/
1397
1398 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)
1399 {
1400         fstring share_name;
1401
1402         DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1403
1404         /* Create the list of shares for the response. */
1405         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1406         init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1407
1408         DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1409
1410         return r_u->status;
1411 }
1412
1413 /*******************************************************************
1414  Check a given DOS pathname is valid for a share.
1415 ********************************************************************/
1416
1417 char *valid_share_pathname(char *dos_pathname)
1418 {
1419         char *ptr;
1420
1421         /* Convert any '\' paths to '/' */
1422         unix_format(dos_pathname);
1423         unix_clean_name(dos_pathname);
1424
1425         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1426         ptr = dos_pathname;
1427         if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1428                 ptr += 2;
1429
1430         /* Only absolute paths allowed. */
1431         if (*ptr != '/')
1432                 return NULL;
1433
1434         return ptr;
1435 }
1436
1437 /*******************************************************************
1438  Net share set info. Modify share details.
1439 ********************************************************************/
1440
1441 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)
1442 {
1443         pstring command;
1444         fstring share_name;
1445         fstring comment;
1446         pstring pathname;
1447         int type;
1448         int snum;
1449         int ret;
1450         char *path;
1451         SEC_DESC *psd = NULL;
1452         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1453         BOOL is_disk_op = False;
1454         int max_connections = 0;
1455
1456         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1457
1458         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1459
1460         r_u->parm_error = 0;
1461
1462         if ( strequal(share_name,"IPC$") 
1463                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1464                 || strequal(share_name,"global") )
1465         {
1466                 return WERR_ACCESS_DENIED;
1467         }
1468
1469         snum = find_service(share_name);
1470
1471         /* Does this share exist ? */
1472         if (snum < 0)
1473                 return WERR_NET_NAME_NOT_FOUND;
1474
1475         /* No change to printer shares. */
1476         if (lp_print_ok(snum))
1477                 return WERR_ACCESS_DENIED;
1478
1479         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1480         
1481         /* fail out now if you are not root and not a disk op */
1482         
1483         if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1484                 return WERR_ACCESS_DENIED;
1485
1486         switch (q_u->info_level) {
1487         case 1:
1488                 pstrcpy(pathname, lp_pathname(snum));
1489                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1490                 type = q_u->info.share.info2.info_2.type;
1491                 psd = NULL;
1492                 break;
1493         case 2:
1494                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1495                 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1496                 type = q_u->info.share.info2.info_2.type;
1497                 max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1498                 psd = NULL;
1499                 break;
1500 #if 0
1501                 /* not supported on set but here for completeness */
1502         case 501:
1503                 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1504                 type = q_u->info.share.info501.info_501.type;
1505                 psd = NULL;
1506                 break;
1507 #endif
1508         case 502:
1509                 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1510                 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1511                 type = q_u->info.share.info502.info_502.type;
1512                 psd = q_u->info.share.info502.info_502_str.sd;
1513                 map_generic_share_sd_bits(psd);
1514                 break;
1515         case 1004:
1516                 pstrcpy(pathname, lp_pathname(snum));
1517                 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1518                 type = STYPE_DISKTREE;
1519                 break;
1520         case 1005:
1521                 /* XP re-sets the csc policy even if it wasn't changed by the
1522                    user, so we must compare it to see if it's what is set in
1523                    smb.conf, so that we can contine other ops like setting
1524                    ACLs on a share */
1525                 if (((q_u->info.share.info1005.share_info_flags &
1526                       SHARE_1005_CSC_POLICY_MASK) >>
1527                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1528                         return WERR_OK;
1529                 else {
1530                         DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1531                         return WERR_ACCESS_DENIED;
1532                 }
1533         case 1006:
1534         case 1007:
1535                 return WERR_ACCESS_DENIED;
1536         case 1501:
1537                 pstrcpy(pathname, lp_pathname(snum));
1538                 fstrcpy(comment, lp_comment(snum));
1539                 psd = q_u->info.share.info1501.sdb->sec;
1540                 map_generic_share_sd_bits(psd);
1541                 type = STYPE_DISKTREE;
1542                 break;
1543         default:
1544                 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1545                 return WERR_UNKNOWN_LEVEL;
1546         }
1547
1548         /* We can only modify disk shares. */
1549         if (type != STYPE_DISKTREE)
1550                 return WERR_ACCESS_DENIED;
1551                 
1552         /* Check if the pathname is valid. */
1553         if (!(path = valid_share_pathname( pathname )))
1554                 return WERR_OBJECT_PATH_INVALID;
1555
1556         /* Ensure share name, pathname and comment don't contain '"' characters. */
1557         string_replace(share_name, '"', ' ');
1558         string_replace(path, '"', ' ');
1559         string_replace(comment, '"', ' ');
1560
1561         DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1562                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1563
1564         /* Only call modify function if something changed. */
1565         
1566         if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) 
1567                 || (lp_max_connections(snum) != max_connections) ) 
1568         {
1569                 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1570                         DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1571                         return WERR_ACCESS_DENIED;
1572                 }
1573
1574                 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1575                                 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections ); 
1576
1577                 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1578                                 
1579                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1580         
1581                 if ( is_disk_op )
1582                         become_root();
1583                         
1584                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1585                         /* Tell everyone we updated smb.conf. */
1586                         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1587                 }
1588                 
1589                 if ( is_disk_op )
1590                         unbecome_root();
1591                         
1592                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1593
1594                 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));              
1595         
1596                 if ( ret != 0 )
1597                         return WERR_ACCESS_DENIED;
1598         } else {
1599                 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1600         }
1601
1602         /* Replace SD if changed. */
1603         if (psd) {
1604                 SEC_DESC *old_sd;
1605                 size_t sd_size;
1606
1607                 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1608                                             &sd_size);
1609
1610                 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1611                         if (!set_share_security(p->mem_ctx, share_name, psd))
1612                                 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1613                                         share_name ));
1614                 }
1615         }
1616                         
1617         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1618
1619         return WERR_OK;
1620 }
1621
1622 /*******************************************************************
1623  Net share add. Call 'add_share_command "sharename" "pathname" 
1624  "comment" "max connections = "
1625 ********************************************************************/
1626
1627 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1628 {
1629         pstring command;
1630         fstring share_name;
1631         fstring comment;
1632         pstring pathname;
1633         int type;
1634         int snum;
1635         int ret;
1636         char *path;
1637         SEC_DESC *psd = NULL;
1638         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1639         BOOL is_disk_op;
1640         int max_connections = 0;
1641
1642         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1643
1644         r_u->parm_error = 0;
1645
1646         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1647
1648         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1649                 return WERR_ACCESS_DENIED;
1650
1651         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1652                 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1653                 return WERR_ACCESS_DENIED;
1654         }
1655         
1656         switch (q_u->info_level) {
1657         case 0:
1658                 /* No path. Not enough info in a level 0 to do anything. */
1659                 return WERR_ACCESS_DENIED;
1660         case 1:
1661                 /* Not enough info in a level 1 to do anything. */
1662                 return WERR_ACCESS_DENIED;
1663         case 2:
1664                 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1665                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1666                 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1667                 max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1668                 type = q_u->info.share.info2.info_2.type;
1669                 break;
1670         case 501:
1671                 /* No path. Not enough info in a level 501 to do anything. */
1672                 return WERR_ACCESS_DENIED;
1673         case 502:
1674                 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1675                 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1676                 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1677                 type = q_u->info.share.info502.info_502.type;
1678                 psd = q_u->info.share.info502.info_502_str.sd;
1679                 map_generic_share_sd_bits(psd);
1680                 break;
1681
1682                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */ 
1683
1684         case 1004:
1685         case 1005:
1686         case 1006:
1687         case 1007:
1688                 return WERR_ACCESS_DENIED;
1689         case 1501:
1690                 /* DFS only level. */
1691                 return WERR_ACCESS_DENIED;
1692         default:
1693                 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1694                 return WERR_UNKNOWN_LEVEL;
1695         }
1696
1697         /* check for invalid share names */
1698
1699         if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1700                 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1701                 return WERR_INVALID_NAME;
1702         }
1703
1704         if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1705                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1706         {
1707                 return WERR_ACCESS_DENIED;
1708         }
1709
1710         snum = find_service(share_name);
1711
1712         /* Share already exists. */
1713         if (snum >= 0)
1714                 return WERR_ALREADY_EXISTS;
1715
1716         /* We can only add disk shares. */
1717         if (type != STYPE_DISKTREE)
1718                 return WERR_ACCESS_DENIED;
1719                 
1720         /* Check if the pathname is valid. */
1721         if (!(path = valid_share_pathname( pathname )))
1722                 return WERR_OBJECT_PATH_INVALID;
1723
1724         /* Ensure share name, pathname and comment don't contain '"' characters. */
1725         string_replace(share_name, '"', ' ');
1726         string_replace(path, '"', ' ');
1727         string_replace(comment, '"', ' ');
1728
1729         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1730                         lp_add_share_cmd(), 
1731                         dyn_CONFIGFILE, 
1732                         share_name, 
1733                         path, 
1734                         comment, 
1735                         max_connections);
1736                         
1737         DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1738         
1739         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1740         
1741         if ( is_disk_op )
1742                 become_root();
1743
1744         if ( (ret = smbrun(command, NULL)) == 0 ) {
1745                 /* Tell everyone we updated smb.conf. */
1746                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1747         }
1748
1749         if ( is_disk_op )
1750                 unbecome_root();
1751                 
1752         /********* END SeDiskOperatorPrivilege BLOCK *********/
1753
1754         DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1755
1756         if ( ret != 0 )
1757                 return WERR_ACCESS_DENIED;
1758
1759         if (psd) {
1760                 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1761                         DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1762                 }
1763         }
1764
1765         /*
1766          * We don't call reload_services() here, the message will
1767          * cause this to be done before the next packet is read
1768          * from the client. JRA.
1769          */
1770
1771         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1772
1773         return WERR_OK;
1774 }
1775
1776 /*******************************************************************
1777  Net share delete. Call "delete share command" with the share name as
1778  a parameter.
1779 ********************************************************************/
1780
1781 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1782 {
1783         pstring command;
1784         fstring share_name;
1785         int ret;
1786         int snum;
1787         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1788         BOOL is_disk_op;
1789
1790         DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1791
1792         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1793
1794         if ( strequal(share_name,"IPC$") 
1795                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1796                 || strequal(share_name,"global") )
1797         {
1798                 return WERR_ACCESS_DENIED;
1799         }
1800
1801         snum = find_service(share_name);
1802
1803         if (snum < 0)
1804                 return WERR_NO_SUCH_SHARE;
1805
1806         /* No change to printer shares. */
1807         if (lp_print_ok(snum))
1808                 return WERR_ACCESS_DENIED;
1809
1810         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1811
1812         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1813                 return WERR_ACCESS_DENIED;
1814
1815         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1816                 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1817                 return WERR_ACCESS_DENIED;
1818         }
1819                 
1820         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1821                         lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1822
1823         DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1824
1825         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1826         
1827         if ( is_disk_op )
1828                 become_root();
1829
1830         if ( (ret = smbrun(command, NULL)) == 0 ) {
1831                 /* Tell everyone we updated smb.conf. */
1832                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1833         }
1834
1835         if ( is_disk_op )
1836                 unbecome_root();
1837                 
1838         /********* END SeDiskOperatorPrivilege BLOCK *********/
1839
1840         DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1841
1842         if ( ret != 0 )
1843                 return WERR_ACCESS_DENIED;
1844
1845         /* Delete the SD in the database. */
1846         delete_share_security(snum);
1847
1848         lp_killservice(snum);
1849
1850         return WERR_OK;
1851 }
1852
1853 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1854 {
1855         DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1856
1857         return _srv_net_share_del(p, q_u, r_u);
1858 }
1859
1860 /*******************************************************************
1861 time of day
1862 ********************************************************************/
1863
1864 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1865 {
1866         TIME_OF_DAY_INFO *tod;
1867         struct tm *t;
1868         time_t unixdate = time(NULL);
1869
1870         /* We do this call first as if we do it *after* the gmtime call
1871            it overwrites the pointed-to values. JRA */
1872
1873         uint32 zone = get_time_zone(unixdate)/60;
1874
1875         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1876
1877         if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) )
1878                 return WERR_NOMEM;
1879
1880         r_u->tod = tod;
1881         r_u->ptr_srv_tod = 0x1;
1882         r_u->status = WERR_OK;
1883
1884         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1885
1886         t = gmtime(&unixdate);
1887
1888         /* set up the */
1889         init_time_of_day_info(tod,
1890                               unixdate,
1891                               0,
1892                               t->tm_hour,
1893                               t->tm_min,
1894                               t->tm_sec,
1895                               0,
1896                               zone,
1897                               10000,
1898                               t->tm_mday,
1899                               t->tm_mon + 1,
1900                               1900+t->tm_year,
1901                               t->tm_wday);
1902         
1903         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1904
1905         return r_u->status;
1906 }
1907
1908 /***********************************************************************************
1909  Win9x NT tools get security descriptor.
1910 ***********************************************************************************/
1911
1912 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1913                         SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1914 {
1915         SEC_DESC *psd = NULL;
1916         size_t sd_size;
1917         DATA_BLOB null_pw;
1918         pstring filename;
1919         pstring qualname;
1920         files_struct *fsp = NULL;
1921         SMB_STRUCT_STAT st;
1922         BOOL bad_path;
1923         NTSTATUS nt_status;
1924         connection_struct *conn = NULL;
1925         BOOL became_user = False; 
1926
1927         ZERO_STRUCT(st);
1928
1929         r_u->status = WERR_OK;
1930
1931         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1932
1933         /* Null password is ok - we are already an authenticated user... */
1934         null_pw = data_blob(NULL, 0);
1935
1936         become_root();
1937         conn = make_connection(qualname, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1938         unbecome_root();
1939
1940         if (conn == NULL) {
1941                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1942                 r_u->status = ntstatus_to_werror(nt_status);
1943                 goto error_exit;
1944         }
1945
1946         if (!become_user(conn, conn->vuid)) {
1947                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1948                 r_u->status = WERR_ACCESS_DENIED;
1949                 goto error_exit;
1950         }
1951         became_user = True;
1952
1953         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1954         unix_convert(filename, conn, NULL, &bad_path, &st);
1955         if (bad_path) {
1956                 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
1957                 r_u->status = WERR_ACCESS_DENIED;
1958                 goto error_exit;
1959         }
1960
1961         if (!check_name(filename,conn)) {
1962                 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
1963                 r_u->status = WERR_ACCESS_DENIED;
1964                 goto error_exit;
1965         }
1966
1967         nt_status = open_file_stat(conn, filename, &st, &fsp);
1968         if (!NT_STATUS_IS_OK(nt_status)) {
1969                 /* Perhaps it is a directory */
1970                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1971                         nt_status = open_directory(conn, filename, &st,
1972                                         READ_CONTROL_ACCESS,
1973                                         FILE_SHARE_READ|FILE_SHARE_WRITE,
1974                                         FILE_OPEN,
1975                                         0,
1976                                         NULL, &fsp);
1977
1978                 if (!NT_STATUS_IS_OK(nt_status)) {
1979                         DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1980                         r_u->status = WERR_ACCESS_DENIED;
1981                         goto error_exit;
1982                 }
1983         }
1984
1985         sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1986
1987         if (sd_size == 0) {
1988                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1989                 r_u->status = WERR_ACCESS_DENIED;
1990                 goto error_exit;
1991         }
1992
1993         r_u->ptr_response = 1;
1994         r_u->size_response = sd_size;
1995         r_u->ptr_secdesc = 1;
1996         r_u->size_secdesc = sd_size;
1997         r_u->sec_desc = psd;
1998
1999         psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2000
2001         close_file(fsp, NORMAL_CLOSE);
2002         unbecome_user();
2003         close_cnum(conn, p->pipe_user.vuid);
2004         return r_u->status;
2005
2006 error_exit:
2007
2008         if(fsp) {
2009                 close_file(fsp, NORMAL_CLOSE);
2010         }
2011
2012         if (became_user)
2013                 unbecome_user();
2014
2015         if (conn) 
2016                 close_cnum(conn, p->pipe_user.vuid);
2017
2018         return r_u->status;
2019 }
2020
2021 /***********************************************************************************
2022  Win9x NT tools set security descriptor.
2023 ***********************************************************************************/
2024
2025 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
2026                                                                         SRV_R_NET_FILE_SET_SECDESC *r_u)
2027 {
2028         BOOL ret;
2029         pstring filename;
2030         pstring qualname;
2031         DATA_BLOB null_pw;
2032         files_struct *fsp = NULL;
2033         SMB_STRUCT_STAT st;
2034         BOOL bad_path;
2035         NTSTATUS nt_status;
2036         connection_struct *conn = NULL;
2037         BOOL became_user = False;
2038
2039         ZERO_STRUCT(st);
2040
2041         r_u->status = WERR_OK;
2042
2043         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2044
2045         /* Null password is ok - we are already an authenticated user... */
2046         null_pw = data_blob(NULL, 0);
2047
2048         become_root();
2049         conn = make_connection(qualname, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2050         unbecome_root();
2051
2052         if (conn == NULL) {
2053                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2054                 r_u->status = ntstatus_to_werror(nt_status);
2055                 goto error_exit;
2056         }
2057
2058         if (!become_user(conn, conn->vuid)) {
2059                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2060                 r_u->status = WERR_ACCESS_DENIED;
2061                 goto error_exit;
2062         }
2063         became_user = True;
2064
2065         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2066         unix_convert(filename, conn, NULL, &bad_path, &st);
2067         if (bad_path) {
2068                 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2069                 r_u->status = WERR_ACCESS_DENIED;
2070                 goto error_exit;
2071         }
2072
2073         if (!check_name(filename,conn)) {
2074                 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2075                 r_u->status = WERR_ACCESS_DENIED;
2076                 goto error_exit;
2077         }
2078
2079
2080         nt_status = open_file_stat(conn, filename, &st, &fsp);
2081
2082         if (!NT_STATUS_IS_OK(nt_status)) {
2083                 /* Perhaps it is a directory */
2084                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2085                         nt_status = open_directory(conn, filename, &st,
2086                                                 FILE_READ_ATTRIBUTES,
2087                                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
2088                                                 FILE_OPEN,
2089                                                 0,
2090                                                 NULL, &fsp);
2091
2092                 if (!NT_STATUS_IS_OK(nt_status)) {
2093                         DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2094                         r_u->status = WERR_ACCESS_DENIED;
2095                         goto error_exit;
2096                 }
2097         }
2098
2099         ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2100
2101         if (ret == False) {
2102                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2103                 r_u->status = WERR_ACCESS_DENIED;
2104                 goto error_exit;
2105         }
2106
2107         close_file(fsp, NORMAL_CLOSE);
2108         unbecome_user();
2109         close_cnum(conn, p->pipe_user.vuid);
2110         return r_u->status;
2111
2112 error_exit:
2113
2114         if(fsp) {
2115                 close_file(fsp, NORMAL_CLOSE);
2116         }
2117
2118         if (became_user) {
2119                 unbecome_user();
2120         }
2121
2122         if (conn) {
2123                 close_cnum(conn, p->pipe_user.vuid);
2124         }
2125
2126         return r_u->status;
2127 }
2128
2129 /***********************************************************************************
2130  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2131  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2132  These disks would the disks listed by this function.
2133  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2134  "Nigel Williams" <nigel@veritas.com>.
2135 ***********************************************************************************/
2136
2137 static const char *server_disks[] = {"C:"};
2138
2139 static uint32 get_server_disk_count(void)
2140 {
2141         return sizeof(server_disks)/sizeof(server_disks[0]);
2142 }
2143
2144 static uint32 init_server_disk_enum(uint32 *resume)
2145 {
2146         uint32 server_disk_count = get_server_disk_count();
2147
2148         /*resume can be an offset into the list for now*/
2149
2150         if(*resume & 0x80000000)
2151                 *resume = 0;
2152
2153         if(*resume > server_disk_count)
2154                 *resume = server_disk_count;
2155
2156         return server_disk_count - *resume;
2157 }
2158
2159 static const char *next_server_disk_enum(uint32 *resume)
2160 {
2161         const char *disk;
2162
2163         if(init_server_disk_enum(resume) == 0)
2164                 return NULL;
2165
2166         disk = server_disks[*resume];
2167
2168         (*resume)++;
2169
2170         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2171
2172         return disk;
2173 }
2174
2175 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2176 {
2177         uint32 i;
2178         const char *disk_name;
2179         TALLOC_CTX *ctx = p->mem_ctx;
2180         uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2181
2182         r_u->status=WERR_OK;
2183
2184         r_u->total_entries = init_server_disk_enum(&resume);
2185
2186         r_u->disk_enum_ctr.unknown = 0; 
2187
2188         if(!(r_u->disk_enum_ctr.disk_info =  TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2189                 return WERR_NOMEM;
2190         }
2191
2192         r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2193
2194         /*allow one DISK_INFO for null terminator*/
2195
2196         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2197
2198                 r_u->disk_enum_ctr.entries_read++;
2199
2200                 /*copy disk name into a unicode string*/
2201
2202                 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);    
2203         }
2204
2205         /* add a terminating null string.  Is this there if there is more data to come? */
2206
2207         r_u->disk_enum_ctr.entries_read++;
2208
2209         init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2210
2211         init_enum_hnd(&r_u->enum_hnd, resume);
2212
2213         return r_u->status;
2214 }
2215
2216 /********************************************************************
2217 ********************************************************************/
2218
2219 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2220 {
2221         fstring sharename;
2222
2223         switch ( q_u->type ) {
2224         case 0x9:
2225                 rpcstr_pull(sharename, q_u->sharename.buffer, sizeof(sharename), q_u->sharename.uni_str_len*2, 0);
2226                 if ( !validate_net_name( sharename, INVALID_SHARENAME_CHARS, sizeof(sharename) ) ) {
2227                         DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", sharename));
2228                         return WERR_INVALID_NAME;
2229                 }
2230                 break;
2231
2232         default:
2233                 return WERR_UNKNOWN_LEVEL;
2234         }
2235
2236         return WERR_OK;
2237 }
2238
2239
2240 /********************************************************************
2241 ********************************************************************/
2242
2243 WERROR _srv_net_file_close(pipes_struct *p, SRV_Q_NET_FILE_CLOSE *q_u, SRV_R_NET_FILE_CLOSE *r_u)
2244 {
2245         return WERR_ACCESS_DENIED;
2246 }
2247