r20017: Make srvsvc_NetShareAdd & friends take care of registry shares
[ira/wip.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  *  Copyright (C) Jelmer Vernooij                          2006.
9  *  
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 /* This is the implementation of the srvsvc pipe. */
26
27 #include "includes.h"
28
29 #define MAX_SERVER_DISK_ENTRIES 15
30
31 extern struct generic_mapping file_generic_mapping;
32 extern userdom_struct current_user_info;
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
36
37 /* Use for enumerating connections, pipes, & files */
38
39 struct file_enum_count {
40         TALLOC_CTX *ctx;
41         uint32 count;
42         struct srvsvc_NetFileInfo3 *info;
43 };
44
45 struct sess_file_count {
46         pid_t pid;
47         uid_t uid;
48         int count;
49 };
50
51 /****************************************************************************
52  Count the entries belonging to a service in the connection db.
53 ****************************************************************************/
54
55 static int pipe_enum_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p)
56 {
57         struct pipe_open_rec prec;
58         struct file_enum_count *fenum = (struct file_enum_count *)p;
59  
60         if (dbuf.dsize != sizeof(struct pipe_open_rec))
61                 return 0;
62
63         memcpy(&prec, dbuf.dptr, sizeof(struct pipe_open_rec));
64  
65         if ( process_exists(prec.pid) ) {
66                 struct srvsvc_NetFileInfo3 *f;
67                 int i = fenum->count;
68                 pstring fullpath;
69                 
70                 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
71                 
72                 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
73                 if ( !f ) {
74                         DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
75                         return 1;
76                 }
77
78                 fenum->info = f;
79                 
80                 fenum->info[i].fid = (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum);
81                 fenum->info[i].permissions = (FILE_READ_DATA|FILE_WRITE_DATA);
82                 fenum->info[i].num_locks = 0;
83                 fenum->info[i].user = uidtoname( prec.uid );
84                 fenum->info[i].path = fullpath;
85                         
86                 fenum->count++;
87         }
88
89         return 0;
90 }
91
92 /*******************************************************************
93 ********************************************************************/
94
95 static WERROR net_enum_pipes( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info, 
96                               uint32 *count, uint32 *resume )
97 {
98         struct file_enum_count fenum;
99         TDB_CONTEXT *conn_tdb = conn_tdb_ctx();
100
101         if ( !conn_tdb ) {
102                 DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
103                 return WERR_ACCESS_DENIED;
104         }
105         
106         fenum.ctx = ctx;
107         fenum.info = *info;
108         fenum.count = *count;
109
110         if (tdb_traverse(conn_tdb, pipe_enum_fn, &fenum) == -1) {
111                 DEBUG(0,("net_enum_pipes: traverse of connections.tdb failed with error %s.\n",
112                         tdb_errorstr(conn_tdb) ));
113                 return WERR_NOMEM;
114         }
115         
116         *info  = fenum.info;
117         *count = fenum.count;
118         
119         return WERR_OK;}
120
121 /*******************************************************************
122 ********************************************************************/
123
124 /* global needed to make use of the share_mode_forall() callback */
125 static struct file_enum_count f_enum_cnt;
126
127 static void enum_file_fn( const struct share_mode_entry *e, 
128                           const char *sharepath, const char *fname,
129                           void *dummy )
130 {
131         struct file_enum_count *fenum = &f_enum_cnt;
132  
133         /* If the pid was not found delete the entry from connections.tdb */
134
135         if ( process_exists(e->pid) ) {
136                 struct srvsvc_NetFileInfo3 *f;
137                 int i = fenum->count;
138                 files_struct fsp;
139                 struct byte_range_lock *brl;
140                 int num_locks = 0;
141                 pstring fullpath;
142                 uint32 permissions;
143                 
144                 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );                   
145                 if ( !f ) {
146                         DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
147                         return;
148                 }
149                 fenum->info = f;
150
151                 /* need to count the number of locks on a file */
152                 
153                 ZERO_STRUCT( fsp );             
154                 fsp.dev   = e->dev;
155                 fsp.inode = e->inode;
156                 
157                 if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) {
158                         num_locks = brl->num_locks;
159                         TALLOC_FREE( brl );
160                 }
161                 
162                 if ( strcmp( fname, "." ) == 0 ) {
163                         pstr_sprintf( fullpath, "C:%s", sharepath );
164                 } else {
165                         pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
166                 }
167                 string_replace( fullpath, '/', '\\' );
168                 
169                 /* mask out create (what ever that is) */
170                 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
171
172                 fenum->info[i].fid = e->share_file_id;
173                 fenum->info[i].permissions = permissions;
174                 fenum->info[i].num_locks = num_locks;
175                 fenum->info[i].user = uidtoname(e->uid);
176                 fenum->info[i].path = fullpath;
177                         
178                 fenum->count++;
179         }
180
181         return;
182
183 }
184
185 /*******************************************************************
186 ********************************************************************/
187
188 static WERROR net_enum_files( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **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, struct srvsvc_NetShareInfo0 *sh0,
229                                   const struct share_params *params)
230 {
231         sh0->name = lp_servicename(params->service);
232 }
233
234 /*******************************************************************
235  Fill in a share info level 1 structure.
236  ********************************************************************/
237
238 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1,
239                                   const struct share_params *params)
240 {
241         connection_struct *conn = p->conn;
242
243         sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
244                                      conn->user, conn->connectpath, conn->gid,
245                                      get_current_username(),
246                                      current_user_info.domain,
247                                      lp_comment(params->service));
248
249         sh1->name = lp_servicename(params->service);
250         sh1->type = get_share_type(params);
251 }
252
253 /*******************************************************************
254  Fill in a share info level 2 structure.
255  ********************************************************************/
256
257 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2,
258                                   const struct share_params *params)
259 {
260         connection_struct *conn = p->conn;
261         char *remark;
262         char *path;
263         int max_connections = lp_max_connections(params->service);
264         uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
265         int count = 0;
266         char *net_name = lp_servicename(params->service);
267         
268         remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
269                                      conn->user, conn->connectpath, conn->gid,
270                                      get_current_username(),
271                                      current_user_info.domain,
272                                      lp_comment(params->service));
273         path = talloc_asprintf(p->mem_ctx, "C:%s",
274                                lp_pathname(params->service));
275
276         /*
277          * Change / to \\ so that win2k will see it as a valid path.  This was
278          * added to enable use of browsing in win2k add share dialog.
279          */ 
280
281         string_replace(path, '/', '\\');
282
283         count = count_current_connections( net_name, False  );
284         sh2->name = net_name;
285         sh2->type = get_share_type(params);
286         sh2->comment = remark;
287         sh2->permissions = 0;
288         sh2->max_users = max_uses;
289         sh2->current_users = count;
290         sh2->path = path;
291         sh2->password = "";
292 }
293
294 /*******************************************************************
295  Map any generic bits to file specific bits.
296 ********************************************************************/
297
298 static void map_generic_share_sd_bits(SEC_DESC *psd)
299 {
300         int i;
301         SEC_ACL *ps_dacl = NULL;
302
303         if (!psd)
304                 return;
305
306         ps_dacl = psd->dacl;
307         if (!ps_dacl)
308                 return;
309
310         for (i = 0; i < ps_dacl->num_aces; i++) {
311                 SEC_ACE *psa = &ps_dacl->aces[i];
312                 uint32 orig_mask = psa->access_mask;
313
314                 se_map_generic(&psa->access_mask, &file_generic_mapping);
315                 psa->access_mask |= orig_mask;
316         }       
317 }
318
319 /*******************************************************************
320  Fill in a share info level 501 structure.
321 ********************************************************************/
322
323 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501,
324                                     const struct share_params *params)
325 {
326         connection_struct *conn = p->conn;
327         char *remark;
328         const char *net_name = lp_servicename(params->service);
329
330         remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
331                                      conn->user, conn->connectpath, conn->gid,
332                                      get_current_username(),
333                                      current_user_info.domain,
334                                      lp_comment(params->service));
335
336
337         sh501->name = net_name;
338         sh501->type = get_share_type(params);
339         sh501->comment = remark;
340         sh501->csc_policy = (lp_csc_policy(params->service) << 4);
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, struct srvsvc_NetShareInfo502 *sh502,
348                                     const struct share_params *params)
349 {
350         int max_connections = lp_max_connections(params->service);
351         uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
352         connection_struct *conn = p->conn;
353         int count; 
354         char *net_name;
355         char *remark;
356         char *path;
357         SEC_DESC *sd;
358         size_t sd_size;
359         TALLOC_CTX *ctx = p->mem_ctx;
360
361
362         ZERO_STRUCTP(sh502);
363
364         net_name = lp_servicename(params->service);
365         count = count_current_connections( net_name, False  );
366
367         remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
368                                      conn->user, conn->connectpath, conn->gid,
369                                      get_current_username(),
370                                      current_user_info.domain,
371                                      lp_comment(params->service));
372
373         path = talloc_asprintf(p->mem_ctx, "C:%s",
374                                lp_pathname(params->service));
375
376         /*
377          * Change / to \\ so that win2k will see it as a valid path.  This was
378          * added to enable use of browsing in win2k add share dialog.
379          */ 
380
381         string_replace(path, '/', '\\');
382
383         sd = get_share_security(ctx, lp_servicename(params->service),
384                                 &sd_size);
385
386         sh502->name = net_name;
387         sh502->type = get_share_type(params);
388         sh502->comment = remark;
389         sh502->path = path;
390         sh502->password = "";
391         sh502->sd = sd;
392         sh502->permissions = 0;
393         sh502->max_users = max_uses;
394         sh502->current_users = count;
395         sh502->unknown = 1;
396 }
397
398 /***************************************************************************
399  Fill in a share info level 1004 structure.
400  ***************************************************************************/
401
402 static void init_srv_share_info_1004(pipes_struct *p,
403                                      struct srvsvc_NetShareInfo1004* sh1004,
404                                      const struct share_params *params)
405 {
406         connection_struct *conn = p->conn;
407         char *remark;
408
409         remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
410                                      conn->user, conn->connectpath, conn->gid,
411                                      get_current_username(),
412                                      current_user_info.domain,
413                                      lp_comment(params->service));
414
415         ZERO_STRUCTP(sh1004);
416
417         sh1004->comment = remark;
418 }
419
420 /***************************************************************************
421  Fill in a share info level 1005 structure.
422  ***************************************************************************/
423
424 static void init_srv_share_info_1005(pipes_struct *p,
425                                      struct srvsvc_NetShareInfo1005* sh1005,
426                                      const struct share_params *params)
427 {
428         sh1005->dfs_flags = 0;
429
430         if(lp_host_msdfs() && lp_msdfs_root(params->service))
431                 sh1005->dfs_flags |= 
432                         SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
433         sh1005->dfs_flags |= 
434                 lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT;
435 }
436 /***************************************************************************
437  Fill in a share info level 1006 structure.
438  ***************************************************************************/
439
440 static void init_srv_share_info_1006(pipes_struct *p,
441                                      struct srvsvc_NetShareInfo1006* sh1006,
442                                      const struct share_params *params)
443 {
444         sh1006->max_users = -1;
445 }
446
447 /***************************************************************************
448  Fill in a share info level 1007 structure.
449  ***************************************************************************/
450
451 static void init_srv_share_info_1007(pipes_struct *p,
452                                      struct srvsvc_NetShareInfo1007* sh1007,
453                                      const struct share_params *params)
454 {
455         uint32 flags = 0;
456
457         ZERO_STRUCTP(sh1007);
458   
459         sh1007->flags = flags;
460         sh1007->alternate_directory_name = "";
461 }
462
463 /*******************************************************************
464  Fill in a share info level 1501 structure.
465  ********************************************************************/
466
467 static void init_srv_share_info_1501(pipes_struct *p,
468                                      struct sec_desc_buf *sh1501,
469                                      const struct share_params *params)
470 {
471         SEC_DESC *sd;
472         size_t sd_size;
473         TALLOC_CTX *ctx = p->mem_ctx;
474
475         ZERO_STRUCTP(sh1501);
476
477         sd = get_share_security(ctx, lp_servicename(params->service),
478                                 &sd_size);
479
480         sh1501->sd = sd;
481 }
482
483 /*******************************************************************
484  True if it ends in '$'.
485  ********************************************************************/
486
487 static BOOL is_hidden_share(const struct share_params *params)
488 {
489         const char *net_name = lp_servicename(params->service);
490
491         return (net_name[strlen(net_name) - 1] == '$');
492 }
493
494 /*******************************************************************
495  Fill in a share info structure.
496  ********************************************************************/
497
498 static WERROR init_srv_share_info_ctr(pipes_struct *p,
499                                       union srvsvc_NetShareCtr *ctr,
500                                       uint32 info_level, uint32 *resume_hnd,
501                                       uint32 *total_entries, BOOL all_shares)
502 {
503         TALLOC_CTX *ctx = p->mem_ctx;
504         struct share_iterator *shares;
505         struct share_params *share;
506         WERROR result = WERR_NOMEM;
507
508         DEBUG(5,("init_srv_share_info_ctr\n"));
509
510         ZERO_STRUCTP(ctr);
511
512         if (resume_hnd) {
513                 *resume_hnd = 0;
514         }
515
516         /* Ensure all the usershares are loaded. */
517         become_root();
518         load_usershare_shares();
519         load_registry_shares();
520         unbecome_root();
521
522         *total_entries = 0;
523
524         if (!(shares = share_list_all(ctx))) {
525                 DEBUG(5, ("Could not list shares\n"));
526                 return WERR_ACCESS_DENIED;
527         }
528
529         switch (info_level) {
530         case 0:
531                 if (!(ctr->ctr0 = talloc_zero(
532                               p->mem_ctx, struct srvsvc_NetShareCtr0))) {
533                         goto done;
534                 }
535                 break;
536         case 1:
537                 if (!(ctr->ctr1 = talloc_zero(
538                               p->mem_ctx, struct srvsvc_NetShareCtr1))) {
539                         goto done;
540                 }
541                 break;
542         case 2:
543                 if (!(ctr->ctr2 = talloc_zero(
544                               p->mem_ctx, struct srvsvc_NetShareCtr2))) {
545                         goto done;
546                 }
547                 break;
548         case 501:
549                 if (!(ctr->ctr501 = talloc_zero(
550                               p->mem_ctx, struct srvsvc_NetShareCtr501))) {
551                         goto done;
552                 }
553                 break;
554         case 502:
555                 if (!(ctr->ctr502 = talloc_zero(
556                               p->mem_ctx, struct srvsvc_NetShareCtr502))) {
557                         goto done;
558                 }
559                 break;
560         case 1004:
561                 if (!(ctr->ctr1004 = talloc_zero(
562                               p->mem_ctx, struct srvsvc_NetShareCtr1004))) {
563                         goto done;
564                 }
565                 break;
566         case 1005:
567                 if (!(ctr->ctr1005 = talloc_zero(
568                               p->mem_ctx, struct srvsvc_NetShareCtr1005))) {
569                         goto done;
570                 }
571                 break;
572         case 1006:
573                 if (!(ctr->ctr1006 = talloc_zero(
574                               p->mem_ctx, struct srvsvc_NetShareCtr1006))) {
575                         goto done;
576                 }
577                 break;
578         case 1007:
579                 if (!(ctr->ctr1007 = talloc_zero(
580                               p->mem_ctx, struct srvsvc_NetShareCtr1007))) {
581                         goto done;
582                 }
583                 break;
584         case 1501:
585                 if (!(ctr->ctr1501 = talloc_zero(
586                               p->mem_ctx, struct srvsvc_NetShareCtr1501))) {
587                         goto done;
588                 }
589                 break;
590         default:
591                 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
592                          "value %d\n", info_level));
593                 return WERR_UNKNOWN_LEVEL;
594         }
595
596         while ((share = next_share(shares)) != NULL) {
597                 if (!lp_browseable(share->service)) {
598                         continue;
599                 }
600                 if (!all_shares && is_hidden_share(share)) {
601                         continue;
602                 }
603
604                 switch (info_level) {
605                 case 0:
606                 {
607                         struct srvsvc_NetShareInfo0 i;
608                         init_srv_share_info_0(p, &i, share);
609                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
610                                      &ctr->ctr0->array, &ctr->ctr0->count);
611                         if (ctr->ctr0->array == NULL) {
612                                 return WERR_NOMEM;
613                         }
614                         *total_entries = ctr->ctr0->count;
615                         break;
616                 }
617
618                 case 1:
619                 {
620                         struct srvsvc_NetShareInfo1 i;
621                         init_srv_share_info_1(p, &i, share);
622                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
623                                      &ctr->ctr1->array, &ctr->ctr1->count);
624                         if (ctr->ctr1->array == NULL) {
625                                 return WERR_NOMEM;
626                         }
627                         *total_entries = ctr->ctr1->count;
628                         break;
629                 }
630
631                 case 2:
632                 {
633                         struct srvsvc_NetShareInfo2 i;
634                         init_srv_share_info_2(p, &i, share);
635                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
636                                      &ctr->ctr2->array, &ctr->ctr2->count);
637                         if (ctr->ctr2->array == NULL) {
638                                 return WERR_NOMEM;
639                         }
640                         *total_entries = ctr->ctr2->count;
641                         break;
642                 }
643
644                 case 501:
645                 {
646                         struct srvsvc_NetShareInfo501 i;
647                         init_srv_share_info_501(p, &i, share);
648                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
649                                      &ctr->ctr501->array, &ctr->ctr501->count);
650                         if (ctr->ctr501->array == NULL) {
651                                 return WERR_NOMEM;
652                         }
653                         *total_entries = ctr->ctr501->count;
654                         break;
655                 }
656
657                 case 502:
658                 {
659                         struct srvsvc_NetShareInfo502 i;
660                         init_srv_share_info_502(p, &i, share);
661                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
662                                      &ctr->ctr502->array, &ctr->ctr502->count);
663                         if (ctr->ctr502->array == NULL) {
664                                 return WERR_NOMEM;
665                         }
666                         *total_entries = ctr->ctr502->count;
667                         break;
668                 }
669
670                 /* here for completeness but not currently used with enum
671                  * (1004 - 1501)*/
672         
673                 case 1004:
674                 {
675                         struct srvsvc_NetShareInfo1004 i;
676                         init_srv_share_info_1004(p, &i, share);
677                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
678                                      &ctr->ctr1004->array, &ctr->ctr1004->count);
679                         if (ctr->ctr1004->array == NULL) {
680                                 return WERR_NOMEM;
681                         }
682                         *total_entries = ctr->ctr1004->count;
683                         break;
684                 }
685
686                 case 1005:
687                 {
688                         struct srvsvc_NetShareInfo1005 i;
689                         init_srv_share_info_1005(p, &i, share);
690                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
691                                      &ctr->ctr1005->array, &ctr->ctr1005->count);
692                         if (ctr->ctr1005->array == NULL) {
693                                 return WERR_NOMEM;
694                         }
695                         *total_entries = ctr->ctr1005->count;
696                         break;
697                 }
698
699                 case 1006:
700                 {
701                         struct srvsvc_NetShareInfo1006 i;
702                         init_srv_share_info_1006(p, &i, share);
703                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
704                                      &ctr->ctr1006->array, &ctr->ctr1006->count);
705                         if (ctr->ctr1006->array == NULL) {
706                                 return WERR_NOMEM;
707                         }
708                         *total_entries = ctr->ctr1006->count;
709                         break;
710                 }
711
712                 case 1007:
713                 {
714                         struct srvsvc_NetShareInfo1007 i;
715                         init_srv_share_info_1007(p, &i, share);
716                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
717                                      &ctr->ctr1007->array, &ctr->ctr1007->count);
718                         if (ctr->ctr1007->array == NULL) {
719                                 return WERR_NOMEM;
720                         }
721                         *total_entries = ctr->ctr1007->count;
722                         break;
723                 }
724
725                 case 1501:
726                 {
727                         struct sec_desc_buf i;
728                         init_srv_share_info_1501(p, &i, share);
729                         ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
730                                      &ctr->ctr1501->array, &ctr->ctr1501->count);
731                         if (ctr->ctr1501->array == NULL) {
732                                 return WERR_NOMEM;
733                         }
734                         *total_entries = ctr->ctr1501->count;
735                         break;
736                 }
737                 }
738
739                 TALLOC_FREE(share);
740         }
741
742         result = WERR_OK;
743  done:
744         TALLOC_FREE(shares);
745         return result;
746 }
747
748 /*******************************************************************
749  fill in a sess info level 0 structure.
750  ********************************************************************/
751
752 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
753 {
754         struct sessionid *session_list;
755         uint32 num_entries = 0;
756         (*stot) = list_sessions(&session_list);
757
758         if (ss0 == NULL) {
759                 if (snum) {
760                         (*snum) = 0;
761                 }
762                 SAFE_FREE(session_list);
763                 return;
764         }
765
766         DEBUG(5,("init_srv_sess_0_ss0\n"));
767
768         ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
769
770         if (snum) {
771                 for (; (*snum) < (*stot); (*snum)++) {
772                         ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
773                         num_entries++;
774                 }
775
776                 ss0->count = num_entries;
777                 
778                 if ((*snum) >= (*stot)) {
779                         (*snum) = 0;
780                 }
781
782         } else {
783                 ss0->array = NULL;
784                 ss0->count = 0;
785         }
786         SAFE_FREE(session_list);
787 }
788
789 /*******************************************************************
790 ********************************************************************/
791
792 static void sess_file_fn( const struct share_mode_entry *e, 
793                           const char *sharepath, const char *fname,
794                           void *private_data )
795 {
796         struct sess_file_count *sess = (struct sess_file_count *)private_data;
797  
798         if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
799                 sess->count++;
800         }
801         
802         return;
803 }
804
805 /*******************************************************************
806 ********************************************************************/
807
808 static int net_count_files( uid_t uid, pid_t pid )
809 {
810         struct sess_file_count s_file_cnt;
811
812         s_file_cnt.count = 0;
813         s_file_cnt.uid = uid;
814         s_file_cnt.pid = pid;
815         
816         share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
817         
818         return s_file_cnt.count;
819 }
820
821 /*******************************************************************
822  fill in a sess info level 1 structure.
823  ********************************************************************/
824
825 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
826 {
827         struct sessionid *session_list;
828         uint32 num_entries = 0;
829         time_t now = time(NULL);
830
831         if ( !snum ) {
832                 ss1->count = 0;
833                 ss1->array = NULL;
834                 
835                 (*stot) = 0;
836
837                 return;
838         }
839         
840         if (ss1 == NULL) {
841                 if (snum != NULL)
842                         (*snum) = 0;
843                 return;
844         }
845
846         (*stot) = list_sessions(&session_list);
847
848         ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
849         
850         for (; (*snum) < (*stot); (*snum)++) {
851                 uint32 num_files;
852                 uint32 connect_time;
853                 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
854                 BOOL guest;
855                         
856                 if ( !pw ) {
857                         DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
858                                 session_list[*snum].username));
859                         continue;
860                 }
861                                 
862                 connect_time = (uint32)(now - session_list[*snum].connect_start);
863                 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
864                 guest = strequal( session_list[*snum].username, lp_guestaccount() );
865                                         
866                 ss1->array[num_entries].client = session_list[*snum].remote_machine;
867                 ss1->array[num_entries].user = session_list[*snum].username; 
868                 ss1->array[num_entries].num_open = num_files;
869                 ss1->array[num_entries].time = connect_time;
870                 ss1->array[num_entries].idle_time = 0;
871                 ss1->array[num_entries].user_flags = guest;
872
873                 num_entries++;
874         }
875
876         ss1->count = num_entries;
877         
878         if ((*snum) >= (*stot)) {
879                 (*snum) = 0;
880         }
881
882         SAFE_FREE(session_list);
883 }
884
885 /*******************************************************************
886  makes a SRV_R_NET_SESS_ENUM structure.
887 ********************************************************************/
888
889 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
890                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
891 {
892         WERROR status = WERR_OK;
893         DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
894
895         switch (switch_value) {
896         case 0:
897                 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
898                 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
899                 break;
900         case 1:
901                 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
902                 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
903                 break;
904         default:
905                 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
906                 if (resume_hnd != NULL)
907                         (*resume_hnd) = 0;
908                 (*total_entries) = 0;
909                 ctr->ctr0 = NULL;
910                 status = WERR_UNKNOWN_LEVEL;
911                 break;
912         }
913
914         return status;
915 }
916
917 /*******************************************************************
918  fill in a conn info level 0 structure.
919  ********************************************************************/
920
921 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
922 {
923         uint32 num_entries = 0;
924         (*stot) = 1;
925
926         if (ss0 == NULL) {
927                 if (snum != NULL)
928                         (*snum) = 0;
929                 return;
930         }
931
932         DEBUG(5,("init_srv_conn_0_ss0\n"));
933
934         if (snum) {
935                 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
936                 for (; (*snum) < (*stot); (*snum)++) {
937
938                         ss0->array[num_entries].conn_id = (*stot);
939
940                         /* move on to creating next connection */
941                         /* move on to creating next conn */
942                         num_entries++;
943                 }
944
945                 ss0->count = num_entries;
946                 
947                 if ((*snum) >= (*stot)) {
948                         (*snum) = 0;
949                 }
950
951         } else {
952                 ss0->array = NULL;
953                 ss0->count = 0;
954
955                 (*stot) = 0;
956         }
957 }
958
959 /*******************************************************************
960  fill in a conn info level 1 structure.
961  ********************************************************************/
962
963 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
964 {
965         uint32 num_entries = 0;
966         (*stot) = 1;
967
968         if (ss1 == NULL) {
969                 if (snum != NULL)
970                         (*snum) = 0;
971                 return;
972         }
973
974         DEBUG(5,("init_srv_conn_1_ss1\n"));
975
976         if (snum) {
977                 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
978                 for (; (*snum) < (*stot); (*snum)++) {
979                         ss1->array[num_entries].conn_id = (*stot);
980                         ss1->array[num_entries].conn_type = 0x3;
981                         ss1->array[num_entries].num_open = 1;
982                         ss1->array[num_entries].num_users = 1;
983                         ss1->array[num_entries].conn_time = 3;
984                         ss1->array[num_entries].user = "dummy_user";
985                         ss1->array[num_entries].share = "IPC$";
986
987                         /* move on to creating next connection */
988                         /* move on to creating next conn */
989                         num_entries++;
990                 }
991
992                 ss1->count = num_entries;
993
994                 if ((*snum) >= (*stot)) {
995                         (*snum) = 0;
996                 }
997
998         } else {
999                 ss1->count = 0;
1000                 ss1->array = NULL;
1001                 
1002                 (*stot) = 0;
1003         }
1004 }
1005
1006 /*******************************************************************
1007  makes a SRV_R_NET_CONN_ENUM structure.
1008 ********************************************************************/
1009
1010 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
1011                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1012 {
1013         WERROR status = WERR_OK;
1014         DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1015
1016         switch (switch_value) {
1017         case 0:
1018                 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
1019                 break;
1020         case 1:
1021                 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
1022                 break;
1023         default:
1024                 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1025                 ctr->ctr0 = NULL;
1026                 (*resume_hnd) = 0;
1027                 (*total_entries) = 0;
1028                 status = WERR_UNKNOWN_LEVEL;
1029                 break;
1030         }
1031
1032         return status;
1033 }
1034
1035 /*******************************************************************
1036  makes a SRV_R_NET_FILE_ENUM structure.
1037 ********************************************************************/
1038
1039 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, uint32 *resume_hnd, uint32 *num_entries )
1040 {
1041         TALLOC_CTX *ctx = get_talloc_ctx();
1042         WERROR status;
1043
1044         /* TODO -- Windows enumerates 
1045            (b) active pipes
1046            (c) open directories and files */
1047
1048         ctr->ctr3 = talloc_zero(p->mem_ctx, struct srvsvc_NetFileCtr3);
1049         
1050         status = net_enum_files( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1051         if ( !W_ERROR_IS_OK(status))
1052                 return status;
1053                 
1054         status = net_enum_pipes( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1055         if ( !W_ERROR_IS_OK(status))
1056                 return status;
1057
1058         ctr->ctr3->count = *num_entries;
1059         
1060         return WERR_OK;
1061 }
1062
1063 /*******************************************************************
1064 *******************************************************************/
1065
1066 WERROR _srvsvc_NetFileEnum(pipes_struct *p, const char *server_unc, const char *path, const char *user, uint32_t *level, union srvsvc_NetFileCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1067 {
1068         switch ( *level ) {
1069         case 3:
1070                 return net_file_enum_3(p, ctr, resume_handle, totalentries );   
1071         default:
1072                 return WERR_UNKNOWN_LEVEL;
1073         }
1074         
1075         return WERR_OK;
1076 }
1077
1078 /*******************************************************************
1079 net server get info
1080 ********************************************************************/
1081
1082 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo *info)
1083 {
1084         WERROR status = WERR_OK;
1085
1086         ZERO_STRUCTP(info);
1087
1088         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1089
1090         if (!pipe_access_check(p)) {
1091                 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1092                 return WERR_ACCESS_DENIED;
1093         }
1094
1095         switch (level) {
1096
1097                 /* Technically level 102 should only be available to
1098                    Administrators but there isn't anything super-secret
1099                    here, as most of it is made up. */
1100
1101         case 102:
1102                 info->info102 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1103
1104                 info->info102->platform_id = 500;
1105                 info->info102->version_major = lp_major_announce_version();
1106                 info->info102->version_minor = lp_minor_announce_version();
1107                 info->info102->server_name = global_myname(); 
1108                 info->info102->server_type = lp_default_server_announce();
1109                 info->info102->userpath = "C:\\";
1110                 info->info102->licenses = 10000;
1111                 info->info102->anndelta = 3000;
1112                 info->info102->disc = 0xf;
1113                 info->info102->users = 0xffffffff;
1114                 info->info102->hidden = 0;
1115                 info->info102->announce = 240;
1116                 info->info102->comment = lp_serverstring();
1117                 break;
1118         case 101:
1119                 info->info101 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1120                         info->info101->platform_id = 500;
1121                         info->info101->server_name = global_myname();
1122                         info->info101->version_major = lp_major_announce_version();
1123                         info->info101->version_minor = lp_minor_announce_version();
1124                         info->info101->server_type = lp_default_server_announce();
1125                         info->info101->comment = lp_serverstring();
1126                 break;
1127         case 100:
1128                 info->info100 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1129                 info->info100->platform_id = 500;
1130                 info->info100->server_name = global_myname();
1131                 break;
1132         default:
1133                 return WERR_UNKNOWN_LEVEL;
1134                 break;
1135         }
1136
1137         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1138
1139         return status;
1140 }
1141
1142 /*******************************************************************
1143 net server set info
1144 ********************************************************************/
1145
1146 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo info, uint32_t *parm_error)
1147 {
1148         /* Set up the net server set info structure. */
1149         if (parm_error) {
1150                 *parm_error = 0;
1151         }
1152         return WERR_OK;
1153 }
1154
1155 /*******************************************************************
1156 net conn enum
1157 ********************************************************************/
1158
1159 WERROR _srvsvc_NetConnEnum(pipes_struct *p, const char *server_unc, const char *path, uint32_t *level, union srvsvc_NetConnCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1160 {
1161         DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1162
1163         ZERO_STRUCTP(ctr);
1164
1165         /* set up the */
1166         return init_srv_conn_info_ctr(p, ctr, *level, resume_handle, totalentries);
1167 }
1168
1169 /*******************************************************************
1170 net sess enum
1171 ********************************************************************/
1172
1173 WERROR _srvsvc_NetSessEnum(pipes_struct *p, const char *server_unc, const char *client, const char *user, uint32_t *level, union srvsvc_NetSessCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1174 {
1175         DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1176
1177         ZERO_STRUCTP(ctr);
1178
1179         /* set up the */
1180         return init_srv_sess_info_ctr(p, ctr,
1181                                 *level, 
1182                                 resume_handle,
1183                                 totalentries);
1184 }
1185
1186 /*******************************************************************
1187 net sess del
1188 ********************************************************************/
1189
1190 WERROR _srvsvc_NetSessDel(pipes_struct *p, const char *server_unc, const char *client, const char *user)
1191 {
1192         struct sessionid *session_list;
1193         int num_sessions, snum;
1194         WERROR status;
1195
1196         char *machine = talloc_strdup(p->mem_ctx, server_unc);
1197
1198         /* strip leading backslashes if any */
1199         while (machine[0] == '\\') {
1200                 memmove(machine, &machine[1], strlen(machine));
1201         }
1202
1203         num_sessions = list_sessions(&session_list);
1204
1205         DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1206
1207         status = WERR_ACCESS_DENIED;
1208
1209         /* fail out now if you are not root or not a domain admin */
1210
1211         if ((p->pipe_user.ut.uid != sec_initial_uid()) && 
1212                 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1213
1214                 goto done;
1215         }
1216
1217         for (snum = 0; snum < num_sessions; snum++) {
1218
1219                 if ((strequal(session_list[snum].username, user) || user[0] == '\0' ) &&
1220                     strequal(session_list[snum].remote_machine, machine)) {
1221                 
1222                         if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))
1223                                 status = WERR_OK;
1224                 }
1225         }
1226
1227         DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1228
1229
1230 done:
1231         SAFE_FREE(session_list);
1232
1233         return status;
1234 }
1235
1236 /*******************************************************************
1237  Net share enum all.
1238 ********************************************************************/
1239
1240 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetShareCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1241 {
1242         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1243
1244         if (!pipe_access_check(p)) {
1245                 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1246                 return WERR_ACCESS_DENIED;
1247         }
1248
1249         /* Create the list of shares for the response. */
1250         return init_srv_share_info_ctr(p, ctr, *level,
1251                                               resume_handle, totalentries, True);
1252 }
1253
1254 /*******************************************************************
1255  Net share enum.
1256 ********************************************************************/
1257
1258 WERROR _srvsvc_NetShareEnum(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetShareCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1259 {
1260         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1261
1262         if (!pipe_access_check(p)) {
1263                 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1264                 return WERR_ACCESS_DENIED;
1265         }
1266
1267         /* Create the list of shares for the response. */
1268         return init_srv_share_info_ctr(p, ctr, *level,
1269                                               resume_handle, totalentries, False);
1270 }
1271
1272 /*******************************************************************
1273  Net share get info.
1274 ********************************************************************/
1275
1276 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t level, union srvsvc_NetShareInfo *info)
1277 {
1278         const struct share_params *params;
1279
1280         params = get_share_params(p->mem_ctx, share_name);
1281
1282         if (params != NULL) {
1283                 switch (level) {
1284                 case 0:
1285                         info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1286                         init_srv_share_info_0(p, info->info0,
1287                                               params);
1288                         break;
1289                 case 1:
1290                         info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1291                         init_srv_share_info_1(p, info->info1,
1292                                               params);
1293                         break;
1294                 case 2:
1295                         info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1296                         init_srv_share_info_2(p, info->info2,
1297                                               params);
1298                         break;
1299                 case 501:
1300                         info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1301                         init_srv_share_info_501(p, info->info501,
1302                                                 params);
1303                         break;
1304                 case 502:
1305                         info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1306                         init_srv_share_info_502(p, info->info502,
1307                                                 params);
1308                         break;
1309
1310                         /* here for completeness */
1311                 case 1004:
1312                         info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1313                         init_srv_share_info_1004(p, info->info1004,
1314                                                  params);
1315                         break;
1316                 case 1005:
1317                         info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1318                         init_srv_share_info_1005(p, info->info1005,
1319                                                  params);
1320                         break;
1321
1322                         /* here for completeness 1006 - 1501 */
1323                 case 1006:
1324                         info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1325                         init_srv_share_info_1006(p, info->info1006,
1326                                                  params);
1327                         break;
1328                 case 1007:
1329                         info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1330                         init_srv_share_info_1007(p, info->info1007,
1331                                                  params);
1332                         break;
1333                 case 1501:
1334                         info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1335                         init_srv_share_info_1501(p, info->info1501,
1336                                                  params);
1337                         break;
1338                 default:
1339                         DEBUG(5,("init_srv_net_share_get_info: unsupported "
1340                                  "switch value %d\n", level));
1341                         return WERR_UNKNOWN_LEVEL;
1342                         break;
1343                 }
1344         } else {
1345                 return WERR_INVALID_NAME;
1346         }
1347
1348         return WERR_OK;
1349 }
1350
1351 /*******************************************************************
1352  Check a given DOS pathname is valid for a share.
1353 ********************************************************************/
1354
1355 char *valid_share_pathname(char *dos_pathname)
1356 {
1357         char *ptr;
1358
1359         /* Convert any '\' paths to '/' */
1360         unix_format(dos_pathname);
1361         unix_clean_name(dos_pathname);
1362
1363         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1364         ptr = dos_pathname;
1365         if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1366                 ptr += 2;
1367
1368         /* Only absolute paths allowed. */
1369         if (*ptr != '/')
1370                 return NULL;
1371
1372         return ptr;
1373 }
1374
1375 static void setval_helper(struct registry_key *key, const char *name,
1376                           const char *value, WERROR *err)
1377 {
1378         struct registry_value val;
1379
1380         if (!W_ERROR_IS_OK(*err)) {
1381                 return;
1382         }
1383
1384         ZERO_STRUCT(val);
1385         val.type = REG_SZ;
1386         val.v.sz.str = CONST_DISCARD(char *, value);
1387         val.v.sz.len = strlen(value)+1;
1388
1389         *err = reg_setvalue(key, name, &val);
1390 }
1391
1392 static WERROR add_share(const char *share_name, const char *path,
1393                         const char *comment, uint32 max_connections,
1394                         const struct nt_user_token *token,
1395                         BOOL is_disk_op)
1396 {
1397         if (lp_add_share_cmd() && *lp_add_share_cmd()) {
1398                 char *command;
1399                 int ret;
1400
1401                 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1402                              lp_add_share_cmd(), dyn_CONFIGFILE, share_name,
1403                              path, comment, max_connections) == -1) {
1404                         return WERR_NOMEM;
1405                 }
1406
1407                 DEBUG(10,("add_share: Running [%s]\n", command ));
1408
1409                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1410         
1411                 if ( is_disk_op )
1412                         become_root();
1413
1414                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1415                         /* Tell everyone we updated smb.conf. */
1416                         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED,
1417                                          NULL, 0, False, NULL);
1418                 }
1419
1420                 if ( is_disk_op )
1421                         unbecome_root();
1422                 
1423                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1424
1425                 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n",
1426                          command, ret ));
1427
1428                 /*
1429                  * No fallback to registry shares, the user did define a add
1430                  * share command, so fail here.
1431                  */
1432
1433                 SAFE_FREE(command);
1434                 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1435         }
1436
1437         if (lp_registry_shares()) {
1438                 char *keyname;
1439                 struct registry_key *key;
1440                 enum winreg_CreateAction action;
1441                 WERROR err;
1442                 TALLOC_CTX *mem_ctx;
1443
1444                 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1445                                                 share_name))) {
1446                         return WERR_NOMEM;
1447                 }
1448
1449                 mem_ctx = (TALLOC_CTX *)keyname;
1450
1451                 err = reg_create_path(mem_ctx, keyname, REG_KEY_WRITE,
1452                                       is_disk_op ? get_root_nt_token():token,
1453                                       &action, &key);
1454
1455                 if (action != REG_CREATED_NEW_KEY) {
1456                         err = WERR_ALREADY_EXISTS;
1457                 }
1458
1459                 if (!W_ERROR_IS_OK(err)) {
1460                         TALLOC_FREE(mem_ctx);
1461                         return err;
1462                 }
1463
1464                 setval_helper(key, "path", path, &err);
1465                 if ((comment != NULL) && (comment[0] != '\0')) {
1466                         setval_helper(key, "comment", comment, &err);
1467                 }
1468                 if (max_connections != 0) {
1469                         char tmp[16];
1470                         snprintf(tmp, sizeof(tmp), "%d", max_connections);
1471                         setval_helper(key, "max connections", tmp, &err);
1472                 }
1473
1474                 if (!W_ERROR_IS_OK(err)) {
1475                         /*
1476                          * Hmmmm. We'd need transactions on the registry to
1477                          * get this right....
1478                          */
1479                         reg_delete_path(is_disk_op ? get_root_nt_token():token,
1480                                         keyname);
1481                 }
1482                 TALLOC_FREE(mem_ctx);
1483                 return err;
1484         }
1485
1486         return WERR_ACCESS_DENIED;
1487 }
1488
1489 static WERROR delete_share(const char *sharename, 
1490                            const struct nt_user_token *token,
1491                            BOOL is_disk_op)
1492 {
1493         if (lp_delete_share_cmd() && *lp_delete_share_cmd()) {
1494                 char *command;
1495                 int ret;
1496
1497                 if (asprintf(&command, "%s \"%s\" \"%s\"",
1498                              lp_delete_share_cmd(), dyn_CONFIGFILE,
1499                              sharename)) {
1500                         return WERR_NOMEM;
1501                 }
1502
1503                 DEBUG(10,("delete_share: Running [%s]\n", command ));
1504
1505                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1506         
1507                 if ( is_disk_op )
1508                         become_root();
1509
1510                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1511                         /* Tell everyone we updated smb.conf. */
1512                         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED,
1513                                          NULL, 0, False, NULL);
1514                 }
1515
1516                 if ( is_disk_op )
1517                         unbecome_root();
1518
1519                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1520
1521                 SAFE_FREE(command);
1522
1523                 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n",
1524                          command, ret ));
1525                 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1526         }
1527
1528         if (lp_registry_shares()) {
1529                 char *keyname;
1530                 WERROR err;
1531
1532                 if (asprintf(&keyname, "%s\\%s", KEY_SMBCONF,
1533                              sharename) == -1) {
1534                         return WERR_NOMEM;
1535                 }
1536
1537                 err = reg_delete_path(is_disk_op ? get_root_nt_token():token,
1538                                       keyname);
1539                 SAFE_FREE(keyname);
1540                 return err;
1541         }
1542
1543         return WERR_ACCESS_DENIED;
1544 }
1545
1546 static WERROR change_share(const char *share_name, const char *path,
1547                            const char *comment, uint32 max_connections,
1548                            const struct nt_user_token *token,
1549                            BOOL is_disk_op)
1550 {
1551         if (lp_change_share_cmd() && *lp_change_share_cmd()) {
1552                 char *command;
1553                 int ret;
1554
1555                 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1556                              lp_change_share_cmd(), dyn_CONFIGFILE, share_name,
1557                              path, comment, max_connections) == -1) {
1558                         return WERR_NOMEM;
1559                 }
1560
1561                 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command));
1562                                 
1563                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1564         
1565                 if ( is_disk_op )
1566                         become_root();
1567                         
1568                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1569                         /* Tell everyone we updated smb.conf. */
1570                         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED,
1571                                          NULL, 0, False, NULL);
1572                 }
1573                 
1574                 if ( is_disk_op )
1575                         unbecome_root();
1576                         
1577                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1578
1579                 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned "
1580                          "(%d)\n", command, ret ));
1581
1582                 SAFE_FREE(command);
1583
1584                 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1585         }
1586
1587         if (lp_registry_shares()) {
1588                 char *keyname;
1589                 struct registry_key *key;
1590                 WERROR err;
1591                 TALLOC_CTX *mem_ctx;
1592
1593                 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1594                                                 share_name))) {
1595                         return WERR_NOMEM;
1596                 }
1597
1598                 mem_ctx = (TALLOC_CTX *)keyname;
1599
1600                 err = reg_open_path(mem_ctx, keyname, REG_KEY_WRITE,
1601                                     is_disk_op ? get_root_nt_token():token,
1602                                     &key);
1603                 if (!W_ERROR_IS_OK(err)) {
1604                         TALLOC_FREE(mem_ctx);
1605                         return err;
1606                 }
1607
1608                 setval_helper(key, "path", path, &err);
1609
1610                 reg_deletevalue(key, "comment");
1611                 if ((comment != NULL) && (comment[0] != '\0')) {
1612                         setval_helper(key, "comment", comment, &err);
1613                 }
1614
1615                 reg_deletevalue(key, "max connections");
1616                 if (max_connections != 0) {
1617                         char tmp[16];
1618                         snprintf(tmp, sizeof(tmp), "%d", max_connections);
1619                         setval_helper(key, "max connections", tmp, &err);
1620                 }
1621
1622                 TALLOC_FREE(mem_ctx);
1623                 return err;
1624         }               
1625
1626         return WERR_ACCESS_DENIED;
1627 }
1628
1629 /*******************************************************************
1630  Net share set info. Modify share details.
1631 ********************************************************************/
1632
1633 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, const char *server_unc,
1634                                const char *share_name, uint32_t level,
1635                                union srvsvc_NetShareInfo info,
1636                                uint32_t *parm_error)
1637 {
1638         pstring comment;
1639         pstring pathname;
1640         int type;
1641         int snum;
1642         char *path;
1643         SEC_DESC *psd = NULL;
1644         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1645         BOOL is_disk_op = False;
1646         int max_connections = 0;
1647         fstring tmp_share_name;
1648
1649         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1650
1651         if (parm_error) {
1652                 *parm_error = 0;
1653         }
1654
1655         if ( strequal(share_name,"IPC$") 
1656                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1657                 || strequal(share_name,"global") )
1658         {
1659                 return WERR_ACCESS_DENIED;
1660         }
1661
1662         fstrcpy(tmp_share_name, share_name);
1663         snum = find_service(tmp_share_name);
1664
1665         /* Does this share exist ? */
1666         if (snum < 0)
1667                 return WERR_NET_NAME_NOT_FOUND;
1668
1669         /* No change to printer shares. */
1670         if (lp_print_ok(snum))
1671                 return WERR_ACCESS_DENIED;
1672
1673         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1674                                           &se_diskop );
1675         
1676         /* fail out now if you are not root and not a disk op */
1677         
1678         if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1679                 return WERR_ACCESS_DENIED;
1680
1681         switch (level) {
1682         case 1:
1683                 pstrcpy(pathname, lp_pathname(snum));
1684                 pstrcpy(comment, info.info1->comment);
1685                 type = info.info1->type;
1686                 psd = NULL;
1687                 break;
1688         case 2:
1689                 pstrcpy(comment, info.info2->comment);
1690                 pstrcpy(pathname, info.info2->path);
1691                 type = info.info2->type;
1692                 max_connections = (info.info2->max_users == 0xffffffff) ?
1693                         0 : info.info2->max_users;
1694                 psd = NULL;
1695                 break;
1696         case 502:
1697                 pstrcpy(comment, info.info502->comment);
1698                 pstrcpy(pathname, info.info502->path);
1699                 type = info.info502->type;
1700                 psd = info.info502->sd;
1701                 map_generic_share_sd_bits(psd);
1702                 break;
1703         case 1004:
1704                 pstrcpy(pathname, lp_pathname(snum));
1705                 pstrcpy(comment, info.info1004->comment);
1706                 type = STYPE_DISKTREE;
1707                 break;
1708         case 1005:
1709                 /* XP re-sets the csc policy even if it wasn't changed by the
1710                    user, so we must compare it to see if it's what is set in
1711                    smb.conf, so that we can contine other ops like setting
1712                    ACLs on a share */
1713                 if (((info.info1005->dfs_flags &
1714                       SHARE_1005_CSC_POLICY_MASK) >>
1715                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1716                         return WERR_OK;
1717                 else {
1718                         DEBUG(3, ("_srv_net_share_set_info: client is trying "
1719                                   "to change csc policy from the network; "
1720                                   "must be done with smb.conf\n"));
1721                         return WERR_ACCESS_DENIED;
1722                 }
1723         case 1006:
1724         case 1007:
1725                 return WERR_ACCESS_DENIED;
1726         case 1501:
1727                 pstrcpy(pathname, lp_pathname(snum));
1728                 pstrcpy(comment, lp_comment(snum));
1729                 psd = info.info1501->sd;
1730                 map_generic_share_sd_bits(psd);
1731                 type = STYPE_DISKTREE;
1732                 break;
1733         default:
1734                 DEBUG(5,("_srv_net_share_set_info: unsupported switch value "
1735                          "%d\n", level));
1736                 return WERR_UNKNOWN_LEVEL;
1737         }
1738
1739         /* We can only modify disk shares. */
1740         if (type != STYPE_DISKTREE)
1741                 return WERR_ACCESS_DENIED;
1742                 
1743         /* Check if the pathname is valid. */
1744         if (!(path = valid_share_pathname( pathname )))
1745                 return WERR_OBJECT_PATH_INVALID;
1746
1747         /* Ensure share name, pathname and comment don't contain '"'
1748          * characters. */
1749         string_replace(tmp_share_name, '"', ' ');
1750         string_replace(path, '"', ' ');
1751         string_replace(comment, '"', ' ');
1752
1753         DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1754                   lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1755
1756         /* Only call modify function if something changed. */
1757         
1758         if (strcmp(path, lp_pathname(snum))
1759             || strcmp(comment, lp_comment(snum)) 
1760             || (lp_max_connections(snum) != max_connections) ) {
1761                 WERROR err;
1762
1763                 err = change_share(tmp_share_name, path, comment,
1764                                    max_connections, p->pipe_user.nt_user_token,
1765                                    is_disk_op);
1766
1767                 if (!W_ERROR_IS_OK(err)) {
1768                         return err;
1769                 }
1770         }
1771
1772         /* Replace SD if changed. */
1773         if (psd) {
1774                 SEC_DESC *old_sd;
1775                 size_t sd_size;
1776
1777                 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1778                                             &sd_size);
1779
1780                 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1781                         if (!set_share_security(share_name, psd)) {
1782                                 DEBUG(0,("_srv_net_share_set_info: Failed to "
1783                                          "change security info in share %s.\n",
1784                                          share_name ));
1785                         }
1786                 }
1787         }
1788                         
1789         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1790
1791         return WERR_OK;
1792 }
1793
1794
1795 /*******************************************************************
1796  Net share add. Call 'add_share_command "sharename" "pathname" 
1797  "comment" "max connections = "
1798 ********************************************************************/
1799
1800 WERROR _srvsvc_NetShareAdd(pipes_struct *p, const char *server_unc,
1801                            uint32_t level, union srvsvc_NetShareInfo info,
1802                            uint32_t *parm_error)
1803 {
1804         pstring share_name;
1805         pstring comment;
1806         pstring pathname;
1807         char *path;
1808         int type;
1809         SEC_DESC *psd = NULL;
1810         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1811         BOOL is_disk_op;
1812         uint32 max_connections = 0;
1813         WERROR err;
1814
1815         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1816
1817         if (parm_error) {
1818                 *parm_error = 0;
1819         }
1820
1821         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1822                                           &se_diskop );
1823
1824         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1825                 return WERR_ACCESS_DENIED;
1826
1827         switch (level) {
1828         case 0:
1829                 /* No path. Not enough info in a level 0 to do anything. */
1830                 return WERR_ACCESS_DENIED;
1831         case 1:
1832                 /* Not enough info in a level 1 to do anything. */
1833                 return WERR_ACCESS_DENIED;
1834         case 2:
1835                 pstrcpy(share_name, info.info2->name);
1836                 pstrcpy(comment, info.info2->comment);
1837                 pstrcpy(pathname, info.info2->path);
1838                 max_connections = (info.info2->max_users == 0xffffffff) ?
1839                         0 : info.info2->max_users;
1840                 type = info.info2->type;
1841                 break;
1842         case 501:
1843                 /* No path. Not enough info in a level 501 to do anything. */
1844                 return WERR_ACCESS_DENIED;
1845         case 502:
1846                 pstrcpy(share_name, info.info502->name);
1847                 pstrcpy(comment, info.info502->comment);
1848                 pstrcpy(pathname, info.info502->path);
1849                 type = info.info502->type;
1850                 psd = info.info502->sd;
1851                 map_generic_share_sd_bits(psd);
1852                 break;
1853
1854                 /* none of the following contain share names.  NetShareAdd
1855                  * does not have a separate parameter for the share name */ 
1856
1857         case 1004:
1858         case 1005:
1859         case 1006:
1860         case 1007:
1861                 return WERR_ACCESS_DENIED;
1862         case 1501:
1863                 /* DFS only level. */
1864                 return WERR_ACCESS_DENIED;
1865         default:
1866                 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n",
1867                          level));
1868                 return WERR_UNKNOWN_LEVEL;
1869         }
1870
1871         /* check for invalid share names */
1872
1873         if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS,
1874                                  sizeof(share_name) ) ) {
1875                 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n",
1876                          share_name));
1877                 return WERR_INVALID_NAME;
1878         }
1879
1880         if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1881              || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1882         {
1883                 return WERR_ACCESS_DENIED;
1884         }
1885
1886         if (get_share_params(p->mem_ctx, share_name) != NULL) {
1887                 /* Share already exists. */
1888                 return WERR_ALREADY_EXISTS;
1889         }
1890
1891         /* We can only add disk shares. */
1892         if (type != STYPE_DISKTREE)
1893                 return WERR_ACCESS_DENIED;
1894                 
1895         /* Check if the pathname is valid. */
1896         if (!(path = valid_share_pathname( pathname )))
1897                 return WERR_OBJECT_PATH_INVALID;
1898
1899         /* Ensure share name, pathname and comment don't contain '"'
1900          * characters. */
1901
1902         string_replace(share_name, '"', ' ');
1903         string_replace(path, '"', ' ');
1904         string_replace(comment, '"', ' ');
1905
1906         err = add_share(share_name, path, comment, max_connections,
1907                         p->pipe_user.nt_user_token, is_disk_op);
1908
1909         if (!W_ERROR_IS_OK(err)) {
1910                 return err;
1911         }
1912
1913         if (psd) {
1914                 if (!set_share_security(share_name, psd)) {
1915                         DEBUG(0,("_srv_net_share_add: Failed to add security "
1916                                  "info to share %s.\n", share_name ));
1917                 }
1918         }
1919
1920         /*
1921          * We don't call reload_services() here, the message will
1922          * cause this to be done before the next packet is read
1923          * from the client. JRA.
1924          */
1925
1926         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1927
1928         return WERR_OK;
1929 }
1930
1931 /*******************************************************************
1932  Net share delete. Call "delete share command" with the share name as
1933  a parameter.
1934 ********************************************************************/
1935
1936 WERROR _srvsvc_NetShareDel(pipes_struct *p, const char *server_unc,
1937                            const char *share_name, uint32_t reserved)
1938 {
1939         struct share_params *params;
1940         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1941         BOOL is_disk_op;
1942         WERROR err;
1943
1944         DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1945
1946         if ( strequal(share_name,"IPC$") 
1947              || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1948              || strequal(share_name,"global") )
1949         {
1950                 return WERR_ACCESS_DENIED;
1951         }
1952
1953         if (!(params = get_share_params(p->mem_ctx, share_name))) {
1954                 return WERR_NO_SUCH_SHARE;
1955         }
1956
1957         /* No change to printer shares. */
1958         if (lp_print_ok(params->service))
1959                 return WERR_ACCESS_DENIED;
1960
1961         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1962                                           &se_diskop );
1963
1964         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1965                 return WERR_ACCESS_DENIED;
1966
1967         err = delete_share(lp_servicename(params->service),
1968                            p->pipe_user.nt_user_token, is_disk_op);
1969
1970         if (!W_ERROR_IS_OK(err)) {
1971                 return err;
1972         }
1973
1974         /* Delete the SD in the database. */
1975         delete_share_security(params);
1976
1977         lp_killservice(params->service);
1978
1979         return WERR_OK;
1980 }
1981
1982 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, const char *server_unc,
1983                                  const char *share_name, uint32_t reserved)
1984 {
1985         DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1986
1987         return _srvsvc_NetShareDel(p, server_unc, share_name, reserved);
1988 }
1989
1990 /*******************************************************************
1991 time of day
1992 ********************************************************************/
1993
1994 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, const char *server_unc, struct srvsvc_NetRemoteTODInfo *tod)
1995 {
1996         struct tm *t;
1997         time_t unixdate = time(NULL);
1998         WERROR status = WERR_OK;
1999
2000         /* We do this call first as if we do it *after* the gmtime call
2001            it overwrites the pointed-to values. JRA */
2002
2003         uint32 zone = get_time_zone(unixdate)/60;
2004
2005         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2006
2007         t = gmtime(&unixdate);
2008
2009         /* set up the */
2010         tod->elapsed = unixdate;
2011         tod->msecs = 0;
2012         tod->hours = t->tm_hour;
2013         tod->mins = t->tm_min;
2014         tod->secs = t->tm_sec;
2015         tod->hunds = 0;
2016         tod->timezone = zone;
2017         tod->tinterval = 10000;
2018         tod->day = t->tm_mday;
2019         tod->month = t->tm_mon + 1;
2020         tod->year = 1900+t->tm_year;
2021         tod->weekday = t->tm_wday;
2022         
2023         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2024
2025         return status;
2026 }
2027
2028 /***********************************************************************************
2029  Win9x NT tools get security descriptor.
2030 ***********************************************************************************/
2031
2032 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, const char *server_unc, const char *share, const char *file, uint32_t securityinformation, struct sec_desc_buf *sd_buf)
2033 {
2034         SEC_DESC *psd = NULL;
2035         size_t sd_size;
2036         DATA_BLOB null_pw;
2037         files_struct *fsp = NULL;
2038         SMB_STRUCT_STAT st;
2039         BOOL bad_path;
2040         NTSTATUS nt_status;
2041         connection_struct *conn = NULL;
2042         BOOL became_user = False; 
2043         WERROR status = WERR_OK;
2044         pstring tmp_file;
2045
2046         ZERO_STRUCT(st);
2047
2048
2049         /* Null password is ok - we are already an authenticated user... */
2050         null_pw = data_blob(NULL, 0);
2051
2052         become_root();
2053         conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2054         unbecome_root();
2055
2056         if (conn == NULL) {
2057                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", share));
2058                 status = ntstatus_to_werror(nt_status);
2059                 goto error_exit;
2060         }
2061
2062         if (!become_user(conn, conn->vuid)) {
2063                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2064                 status = WERR_ACCESS_DENIED;
2065                 goto error_exit;
2066         }
2067         became_user = True;
2068
2069         pstrcpy(tmp_file, file);
2070         unix_convert(tmp_file, conn, NULL, &bad_path, &st);
2071         if (bad_path) {
2072                 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", file));
2073                 status = WERR_ACCESS_DENIED;
2074                 goto error_exit;
2075         }
2076
2077         if (!check_name(file,conn)) {
2078                 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", file));
2079                 status = WERR_ACCESS_DENIED;
2080                 goto error_exit;
2081         }
2082
2083         nt_status = open_file_stat(conn, file, &st, &fsp);
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, file, &st,
2088                                         READ_CONTROL_ACCESS,
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_query_secdesc: Unable to open file %s\n", file));
2096                         status = WERR_ACCESS_DENIED;
2097                         goto error_exit;
2098                 }
2099         }
2100
2101         sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2102
2103         if (sd_size == 0) {
2104                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", file));
2105                 status = WERR_ACCESS_DENIED;
2106                 goto error_exit;
2107         }
2108
2109         sd_buf->sd_size= sd_size;
2110         sd_buf->sd = psd;
2111
2112         psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2113
2114         close_file(fsp, NORMAL_CLOSE);
2115         unbecome_user();
2116         close_cnum(conn, p->pipe_user.vuid);
2117         return status;
2118
2119 error_exit:
2120
2121         if(fsp) {
2122                 close_file(fsp, NORMAL_CLOSE);
2123         }
2124
2125         if (became_user)
2126                 unbecome_user();
2127
2128         if (conn) 
2129                 close_cnum(conn, p->pipe_user.vuid);
2130
2131         return status;
2132 }
2133
2134 /***********************************************************************************
2135  Win9x NT tools set security descriptor.
2136 ***********************************************************************************/
2137
2138 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, const char *server_unc, const char *share, const char *file, uint32_t securityinformation, struct sec_desc_buf sd_buf)
2139 {
2140         BOOL ret;
2141         DATA_BLOB null_pw;
2142         files_struct *fsp = NULL;
2143         SMB_STRUCT_STAT st;
2144         BOOL bad_path;
2145         NTSTATUS nt_status;
2146         connection_struct *conn = NULL;
2147         BOOL became_user = False;
2148         WERROR status = WERR_OK;
2149         pstring tmp_file;
2150
2151         ZERO_STRUCT(st);
2152
2153         /* Null password is ok - we are already an authenticated user... */
2154         null_pw = data_blob(NULL, 0);
2155
2156         become_root();
2157         conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2158         unbecome_root();
2159
2160         if (conn == NULL) {
2161                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", share));
2162                 status = ntstatus_to_werror(nt_status);
2163                 goto error_exit;
2164         }
2165
2166         if (!become_user(conn, conn->vuid)) {
2167                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2168                 status = WERR_ACCESS_DENIED;
2169                 goto error_exit;
2170         }
2171         became_user = True;
2172
2173         pstrcpy(tmp_file, file);
2174         unix_convert(tmp_file, conn, NULL, &bad_path, &st);
2175         if (bad_path) {
2176                 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", file));
2177                 status = WERR_ACCESS_DENIED;
2178                 goto error_exit;
2179         }
2180
2181         if (!check_name(file,conn)) {
2182                 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", file));
2183                 status = WERR_ACCESS_DENIED;
2184                 goto error_exit;
2185         }
2186
2187
2188         nt_status = open_file_stat(conn, file, &st, &fsp);
2189
2190         if (!NT_STATUS_IS_OK(nt_status)) {
2191                 /* Perhaps it is a directory */
2192                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2193                         nt_status = open_directory(conn, file, &st,
2194                                                 FILE_READ_ATTRIBUTES,
2195                                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
2196                                                 FILE_OPEN,
2197                                                 0,
2198                                                 NULL, &fsp);
2199
2200                 if (!NT_STATUS_IS_OK(nt_status)) {
2201                         DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", file));
2202                         status = WERR_ACCESS_DENIED;
2203                         goto error_exit;
2204                 }
2205         }
2206
2207         ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, securityinformation, sd_buf.sd);
2208
2209         if (ret == False) {
2210                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", file));
2211                 status = WERR_ACCESS_DENIED;
2212                 goto error_exit;
2213         }
2214
2215         close_file(fsp, NORMAL_CLOSE);
2216         unbecome_user();
2217         close_cnum(conn, p->pipe_user.vuid);
2218         return status;
2219
2220 error_exit:
2221
2222         if(fsp) {
2223                 close_file(fsp, NORMAL_CLOSE);
2224         }
2225
2226         if (became_user) {
2227                 unbecome_user();
2228         }
2229
2230         if (conn) {
2231                 close_cnum(conn, p->pipe_user.vuid);
2232         }
2233
2234         return status;
2235 }
2236
2237 /***********************************************************************************
2238  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2239  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2240  These disks would the disks listed by this function.
2241  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2242  "Nigel Williams" <nigel@veritas.com>.
2243 ***********************************************************************************/
2244
2245 static const char *server_disks[] = {"C:"};
2246
2247 static uint32 get_server_disk_count(void)
2248 {
2249         return sizeof(server_disks)/sizeof(server_disks[0]);
2250 }
2251
2252 static uint32 init_server_disk_enum(uint32 *resume)
2253 {
2254         uint32 server_disk_count = get_server_disk_count();
2255
2256         /*resume can be an offset into the list for now*/
2257
2258         if(*resume & 0x80000000)
2259                 *resume = 0;
2260
2261         if(*resume > server_disk_count)
2262                 *resume = server_disk_count;
2263
2264         return server_disk_count - *resume;
2265 }
2266
2267 static const char *next_server_disk_enum(uint32 *resume)
2268 {
2269         const char *disk;
2270
2271         if(init_server_disk_enum(resume) == 0)
2272                 return NULL;
2273
2274         disk = server_disks[*resume];
2275
2276         (*resume)++;
2277
2278         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2279
2280         return disk;
2281 }
2282
2283 WERROR _srvsvc_NetDiskEnum(pipes_struct *p, const char *server_unc, uint32_t level, struct srvsvc_NetDiskInfo *info, uint32_t maxlen, uint32_t *totalentries, uint32_t *resume_handle)
2284 {
2285         uint32 i;
2286         const char *disk_name;
2287
2288         WERROR status = WERR_OK;
2289
2290         *totalentries = init_server_disk_enum(resume_handle);
2291         info->count = 0;
2292
2293         if(!(info->disks =  TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2294                 return WERR_NOMEM;
2295         }
2296
2297         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2298
2299         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(resume_handle)); i++) {
2300
2301                 info->count++;
2302                 (*totalentries)++;
2303
2304                 /*copy disk name into a unicode string*/
2305
2306                 info->disks[i].disk = disk_name; 
2307         }
2308
2309         /* add a terminating null string.  Is this there if there is more data to come? */
2310
2311         info->count++;
2312         (*totalentries)++;
2313
2314         info->disks[i].disk = "";
2315
2316         return status;
2317 }
2318
2319 /********************************************************************
2320 ********************************************************************/
2321
2322 WERROR _srvsvc_NetNameValidate(pipes_struct *p, const char *server_unc, const char *name, uint32_t name_type, uint32_t flags)
2323 {
2324         int len;
2325
2326         if ((flags != 0x0) && (flags != 0x80000000)) {
2327                 return WERR_INVALID_PARAM;
2328         }
2329
2330         switch ( name_type ) {
2331         case 0x9:
2332                 len = strlen_m(name);
2333
2334                 if ((flags == 0x0) && (len > 81)) {
2335                         DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", name));
2336                         return WERR_INVALID_NAME;
2337                 }
2338                 if ((flags == 0x80000000) && (len > 13)) {
2339                         DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", name));
2340                         return WERR_INVALID_NAME;
2341                 }
2342
2343                 if ( ! validate_net_name( name, INVALID_SHARENAME_CHARS, sizeof(name) ) ) {
2344                         DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", name));
2345                         return WERR_INVALID_NAME;
2346                 }
2347                 break;
2348
2349         default:
2350                 return WERR_UNKNOWN_LEVEL;
2351         }
2352
2353         return WERR_OK;
2354 }
2355
2356
2357 /********************************************************************
2358 ********************************************************************/
2359
2360 WERROR _srvsvc_NetFileClose(pipes_struct *p, const char *server_unc, uint32_t fid)
2361 {
2362         return WERR_ACCESS_DENIED;
2363 }
2364
2365 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetCharDevCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
2366 {
2367         p->rng_fault_state = True;
2368         return WERR_NOT_SUPPORTED;
2369 }
2370
2371 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t level, union srvsvc_NetCharDevInfo *info)
2372 {
2373         p->rng_fault_state = True;
2374         return WERR_NOT_SUPPORTED;
2375 }
2376
2377 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t opcode)
2378 {
2379         p->rng_fault_state = True;
2380         return WERR_NOT_SUPPORTED;
2381 }
2382
2383 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, const char *server_unc, const char *user, uint32_t *level, union srvsvc_NetCharDevQCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
2384 {
2385         p->rng_fault_state = True;
2386         return WERR_NOT_SUPPORTED;
2387 }
2388
2389 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, const char *user, uint32_t level, union srvsvc_NetCharDevQInfo *info)
2390 {
2391         p->rng_fault_state = True;
2392         return WERR_NOT_SUPPORTED;
2393 }
2394
2395 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, uint32_t level, union srvsvc_NetCharDevQInfo info, uint32_t *parm_error)
2396 {
2397         p->rng_fault_state = True;
2398         return WERR_NOT_SUPPORTED;
2399 }
2400
2401 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, const char *server_unc, const char *queue_name)
2402 {
2403         p->rng_fault_state = True;
2404         return WERR_NOT_SUPPORTED;
2405 }
2406
2407 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, const char *server_unc, const char *queue_name, const char *computer_name)
2408 {
2409         p->rng_fault_state = True;
2410         return WERR_NOT_SUPPORTED;
2411 }
2412
2413 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, const char *server_unc, uint32_t fid, uint32_t level, union srvsvc_NetFileInfo *info)
2414 {
2415         p->rng_fault_state = True;
2416         return WERR_NOT_SUPPORTED;
2417 }
2418
2419 WERROR _srvsvc_NetShareCheck(pipes_struct *p, const char *server_unc, const char *device_name, enum srvsvc_ShareType *type)
2420 {
2421         p->rng_fault_state = True;
2422         return WERR_NOT_SUPPORTED;
2423 }
2424
2425 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, const char *server_unc, const char *service, uint32_t level, uint32_t options, struct srvsvc_Statistics *stats)
2426 {
2427         p->rng_fault_state = True;
2428         return WERR_NOT_SUPPORTED;
2429 }
2430
2431 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2432 {
2433         p->rng_fault_state = True;
2434         return WERR_NOT_SUPPORTED;
2435 }
2436
2437 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetTransportCtr *transports, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
2438 {
2439         p->rng_fault_state = True;
2440         return WERR_NOT_SUPPORTED;
2441 }
2442
2443 WERROR _srvsvc_NetTransportDel(pipes_struct *p, const char *server_unc, uint32_t unknown, struct srvsvc_NetTransportInfo0 transport)
2444 {
2445         p->rng_fault_state = True;
2446         return WERR_NOT_SUPPORTED;
2447 }
2448
2449 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, const char *server_unc, const char *transport, uint32_t servicebits, uint32_t updateimmediately)
2450 {
2451         p->rng_fault_state = True;
2452         return WERR_NOT_SUPPORTED;
2453 }
2454
2455 WERROR _srvsvc_NetPathType(pipes_struct *p, const char *server_unc, const char *path, uint32_t pathflags, uint32_t *pathtype)
2456 {
2457         p->rng_fault_state = True;
2458         return WERR_NOT_SUPPORTED;
2459 }
2460
2461 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, const char *server_unc, const char *path, uint8_t *can_path, uint32_t maxbuf, const char *prefix, uint32_t *pathtype, uint32_t pathflags)
2462 {
2463         p->rng_fault_state = True;
2464         return WERR_NOT_SUPPORTED;
2465 }
2466
2467 WERROR _srvsvc_NetPathCompare(pipes_struct *p, const char *server_unc, const char *path1, const char *path2, uint32_t pathtype, uint32_t pathflags)
2468 {
2469         p->rng_fault_state = True;
2470         return WERR_NOT_SUPPORTED;
2471 }
2472
2473 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p)
2474 {
2475         p->rng_fault_state = True;
2476         return WERR_NOT_SUPPORTED;
2477 }
2478
2479 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, const char *server_unc, const char *name1, const char *name2, uint32_t name_type, uint32_t flags)
2480 {
2481         p->rng_fault_state = True;
2482         return WERR_NOT_SUPPORTED;
2483 }
2484
2485 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, const char *server_unc, const char *share, uint32_t reserved, struct policy_handle *hnd)
2486 {
2487         p->rng_fault_state = True;
2488         return WERR_NOT_SUPPORTED;
2489 }
2490
2491 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct policy_handle *hnd)
2492 {
2493         p->rng_fault_state = True;
2494         return WERR_NOT_SUPPORTED;
2495 }
2496
2497 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2498 {
2499         p->rng_fault_state = True;
2500         return WERR_NOT_SUPPORTED;
2501 }
2502
2503 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, const char *server_unc, const char *emulated_server_unc, const char *transport, uint32_t servicebitsofinterest, uint32_t servicebits, uint32_t updateimmediately)
2504 {
2505         p->rng_fault_state = True;
2506         return WERR_NOT_SUPPORTED;
2507 }
2508
2509 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p)
2510 {
2511         p->rng_fault_state = True;
2512         return WERR_NOT_SUPPORTED;
2513 }
2514
2515 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p)
2516 {
2517         p->rng_fault_state = True;
2518         return WERR_NOT_SUPPORTED;
2519 }
2520
2521 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p)
2522 {
2523         p->rng_fault_state = True;
2524         return WERR_NOT_SUPPORTED;
2525 }
2526
2527 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p)
2528 {
2529         p->rng_fault_state = True;
2530         return WERR_NOT_SUPPORTED;
2531 }
2532
2533 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p)
2534 {
2535         p->rng_fault_state = True;
2536         return WERR_NOT_SUPPORTED;
2537 }
2538
2539 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p)
2540 {
2541         p->rng_fault_state = True;
2542         return WERR_NOT_SUPPORTED;
2543 }
2544
2545 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p)
2546 {
2547         p->rng_fault_state = True;
2548         return WERR_NOT_SUPPORTED;
2549 }
2550
2551 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p)
2552 {
2553         p->rng_fault_state = True;
2554         return WERR_NOT_SUPPORTED;
2555 }
2556
2557 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p)
2558 {
2559         p->rng_fault_state = True;
2560         return WERR_NOT_SUPPORTED;
2561 }
2562
2563 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p)
2564 {
2565         p->rng_fault_state = True;
2566         return WERR_NOT_SUPPORTED;
2567 }
2568
2569 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p)
2570 {
2571         p->rng_fault_state = True;
2572         return WERR_NOT_SUPPORTED;
2573 }