r17872: Fix possible null deref found by the Stanford checker.
[abartlet/samba.git/.git] / source3 / rpc_server / srv_srvsvc_nt.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Jeremy Allison               2001.
6  *  Copyright (C) Nigel Williams               2001.
7  *  Copyright (C) Gerald (Jerry) Carter        2006.
8  *  
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 /* This is the implementation of the srvsvc pipe. */
25
26 #include "includes.h"
27
28 extern struct generic_mapping file_generic_mapping;
29 extern userdom_struct current_user_info;
30
31 #undef DBGC_CLASS
32 #define DBGC_CLASS DBGC_RPC_SRV
33
34 /* Use for enumerating connections, pipes, & files */
35
36 struct file_enum_count {
37         TALLOC_CTX *ctx;
38         int count;
39         FILE_INFO_3 *info;
40 };
41
42 struct sess_file_count {
43         pid_t pid;
44         uid_t uid;
45         int count;
46 };
47
48 /****************************************************************************
49  Count the entries belonging to a service in the connection db.
50 ****************************************************************************/
51
52 static int pipe_enum_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p)
53 {
54         struct pipe_open_rec prec;
55         struct file_enum_count *fenum = (struct file_enum_count *)p;
56  
57         if (dbuf.dsize != sizeof(struct pipe_open_rec))
58                 return 0;
59
60         memcpy(&prec, dbuf.dptr, sizeof(struct pipe_open_rec));
61  
62         if ( process_exists(prec.pid) ) {
63                 FILE_INFO_3 *f;
64                 int i = fenum->count;
65                 pstring fullpath;
66                 
67                 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
68                 
69                 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, FILE_INFO_3, i+1 );
70                 if ( !f ) {
71                         DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
72                         return 1;
73                 }
74                 fenum->info = f;
75                 
76                 
77                 init_srv_file_info3( &fenum->info[i], 
78                         (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum),
79                         (FILE_READ_DATA|FILE_WRITE_DATA), 
80                         0,
81                         uidtoname( prec.uid ),
82                         fullpath );
83                         
84                 fenum->count++;
85         }
86
87         return 0;
88 }
89
90 /*******************************************************************
91 ********************************************************************/
92
93 static WERROR net_enum_pipes( TALLOC_CTX *ctx, FILE_INFO_3 **info, 
94                               uint32 *count, uint32 resume )
95 {
96         struct file_enum_count fenum;
97         TDB_CONTEXT *conn_tdb = conn_tdb_ctx();
98
99         if ( !conn_tdb ) {
100                 DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
101                 return WERR_ACCESS_DENIED;
102         }
103         
104         fenum.ctx = ctx;
105         fenum.count = *count;
106         fenum.info = *info;
107
108         if (tdb_traverse(conn_tdb, pipe_enum_fn, &fenum) == -1) {
109                 DEBUG(0,("net_enum_pipes: traverse of connections.tdb failed with error %s.\n",
110                         tdb_errorstr(conn_tdb) ));
111                 return WERR_NOMEM;
112         }
113         
114         *info  = fenum.info;
115         *count = fenum.count;
116         
117         return WERR_OK;}
118
119 /*******************************************************************
120 ********************************************************************/
121
122 /* global needed to make use of the share_mode_forall() callback */
123 static struct file_enum_count f_enum_cnt;
124
125 static void enum_file_fn( const struct share_mode_entry *e, 
126                           const char *sharepath, const char *fname,
127                           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_readonly(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                 if (snum) {
775                         (*snum) = 0;
776                 }
777                 SAFE_FREE(session_list);
778                 return;
779         }
780
781         DEBUG(5,("init_srv_sess_0_ss0\n"));
782
783         if (snum) {
784                 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
785                         init_srv_sess_info0( &ss0->info_0[num_entries], session_list[(*snum)].remote_machine);
786                         num_entries++;
787                 }
788
789                 ss0->num_entries_read  = num_entries;
790                 ss0->ptr_sess_info     = num_entries > 0 ? 1 : 0;
791                 ss0->num_entries_read2 = num_entries;
792                 
793                 if ((*snum) >= (*stot)) {
794                         (*snum) = 0;
795                 }
796
797         } else {
798                 ss0->num_entries_read = 0;
799                 ss0->ptr_sess_info = 0;
800                 ss0->num_entries_read2 = 0;
801         }
802         SAFE_FREE(session_list);
803 }
804
805 /*******************************************************************
806 ********************************************************************/
807
808 static void sess_file_fn( const struct share_mode_entry *e, 
809                           const char *sharepath, const char *fname,
810                           void *private_data )
811 {
812         struct sess_file_count *sess = (struct sess_file_count *)private_data;
813  
814         if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
815                 sess->count++;
816         }
817         
818         return;
819 }
820
821 /*******************************************************************
822 ********************************************************************/
823
824 static int net_count_files( uid_t uid, pid_t pid )
825 {
826         struct sess_file_count s_file_cnt;
827
828         s_file_cnt.count = 0;
829         s_file_cnt.uid = uid;
830         s_file_cnt.pid = pid;
831         
832         share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
833         
834         return s_file_cnt.count;
835 }
836
837 /*******************************************************************
838  fill in a sess info level 1 structure.
839  ********************************************************************/
840
841 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
842 {
843         struct sessionid *session_list;
844         uint32 num_entries = 0;
845         time_t now = time(NULL);
846
847         if ( !snum ) {
848                 ss1->num_entries_read = 0;
849                 ss1->ptr_sess_info = 0;
850                 ss1->num_entries_read2 = 0;
851                 
852                 (*stot) = 0;
853
854                 return;
855         }
856         
857         if (ss1 == NULL) {
858                 (*snum) = 0;
859                 return;
860         }
861
862         (*stot) = list_sessions(&session_list);
863         
864
865         for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
866                 uint32 num_files;
867                 uint32 connect_time;
868                 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
869                 BOOL guest;
870                         
871                 if ( !pw ) {
872                         DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
873                                 session_list[*snum].username));
874                         continue;
875                 }
876                                 
877                 connect_time = (uint32)(now - session_list[*snum].connect_start);
878                 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
879                 guest = strequal( session_list[*snum].username, lp_guestaccount() );
880                                         
881                 init_srv_sess_info1( &ss1->info_1[num_entries], 
882                                      session_list[*snum].remote_machine,
883                                      session_list[*snum].username, 
884                                      num_files,
885                                      connect_time,
886                                      0, 
887                                      guest);
888                 num_entries++;
889         }
890
891         ss1->num_entries_read  = num_entries;
892         ss1->ptr_sess_info     = num_entries > 0 ? 1 : 0;
893         ss1->num_entries_read2 = num_entries;
894         
895         if ((*snum) >= (*stot)) {
896                 (*snum) = 0;
897         }
898
899         SAFE_FREE(session_list);
900 }
901
902 /*******************************************************************
903  makes a SRV_R_NET_SESS_ENUM structure.
904 ********************************************************************/
905
906 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
907                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
908 {
909         WERROR status = WERR_OK;
910         DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
911
912         ctr->switch_value = switch_value;
913
914         switch (switch_value) {
915         case 0:
916                 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
917                 ctr->ptr_sess_ctr = 1;
918                 break;
919         case 1:
920                 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
921                 ctr->ptr_sess_ctr = 1;
922                 break;
923         default:
924                 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
925                 (*resume_hnd) = 0;
926                 (*total_entries) = 0;
927                 ctr->ptr_sess_ctr = 0;
928                 status = WERR_UNKNOWN_LEVEL;
929                 break;
930         }
931
932         return status;
933 }
934
935 /*******************************************************************
936  makes a SRV_R_NET_SESS_ENUM structure.
937 ********************************************************************/
938
939 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
940                                 uint32 resume_hnd, int sess_level, int switch_value)  
941 {
942         DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
943
944         r_n->sess_level  = sess_level;
945
946         if (sess_level == -1)
947                 r_n->status = WERR_UNKNOWN_LEVEL;
948         else
949                 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
950
951         if (!W_ERROR_IS_OK(r_n->status))
952                 resume_hnd = 0;
953
954         init_enum_hnd(&r_n->enum_hnd, resume_hnd);
955 }
956
957 /*******************************************************************
958  fill in a conn info level 0 structure.
959  ********************************************************************/
960
961 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
962 {
963         uint32 num_entries = 0;
964         (*stot) = 1;
965
966         if (ss0 == NULL) {
967                 (*snum) = 0;
968                 return;
969         }
970
971         DEBUG(5,("init_srv_conn_0_ss0\n"));
972
973         if (snum) {
974                 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
975
976                         init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
977
978                         /* move on to creating next connection */
979                         /* move on to creating next conn */
980                         num_entries++;
981                 }
982
983                 ss0->num_entries_read  = num_entries;
984                 ss0->ptr_conn_info     = num_entries > 0 ? 1 : 0;
985                 ss0->num_entries_read2 = num_entries;
986                 
987                 if ((*snum) >= (*stot)) {
988                         (*snum) = 0;
989                 }
990
991         } else {
992                 ss0->num_entries_read = 0;
993                 ss0->ptr_conn_info = 0;
994                 ss0->num_entries_read2 = 0;
995
996                 (*stot) = 0;
997         }
998 }
999
1000 /*******************************************************************
1001  fill in a conn info level 1 structure.
1002  ********************************************************************/
1003
1004 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1005                                 uint32 id, uint32 type,
1006                                 uint32 num_opens, uint32 num_users, uint32 open_time,
1007                                 const char *usr_name, const char *net_name)
1008 {
1009         init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1010         init_srv_conn_info1_str(str1, usr_name, net_name);
1011 }
1012
1013 /*******************************************************************
1014  fill in a conn info level 1 structure.
1015  ********************************************************************/
1016
1017 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1018 {
1019         uint32 num_entries = 0;
1020         (*stot) = 1;
1021
1022         if (ss1 == NULL) {
1023                 (*snum) = 0;
1024                 return;
1025         }
1026
1027         DEBUG(5,("init_srv_conn_1_ss1\n"));
1028
1029         if (snum) {
1030                 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1031                         init_srv_conn_1_info(&ss1->info_1[num_entries],
1032                                                                  &ss1->info_1_str[num_entries],
1033                                              (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1034
1035                         /* move on to creating next connection */
1036                         /* move on to creating next conn */
1037                         num_entries++;
1038                 }
1039
1040                 ss1->num_entries_read  = num_entries;
1041                 ss1->ptr_conn_info     = num_entries > 0 ? 1 : 0;
1042                 ss1->num_entries_read2 = num_entries;
1043                 
1044
1045                 if ((*snum) >= (*stot)) {
1046                         (*snum) = 0;
1047                 }
1048
1049         } else {
1050                 ss1->num_entries_read = 0;
1051                 ss1->ptr_conn_info = 0;
1052                 ss1->num_entries_read2 = 0;
1053                 
1054                 (*stot) = 0;
1055         }
1056 }
1057
1058 /*******************************************************************
1059  makes a SRV_R_NET_CONN_ENUM structure.
1060 ********************************************************************/
1061
1062 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1063                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1064 {
1065         WERROR status = WERR_OK;
1066         DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1067
1068         ctr->switch_value = switch_value;
1069
1070         switch (switch_value) {
1071         case 0:
1072                 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1073                 ctr->ptr_conn_ctr = 1;
1074                 break;
1075         case 1:
1076                 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1077                 ctr->ptr_conn_ctr = 1;
1078                 break;
1079         default:
1080                 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1081                 (*resume_hnd = 0);
1082                 (*total_entries) = 0;
1083                 ctr->ptr_conn_ctr = 0;
1084                 status = WERR_UNKNOWN_LEVEL;
1085                 break;
1086         }
1087
1088         return status;
1089 }
1090
1091 /*******************************************************************
1092  makes a SRV_R_NET_CONN_ENUM structure.
1093 ********************************************************************/
1094
1095 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1096                                 uint32 resume_hnd, int conn_level, int switch_value)  
1097 {
1098         DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1099
1100         r_n->conn_level  = conn_level;
1101         if (conn_level == -1)
1102                 r_n->status = WERR_UNKNOWN_LEVEL;
1103         else
1104                 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1105
1106         if (!W_ERROR_IS_OK(r_n->status))
1107                 resume_hnd = 0;
1108
1109         init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1110 }
1111
1112 /*******************************************************************
1113  makes a SRV_R_NET_FILE_ENUM structure.
1114 ********************************************************************/
1115
1116 static WERROR net_file_enum_3( SRV_R_NET_FILE_ENUM *r, uint32 resume_hnd )
1117 {
1118         TALLOC_CTX *ctx = get_talloc_ctx();
1119         SRV_FILE_INFO_CTR *ctr = &r->ctr;
1120
1121         /* TODO -- Windows enumerates 
1122            (b) active pipes
1123            (c) open directories and files */
1124
1125         r->status = net_enum_files( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
1126         if ( !W_ERROR_IS_OK(r->status))
1127                 goto done;
1128                 
1129         r->status = net_enum_pipes( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
1130         if ( !W_ERROR_IS_OK(r->status))
1131                 goto done;
1132         
1133         r->level = ctr->level = 3;
1134         r->total_entries = ctr->num_entries;
1135         /* ctr->num_entries = r->total_entries - resume_hnd; */
1136         ctr->num_entries2 = ctr->num_entries;
1137         ctr->ptr_file_info = 1;
1138
1139         r->status = WERR_OK;
1140
1141 done:
1142         if ( ctr->num_entries > 0 ) 
1143                 ctr->ptr_entries = 1;
1144
1145         init_enum_hnd(&r->enum_hnd, 0);
1146
1147         return r->status;
1148 }
1149
1150 /*******************************************************************
1151 *******************************************************************/
1152
1153 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1154 {
1155         switch ( q_u->level ) {
1156         case 3:
1157                 return net_file_enum_3( r_u, get_enum_hnd(&q_u->enum_hnd) );    
1158         default:
1159                 return WERR_UNKNOWN_LEVEL;
1160         }
1161         
1162         return WERR_OK;
1163 }
1164
1165 /*******************************************************************
1166 net server get info
1167 ********************************************************************/
1168
1169 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)
1170 {
1171         WERROR status = WERR_OK;
1172         SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR);
1173
1174         if (!ctr)
1175                 return WERR_NOMEM;
1176
1177         ZERO_STRUCTP(ctr);
1178
1179         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1180
1181         if (!pipe_access_check(p)) {
1182                 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1183                 return WERR_ACCESS_DENIED;
1184         }
1185
1186         switch (q_u->switch_value) {
1187
1188                 /* Technically level 102 should only be available to
1189                    Administrators but there isn't anything super-secret
1190                    here, as most of it is made up. */
1191
1192         case 102:
1193                 init_srv_info_102(&ctr->srv.sv102,
1194                                   500, global_myname(), 
1195                                   string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1196                                   lp_major_announce_version(), lp_minor_announce_version(),
1197                                   lp_default_server_announce(),
1198                                   0xffffffff, /* users */
1199                                   0xf, /* disc */
1200                                   0, /* hidden */
1201                                   240, /* announce */
1202                                   3000, /* announce delta */
1203                                   100000, /* licenses */
1204                                   "c:\\"); /* user path */
1205                 break;
1206         case 101:
1207                 init_srv_info_101(&ctr->srv.sv101,
1208                                   500, global_myname(),
1209                                   lp_major_announce_version(), lp_minor_announce_version(),
1210                                   lp_default_server_announce(),
1211                                   string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1212                 break;
1213         case 100:
1214                 init_srv_info_100(&ctr->srv.sv100, 500, global_myname());
1215                 break;
1216         default:
1217                 status = WERR_UNKNOWN_LEVEL;
1218                 break;
1219         }
1220
1221         /* set up the net server get info structure */
1222         init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1223
1224         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1225
1226         return r_u->status;
1227 }
1228
1229 /*******************************************************************
1230 net server set info
1231 ********************************************************************/
1232
1233 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)
1234 {
1235         WERROR status = WERR_OK;
1236
1237         DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1238
1239         /* Set up the net server set info structure. */
1240
1241         init_srv_r_net_srv_set_info(r_u, 0x0, status);
1242
1243         DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1244
1245         return r_u->status;
1246 }
1247
1248 /*******************************************************************
1249 net conn enum
1250 ********************************************************************/
1251
1252 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1253 {
1254         DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1255
1256         r_u->ctr = TALLOC_P(p->mem_ctx, SRV_CONN_INFO_CTR);
1257         if (!r_u->ctr)
1258                 return WERR_NOMEM;
1259
1260         ZERO_STRUCTP(r_u->ctr);
1261
1262         /* set up the */
1263         init_srv_r_net_conn_enum(r_u,
1264                                 get_enum_hnd(&q_u->enum_hnd),
1265                                 q_u->conn_level,
1266                                 q_u->ctr->switch_value);
1267
1268         DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1269
1270         return r_u->status;
1271 }
1272
1273 /*******************************************************************
1274 net sess enum
1275 ********************************************************************/
1276
1277 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1278 {
1279         DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1280
1281         r_u->ctr = TALLOC_P(p->mem_ctx, SRV_SESS_INFO_CTR);
1282         if (!r_u->ctr)
1283                 return WERR_NOMEM;
1284
1285         ZERO_STRUCTP(r_u->ctr);
1286
1287         /* set up the */
1288         init_srv_r_net_sess_enum(r_u,
1289                                 get_enum_hnd(&q_u->enum_hnd),
1290                                 q_u->sess_level,
1291                                 q_u->ctr->switch_value);
1292
1293         DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1294
1295         return r_u->status;
1296 }
1297
1298 /*******************************************************************
1299 net sess del
1300 ********************************************************************/
1301
1302 WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u)
1303 {
1304         struct sessionid *session_list;
1305         int num_sessions, snum;
1306         fstring username;
1307         fstring machine;
1308
1309         rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name);
1310         rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name);
1311
1312         /* strip leading backslashes if any */
1313         while (machine[0] == '\\') {
1314                 memmove(machine, &machine[1], strlen(machine));
1315         }
1316
1317         num_sessions = list_sessions(&session_list);
1318
1319         DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1320
1321         r_u->status = WERR_ACCESS_DENIED;
1322
1323         /* fail out now if you are not root or not a domain admin */
1324
1325         if ((p->pipe_user.ut.uid != sec_initial_uid()) && 
1326                 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1327
1328                 goto done;
1329         }
1330
1331         for (snum = 0; snum < num_sessions; snum++) {
1332
1333                 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1334                     strequal(session_list[snum].remote_machine, machine)) {
1335                 
1336                         if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))
1337                                 r_u->status = WERR_OK;
1338                 }
1339         }
1340
1341         DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1342
1343
1344 done:
1345         SAFE_FREE(session_list);
1346
1347         return r_u->status;
1348 }
1349
1350 /*******************************************************************
1351  Net share enum all.
1352 ********************************************************************/
1353
1354 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1355 {
1356         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1357
1358         if (!pipe_access_check(p)) {
1359                 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1360                 return WERR_ACCESS_DENIED;
1361         }
1362
1363         /* Create the list of shares for the response. */
1364         init_srv_r_net_share_enum(p, r_u,
1365                                 q_u->ctr.info_level,
1366                                 get_enum_hnd(&q_u->enum_hnd), True);
1367
1368         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1369
1370         return r_u->status;
1371 }
1372
1373 /*******************************************************************
1374  Net share enum.
1375 ********************************************************************/
1376
1377 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1378 {
1379         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1380
1381         if (!pipe_access_check(p)) {
1382                 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1383                 return WERR_ACCESS_DENIED;
1384         }
1385
1386         /* Create the list of shares for the response. */
1387         init_srv_r_net_share_enum(p, r_u,
1388                                   q_u->ctr.info_level,
1389                                   get_enum_hnd(&q_u->enum_hnd), False);
1390
1391         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1392
1393         return r_u->status;
1394 }
1395
1396 /*******************************************************************
1397  Net share get info.
1398 ********************************************************************/
1399
1400 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)
1401 {
1402         fstring share_name;
1403
1404         DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1405
1406         /* Create the list of shares for the response. */
1407         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1408         init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1409
1410         DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1411
1412         return r_u->status;
1413 }
1414
1415 /*******************************************************************
1416  Check a given DOS pathname is valid for a share.
1417 ********************************************************************/
1418
1419 char *valid_share_pathname(char *dos_pathname)
1420 {
1421         char *ptr;
1422
1423         /* Convert any '\' paths to '/' */
1424         unix_format(dos_pathname);
1425         unix_clean_name(dos_pathname);
1426
1427         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1428         ptr = dos_pathname;
1429         if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1430                 ptr += 2;
1431
1432         /* Only absolute paths allowed. */
1433         if (*ptr != '/')
1434                 return NULL;
1435
1436         return ptr;
1437 }
1438
1439 /*******************************************************************
1440  Net share set info. Modify share details.
1441 ********************************************************************/
1442
1443 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)
1444 {
1445         pstring command;
1446         fstring share_name;
1447         fstring comment;
1448         pstring pathname;
1449         int type;
1450         int snum;
1451         int ret;
1452         char *path;
1453         SEC_DESC *psd = NULL;
1454         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1455         BOOL is_disk_op = False;
1456         int max_connections = 0;
1457
1458         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1459
1460         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1461
1462         r_u->parm_error = 0;
1463
1464         if ( strequal(share_name,"IPC$") 
1465                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1466                 || strequal(share_name,"global") )
1467         {
1468                 return WERR_ACCESS_DENIED;
1469         }
1470
1471         snum = find_service(share_name);
1472
1473         /* Does this share exist ? */
1474         if (snum < 0)
1475                 return WERR_NET_NAME_NOT_FOUND;
1476
1477         /* No change to printer shares. */
1478         if (lp_print_ok(snum))
1479                 return WERR_ACCESS_DENIED;
1480
1481         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1482         
1483         /* fail out now if you are not root and not a disk op */
1484         
1485         if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1486                 return WERR_ACCESS_DENIED;
1487
1488         switch (q_u->info_level) {
1489         case 1:
1490                 pstrcpy(pathname, lp_pathname(snum));
1491                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1492                 type = q_u->info.share.info2.info_2.type;
1493                 psd = NULL;
1494                 break;
1495         case 2:
1496                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1497                 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1498                 type = q_u->info.share.info2.info_2.type;
1499                 max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1500                 psd = NULL;
1501                 break;
1502 #if 0
1503                 /* not supported on set but here for completeness */
1504         case 501:
1505                 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1506                 type = q_u->info.share.info501.info_501.type;
1507                 psd = NULL;
1508                 break;
1509 #endif
1510         case 502:
1511                 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1512                 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1513                 type = q_u->info.share.info502.info_502.type;
1514                 psd = q_u->info.share.info502.info_502_str.sd;
1515                 map_generic_share_sd_bits(psd);
1516                 break;
1517         case 1004:
1518                 pstrcpy(pathname, lp_pathname(snum));
1519                 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1520                 type = STYPE_DISKTREE;
1521                 break;
1522         case 1005:
1523                 /* XP re-sets the csc policy even if it wasn't changed by the
1524                    user, so we must compare it to see if it's what is set in
1525                    smb.conf, so that we can contine other ops like setting
1526                    ACLs on a share */
1527                 if (((q_u->info.share.info1005.share_info_flags &
1528                       SHARE_1005_CSC_POLICY_MASK) >>
1529                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1530                         return WERR_OK;
1531                 else {
1532                         DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1533                         return WERR_ACCESS_DENIED;
1534                 }
1535         case 1006:
1536         case 1007:
1537                 return WERR_ACCESS_DENIED;
1538         case 1501:
1539                 pstrcpy(pathname, lp_pathname(snum));
1540                 fstrcpy(comment, lp_comment(snum));
1541                 psd = q_u->info.share.info1501.sdb->sec;
1542                 map_generic_share_sd_bits(psd);
1543                 type = STYPE_DISKTREE;
1544                 break;
1545         default:
1546                 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1547                 return WERR_UNKNOWN_LEVEL;
1548         }
1549
1550         /* We can only modify disk shares. */
1551         if (type != STYPE_DISKTREE)
1552                 return WERR_ACCESS_DENIED;
1553                 
1554         /* Check if the pathname is valid. */
1555         if (!(path = valid_share_pathname( pathname )))
1556                 return WERR_OBJECT_PATH_INVALID;
1557
1558         /* Ensure share name, pathname and comment don't contain '"' characters. */
1559         string_replace(share_name, '"', ' ');
1560         string_replace(path, '"', ' ');
1561         string_replace(comment, '"', ' ');
1562
1563         DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1564                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1565
1566         /* Only call modify function if something changed. */
1567         
1568         if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) 
1569                 || (lp_max_connections(snum) != max_connections) ) 
1570         {
1571                 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1572                         DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1573                         return WERR_ACCESS_DENIED;
1574                 }
1575
1576                 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1577                                 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections ); 
1578
1579                 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1580                                 
1581                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1582         
1583                 if ( is_disk_op )
1584                         become_root();
1585                         
1586                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1587                         /* Tell everyone we updated smb.conf. */
1588                         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1589                 }
1590                 
1591                 if ( is_disk_op )
1592                         unbecome_root();
1593                         
1594                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1595
1596                 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));              
1597         
1598                 if ( ret != 0 )
1599                         return WERR_ACCESS_DENIED;
1600         } else {
1601                 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1602         }
1603
1604         /* Replace SD if changed. */
1605         if (psd) {
1606                 SEC_DESC *old_sd;
1607                 size_t sd_size;
1608
1609                 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1610                                             &sd_size);
1611
1612                 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1613                         if (!set_share_security(p->mem_ctx, share_name, psd))
1614                                 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1615                                         share_name ));
1616                 }
1617         }
1618                         
1619         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1620
1621         return WERR_OK;
1622 }
1623
1624 /*******************************************************************
1625  Net share add. Call 'add_share_command "sharename" "pathname" 
1626  "comment" "max connections = "
1627 ********************************************************************/
1628
1629 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1630 {
1631         pstring command;
1632         fstring share_name;
1633         fstring comment;
1634         pstring pathname;
1635         int type;
1636         int snum;
1637         int ret;
1638         char *path;
1639         SEC_DESC *psd = NULL;
1640         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1641         BOOL is_disk_op;
1642         int max_connections = 0;
1643
1644         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1645
1646         r_u->parm_error = 0;
1647
1648         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1649
1650         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1651                 return WERR_ACCESS_DENIED;
1652
1653         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1654                 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1655                 return WERR_ACCESS_DENIED;
1656         }
1657         
1658         switch (q_u->info_level) {
1659         case 0:
1660                 /* No path. Not enough info in a level 0 to do anything. */
1661                 return WERR_ACCESS_DENIED;
1662         case 1:
1663                 /* Not enough info in a level 1 to do anything. */
1664                 return WERR_ACCESS_DENIED;
1665         case 2:
1666                 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1667                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1668                 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1669                 max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses;
1670                 type = q_u->info.share.info2.info_2.type;
1671                 break;
1672         case 501:
1673                 /* No path. Not enough info in a level 501 to do anything. */
1674                 return WERR_ACCESS_DENIED;
1675         case 502:
1676                 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1677                 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1678                 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1679                 type = q_u->info.share.info502.info_502.type;
1680                 psd = q_u->info.share.info502.info_502_str.sd;
1681                 map_generic_share_sd_bits(psd);
1682                 break;
1683
1684                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */ 
1685
1686         case 1004:
1687         case 1005:
1688         case 1006:
1689         case 1007:
1690                 return WERR_ACCESS_DENIED;
1691         case 1501:
1692                 /* DFS only level. */
1693                 return WERR_ACCESS_DENIED;
1694         default:
1695                 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1696                 return WERR_UNKNOWN_LEVEL;
1697         }
1698
1699         /* check for invalid share names */
1700
1701         if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1702                 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1703                 return WERR_INVALID_NAME;
1704         }
1705
1706         if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1707                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1708         {
1709                 return WERR_ACCESS_DENIED;
1710         }
1711
1712         snum = find_service(share_name);
1713
1714         /* Share already exists. */
1715         if (snum >= 0)
1716                 return WERR_ALREADY_EXISTS;
1717
1718         /* We can only add disk shares. */
1719         if (type != STYPE_DISKTREE)
1720                 return WERR_ACCESS_DENIED;
1721                 
1722         /* Check if the pathname is valid. */
1723         if (!(path = valid_share_pathname( pathname )))
1724                 return WERR_OBJECT_PATH_INVALID;
1725
1726         /* Ensure share name, pathname and comment don't contain '"' characters. */
1727         string_replace(share_name, '"', ' ');
1728         string_replace(path, '"', ' ');
1729         string_replace(comment, '"', ' ');
1730
1731         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1732                         lp_add_share_cmd(), 
1733                         dyn_CONFIGFILE, 
1734                         share_name, 
1735                         path, 
1736                         comment, 
1737                         max_connections);
1738                         
1739         DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1740         
1741         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1742         
1743         if ( is_disk_op )
1744                 become_root();
1745
1746         if ( (ret = smbrun(command, NULL)) == 0 ) {
1747                 /* Tell everyone we updated smb.conf. */
1748                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1749         }
1750
1751         if ( is_disk_op )
1752                 unbecome_root();
1753                 
1754         /********* END SeDiskOperatorPrivilege BLOCK *********/
1755
1756         DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1757
1758         if ( ret != 0 )
1759                 return WERR_ACCESS_DENIED;
1760
1761         if (psd) {
1762                 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1763                         DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1764                 }
1765         }
1766
1767         /*
1768          * We don't call reload_services() here, the message will
1769          * cause this to be done before the next packet is read
1770          * from the client. JRA.
1771          */
1772
1773         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1774
1775         return WERR_OK;
1776 }
1777
1778 /*******************************************************************
1779  Net share delete. Call "delete share command" with the share name as
1780  a parameter.
1781 ********************************************************************/
1782
1783 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1784 {
1785         pstring command;
1786         fstring share_name;
1787         int ret;
1788         int snum;
1789         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1790         BOOL is_disk_op;
1791
1792         DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1793
1794         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1795
1796         if ( strequal(share_name,"IPC$") 
1797                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1798                 || strequal(share_name,"global") )
1799         {
1800                 return WERR_ACCESS_DENIED;
1801         }
1802
1803         snum = find_service(share_name);
1804
1805         if (snum < 0)
1806                 return WERR_NO_SUCH_SHARE;
1807
1808         /* No change to printer shares. */
1809         if (lp_print_ok(snum))
1810                 return WERR_ACCESS_DENIED;
1811
1812         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1813
1814         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1815                 return WERR_ACCESS_DENIED;
1816
1817         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1818                 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1819                 return WERR_ACCESS_DENIED;
1820         }
1821                 
1822         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1823                         lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1824
1825         DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1826
1827         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1828         
1829         if ( is_disk_op )
1830                 become_root();
1831
1832         if ( (ret = smbrun(command, NULL)) == 0 ) {
1833                 /* Tell everyone we updated smb.conf. */
1834                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1835         }
1836
1837         if ( is_disk_op )
1838                 unbecome_root();
1839                 
1840         /********* END SeDiskOperatorPrivilege BLOCK *********/
1841
1842         DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1843
1844         if ( ret != 0 )
1845                 return WERR_ACCESS_DENIED;
1846
1847         /* Delete the SD in the database. */
1848         delete_share_security(snum);
1849
1850         lp_killservice(snum);
1851
1852         return WERR_OK;
1853 }
1854
1855 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1856 {
1857         DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1858
1859         return _srv_net_share_del(p, q_u, r_u);
1860 }
1861
1862 /*******************************************************************
1863 time of day
1864 ********************************************************************/
1865
1866 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1867 {
1868         TIME_OF_DAY_INFO *tod;
1869         struct tm *t;
1870         time_t unixdate = time(NULL);
1871
1872         /* We do this call first as if we do it *after* the gmtime call
1873            it overwrites the pointed-to values. JRA */
1874
1875         uint32 zone = get_time_zone(unixdate)/60;
1876
1877         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1878
1879         if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) )
1880                 return WERR_NOMEM;
1881
1882         r_u->tod = tod;
1883         r_u->ptr_srv_tod = 0x1;
1884         r_u->status = WERR_OK;
1885
1886         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1887
1888         t = gmtime(&unixdate);
1889
1890         /* set up the */
1891         init_time_of_day_info(tod,
1892                               unixdate,
1893                               0,
1894                               t->tm_hour,
1895                               t->tm_min,
1896                               t->tm_sec,
1897                               0,
1898                               zone,
1899                               10000,
1900                               t->tm_mday,
1901                               t->tm_mon + 1,
1902                               1900+t->tm_year,
1903                               t->tm_wday);
1904         
1905         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1906
1907         return r_u->status;
1908 }
1909
1910 /***********************************************************************************
1911  Win9x NT tools get security descriptor.
1912 ***********************************************************************************/
1913
1914 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1915                         SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1916 {
1917         SEC_DESC *psd = NULL;
1918         size_t sd_size;
1919         DATA_BLOB null_pw;
1920         pstring filename;
1921         pstring qualname;
1922         files_struct *fsp = NULL;
1923         SMB_STRUCT_STAT st;
1924         BOOL bad_path;
1925         NTSTATUS nt_status;
1926         connection_struct *conn = NULL;
1927         BOOL became_user = False; 
1928
1929         ZERO_STRUCT(st);
1930
1931         r_u->status = WERR_OK;
1932
1933         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1934
1935         /* Null password is ok - we are already an authenticated user... */
1936         null_pw = data_blob(NULL, 0);
1937
1938         become_root();
1939         conn = make_connection(qualname, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1940         unbecome_root();
1941
1942         if (conn == NULL) {
1943                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1944                 r_u->status = ntstatus_to_werror(nt_status);
1945                 goto error_exit;
1946         }
1947
1948         if (!become_user(conn, conn->vuid)) {
1949                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1950                 r_u->status = WERR_ACCESS_DENIED;
1951                 goto error_exit;
1952         }
1953         became_user = True;
1954
1955         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1956         unix_convert(filename, conn, NULL, &bad_path, &st);
1957         if (bad_path) {
1958                 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
1959                 r_u->status = WERR_ACCESS_DENIED;
1960                 goto error_exit;
1961         }
1962
1963         if (!check_name(filename,conn)) {
1964                 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
1965                 r_u->status = WERR_ACCESS_DENIED;
1966                 goto error_exit;
1967         }
1968
1969         nt_status = open_file_stat(conn, filename, &st, &fsp);
1970         if (!NT_STATUS_IS_OK(nt_status)) {
1971                 /* Perhaps it is a directory */
1972                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1973                         nt_status = open_directory(conn, filename, &st,
1974                                         READ_CONTROL_ACCESS,
1975                                         FILE_SHARE_READ|FILE_SHARE_WRITE,
1976                                         FILE_OPEN,
1977                                         0,
1978                                         NULL, &fsp);
1979
1980                 if (!NT_STATUS_IS_OK(nt_status)) {
1981                         DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1982                         r_u->status = WERR_ACCESS_DENIED;
1983                         goto error_exit;
1984                 }
1985         }
1986
1987         sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1988
1989         if (sd_size == 0) {
1990                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1991                 r_u->status = WERR_ACCESS_DENIED;
1992                 goto error_exit;
1993         }
1994
1995         r_u->ptr_response = 1;
1996         r_u->size_response = sd_size;
1997         r_u->ptr_secdesc = 1;
1998         r_u->size_secdesc = sd_size;
1999         r_u->sec_desc = psd;
2000
2001         psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2002
2003         close_file(fsp, NORMAL_CLOSE);
2004         unbecome_user();
2005         close_cnum(conn, p->pipe_user.vuid);
2006         return r_u->status;
2007
2008 error_exit:
2009
2010         if(fsp) {
2011                 close_file(fsp, NORMAL_CLOSE);
2012         }
2013
2014         if (became_user)
2015                 unbecome_user();
2016
2017         if (conn) 
2018                 close_cnum(conn, p->pipe_user.vuid);
2019
2020         return r_u->status;
2021 }
2022
2023 /***********************************************************************************
2024  Win9x NT tools set security descriptor.
2025 ***********************************************************************************/
2026
2027 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
2028                                                                         SRV_R_NET_FILE_SET_SECDESC *r_u)
2029 {
2030         BOOL ret;
2031         pstring filename;
2032         pstring qualname;
2033         DATA_BLOB null_pw;
2034         files_struct *fsp = NULL;
2035         SMB_STRUCT_STAT st;
2036         BOOL bad_path;
2037         NTSTATUS nt_status;
2038         connection_struct *conn = NULL;
2039         BOOL became_user = False;
2040
2041         ZERO_STRUCT(st);
2042
2043         r_u->status = WERR_OK;
2044
2045         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2046
2047         /* Null password is ok - we are already an authenticated user... */
2048         null_pw = data_blob(NULL, 0);
2049
2050         become_root();
2051         conn = make_connection(qualname, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2052         unbecome_root();
2053
2054         if (conn == NULL) {
2055                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2056                 r_u->status = ntstatus_to_werror(nt_status);
2057                 goto error_exit;
2058         }
2059
2060         if (!become_user(conn, conn->vuid)) {
2061                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2062                 r_u->status = WERR_ACCESS_DENIED;
2063                 goto error_exit;
2064         }
2065         became_user = True;
2066
2067         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2068         unix_convert(filename, conn, NULL, &bad_path, &st);
2069         if (bad_path) {
2070                 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2071                 r_u->status = WERR_ACCESS_DENIED;
2072                 goto error_exit;
2073         }
2074
2075         if (!check_name(filename,conn)) {
2076                 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2077                 r_u->status = WERR_ACCESS_DENIED;
2078                 goto error_exit;
2079         }
2080
2081
2082         nt_status = open_file_stat(conn, filename, &st, &fsp);
2083
2084         if (!NT_STATUS_IS_OK(nt_status)) {
2085                 /* Perhaps it is a directory */
2086                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2087                         nt_status = open_directory(conn, filename, &st,
2088                                                 FILE_READ_ATTRIBUTES,
2089                                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
2090                                                 FILE_OPEN,
2091                                                 0,
2092                                                 NULL, &fsp);
2093
2094                 if (!NT_STATUS_IS_OK(nt_status)) {
2095                         DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2096                         r_u->status = WERR_ACCESS_DENIED;
2097                         goto error_exit;
2098                 }
2099         }
2100
2101         ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2102
2103         if (ret == False) {
2104                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2105                 r_u->status = WERR_ACCESS_DENIED;
2106                 goto error_exit;
2107         }
2108
2109         close_file(fsp, NORMAL_CLOSE);
2110         unbecome_user();
2111         close_cnum(conn, p->pipe_user.vuid);
2112         return r_u->status;
2113
2114 error_exit:
2115
2116         if(fsp) {
2117                 close_file(fsp, NORMAL_CLOSE);
2118         }
2119
2120         if (became_user) {
2121                 unbecome_user();
2122         }
2123
2124         if (conn) {
2125                 close_cnum(conn, p->pipe_user.vuid);
2126         }
2127
2128         return r_u->status;
2129 }
2130
2131 /***********************************************************************************
2132  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2133  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2134  These disks would the disks listed by this function.
2135  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2136  "Nigel Williams" <nigel@veritas.com>.
2137 ***********************************************************************************/
2138
2139 static const char *server_disks[] = {"C:"};
2140
2141 static uint32 get_server_disk_count(void)
2142 {
2143         return sizeof(server_disks)/sizeof(server_disks[0]);
2144 }
2145
2146 static uint32 init_server_disk_enum(uint32 *resume)
2147 {
2148         uint32 server_disk_count = get_server_disk_count();
2149
2150         /*resume can be an offset into the list for now*/
2151
2152         if(*resume & 0x80000000)
2153                 *resume = 0;
2154
2155         if(*resume > server_disk_count)
2156                 *resume = server_disk_count;
2157
2158         return server_disk_count - *resume;
2159 }
2160
2161 static const char *next_server_disk_enum(uint32 *resume)
2162 {
2163         const char *disk;
2164
2165         if(init_server_disk_enum(resume) == 0)
2166                 return NULL;
2167
2168         disk = server_disks[*resume];
2169
2170         (*resume)++;
2171
2172         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2173
2174         return disk;
2175 }
2176
2177 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2178 {
2179         uint32 i;
2180         const char *disk_name;
2181         TALLOC_CTX *ctx = p->mem_ctx;
2182         uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2183
2184         r_u->status=WERR_OK;
2185
2186         r_u->total_entries = init_server_disk_enum(&resume);
2187
2188         r_u->disk_enum_ctr.unknown = 0; 
2189
2190         if(!(r_u->disk_enum_ctr.disk_info =  TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2191                 return WERR_NOMEM;
2192         }
2193
2194         r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2195
2196         /*allow one DISK_INFO for null terminator*/
2197
2198         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2199
2200                 r_u->disk_enum_ctr.entries_read++;
2201
2202                 /*copy disk name into a unicode string*/
2203
2204                 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);    
2205         }
2206
2207         /* add a terminating null string.  Is this there if there is more data to come? */
2208
2209         r_u->disk_enum_ctr.entries_read++;
2210
2211         init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2212
2213         init_enum_hnd(&r_u->enum_hnd, resume);
2214
2215         return r_u->status;
2216 }
2217
2218 /********************************************************************
2219 ********************************************************************/
2220
2221 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2222 {
2223         fstring sharename;
2224
2225         switch ( q_u->type ) {
2226         case 0x9:
2227                 rpcstr_pull(sharename, q_u->sharename.buffer, sizeof(sharename), q_u->sharename.uni_str_len*2, 0);
2228                 if ( !validate_net_name( sharename, INVALID_SHARENAME_CHARS, sizeof(sharename) ) ) {
2229                         DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", sharename));
2230                         return WERR_INVALID_NAME;
2231                 }
2232                 break;
2233
2234         default:
2235                 return WERR_UNKNOWN_LEVEL;
2236         }
2237
2238         return WERR_OK;
2239 }
2240
2241
2242 /********************************************************************
2243 ********************************************************************/
2244
2245 WERROR _srv_net_file_close(pipes_struct *p, SRV_Q_NET_FILE_CLOSE *q_u, SRV_R_NET_FILE_CLOSE *r_u)
2246 {
2247         return WERR_ACCESS_DENIED;
2248 }
2249