r20718: Sync up the filename path parsing changes from SAMBA_3_0_24.
[samba.git] / source / rpc_server / srv_srvsvc_nt.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Jeremy Allison               2001.
6  *  Copyright (C) Nigel Williams               2001.
7  *  Copyright (C) Gerald (Jerry) Carter        2006.
8  *  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         NTSTATUS nt_status;
2040         connection_struct *conn = NULL;
2041         BOOL became_user = False; 
2042         WERROR status = WERR_OK;
2043         pstring tmp_file;
2044
2045         ZERO_STRUCT(st);
2046
2047
2048         /* Null password is ok - we are already an authenticated user... */
2049         null_pw = data_blob(NULL, 0);
2050
2051         become_root();
2052         conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2053         unbecome_root();
2054
2055         if (conn == NULL) {
2056                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", share));
2057                 status = ntstatus_to_werror(nt_status);
2058                 goto error_exit;
2059         }
2060
2061         if (!become_user(conn, conn->vuid)) {
2062                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2063                 status = WERR_ACCESS_DENIED;
2064                 goto error_exit;
2065         }
2066         became_user = True;
2067
2068         pstrcpy(tmp_file, file);
2069         nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
2070         if (!NT_STATUS_IS_OK(nt_status)) {
2071                 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", file));
2072                 status = WERR_ACCESS_DENIED;
2073                 goto error_exit;
2074         }
2075
2076         if (!check_name(file,conn)) {
2077                 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", file));
2078                 status = WERR_ACCESS_DENIED;
2079                 goto error_exit;
2080         }
2081
2082         nt_status = open_file_stat(conn, file, &st, &fsp);
2083         if (!NT_STATUS_IS_OK(nt_status)) {
2084                 /* Perhaps it is a directory */
2085                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2086                         nt_status = open_directory(conn, file, &st,
2087                                         READ_CONTROL_ACCESS,
2088                                         FILE_SHARE_READ|FILE_SHARE_WRITE,
2089                                         FILE_OPEN,
2090                                         0,
2091                                         NULL, &fsp);
2092
2093                 if (!NT_STATUS_IS_OK(nt_status)) {
2094                         DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", file));
2095                         status = WERR_ACCESS_DENIED;
2096                         goto error_exit;
2097                 }
2098         }
2099
2100         sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2101
2102         if (sd_size == 0) {
2103                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", file));
2104                 status = WERR_ACCESS_DENIED;
2105                 goto error_exit;
2106         }
2107
2108         sd_buf->sd_size= sd_size;
2109         sd_buf->sd = psd;
2110
2111         psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2112
2113         close_file(fsp, NORMAL_CLOSE);
2114         unbecome_user();
2115         close_cnum(conn, p->pipe_user.vuid);
2116         return status;
2117
2118 error_exit:
2119
2120         if(fsp) {
2121                 close_file(fsp, NORMAL_CLOSE);
2122         }
2123
2124         if (became_user)
2125                 unbecome_user();
2126
2127         if (conn) 
2128                 close_cnum(conn, p->pipe_user.vuid);
2129
2130         return status;
2131 }
2132
2133 /***********************************************************************************
2134  Win9x NT tools set security descriptor.
2135 ***********************************************************************************/
2136
2137 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)
2138 {
2139         BOOL ret;
2140         DATA_BLOB null_pw;
2141         files_struct *fsp = NULL;
2142         SMB_STRUCT_STAT st;
2143         NTSTATUS nt_status;
2144         connection_struct *conn = NULL;
2145         BOOL became_user = False;
2146         WERROR status = WERR_OK;
2147         pstring tmp_file;
2148
2149         ZERO_STRUCT(st);
2150
2151         /* Null password is ok - we are already an authenticated user... */
2152         null_pw = data_blob(NULL, 0);
2153
2154         become_root();
2155         conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2156         unbecome_root();
2157
2158         if (conn == NULL) {
2159                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", share));
2160                 status = ntstatus_to_werror(nt_status);
2161                 goto error_exit;
2162         }
2163
2164         if (!become_user(conn, conn->vuid)) {
2165                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2166                 status = WERR_ACCESS_DENIED;
2167                 goto error_exit;
2168         }
2169         became_user = True;
2170
2171         pstrcpy(tmp_file, file);
2172         nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
2173         if (!NT_STATUS_IS_OK(nt_status)) {
2174                 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", file));
2175                 status = WERR_ACCESS_DENIED;
2176                 goto error_exit;
2177         }
2178
2179         if (!check_name(file,conn)) {
2180                 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", file));
2181                 status = WERR_ACCESS_DENIED;
2182                 goto error_exit;
2183         }
2184
2185
2186         nt_status = open_file_stat(conn, file, &st, &fsp);
2187
2188         if (!NT_STATUS_IS_OK(nt_status)) {
2189                 /* Perhaps it is a directory */
2190                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2191                         nt_status = open_directory(conn, file, &st,
2192                                                 FILE_READ_ATTRIBUTES,
2193                                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
2194                                                 FILE_OPEN,
2195                                                 0,
2196                                                 NULL, &fsp);
2197
2198                 if (!NT_STATUS_IS_OK(nt_status)) {
2199                         DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", file));
2200                         status = WERR_ACCESS_DENIED;
2201                         goto error_exit;
2202                 }
2203         }
2204
2205         ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, securityinformation, sd_buf.sd);
2206
2207         if (ret == False) {
2208                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", file));
2209                 status = WERR_ACCESS_DENIED;
2210                 goto error_exit;
2211         }
2212
2213         close_file(fsp, NORMAL_CLOSE);
2214         unbecome_user();
2215         close_cnum(conn, p->pipe_user.vuid);
2216         return status;
2217
2218 error_exit:
2219
2220         if(fsp) {
2221                 close_file(fsp, NORMAL_CLOSE);
2222         }
2223
2224         if (became_user) {
2225                 unbecome_user();
2226         }
2227
2228         if (conn) {
2229                 close_cnum(conn, p->pipe_user.vuid);
2230         }
2231
2232         return status;
2233 }
2234
2235 /***********************************************************************************
2236  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2237  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2238  These disks would the disks listed by this function.
2239  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2240  "Nigel Williams" <nigel@veritas.com>.
2241 ***********************************************************************************/
2242
2243 static const char *server_disks[] = {"C:"};
2244
2245 static uint32 get_server_disk_count(void)
2246 {
2247         return sizeof(server_disks)/sizeof(server_disks[0]);
2248 }
2249
2250 static uint32 init_server_disk_enum(uint32 *resume)
2251 {
2252         uint32 server_disk_count = get_server_disk_count();
2253
2254         /*resume can be an offset into the list for now*/
2255
2256         if(*resume & 0x80000000)
2257                 *resume = 0;
2258
2259         if(*resume > server_disk_count)
2260                 *resume = server_disk_count;
2261
2262         return server_disk_count - *resume;
2263 }
2264
2265 static const char *next_server_disk_enum(uint32 *resume)
2266 {
2267         const char *disk;
2268
2269         if(init_server_disk_enum(resume) == 0)
2270                 return NULL;
2271
2272         disk = server_disks[*resume];
2273
2274         (*resume)++;
2275
2276         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2277
2278         return disk;
2279 }
2280
2281 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)
2282 {
2283         uint32 i;
2284         const char *disk_name;
2285
2286         WERROR status = WERR_OK;
2287
2288         *totalentries = init_server_disk_enum(resume_handle);
2289         info->count = 0;
2290
2291         if(!(info->disks =  TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2292                 return WERR_NOMEM;
2293         }
2294
2295         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2296
2297         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(resume_handle)); i++) {
2298
2299                 info->count++;
2300                 (*totalentries)++;
2301
2302                 /*copy disk name into a unicode string*/
2303
2304                 info->disks[i].disk = disk_name; 
2305         }
2306
2307         /* add a terminating null string.  Is this there if there is more data to come? */
2308
2309         info->count++;
2310         (*totalentries)++;
2311
2312         info->disks[i].disk = "";
2313
2314         return status;
2315 }
2316
2317 /********************************************************************
2318 ********************************************************************/
2319
2320 WERROR _srvsvc_NetNameValidate(pipes_struct *p, const char *server_unc, const char *name, uint32_t name_type, uint32_t flags)
2321 {
2322         int len;
2323
2324         if ((flags != 0x0) && (flags != 0x80000000)) {
2325                 return WERR_INVALID_PARAM;
2326         }
2327
2328         switch ( name_type ) {
2329         case 0x9:
2330                 len = strlen_m(name);
2331
2332                 if ((flags == 0x0) && (len > 81)) {
2333                         DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", name));
2334                         return WERR_INVALID_NAME;
2335                 }
2336                 if ((flags == 0x80000000) && (len > 13)) {
2337                         DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", name));
2338                         return WERR_INVALID_NAME;
2339                 }
2340
2341                 if ( ! validate_net_name( name, INVALID_SHARENAME_CHARS, sizeof(name) ) ) {
2342                         DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", name));
2343                         return WERR_INVALID_NAME;
2344                 }
2345                 break;
2346
2347         default:
2348                 return WERR_UNKNOWN_LEVEL;
2349         }
2350
2351         return WERR_OK;
2352 }
2353
2354
2355 /********************************************************************
2356 ********************************************************************/
2357
2358 WERROR _srvsvc_NetFileClose(pipes_struct *p, const char *server_unc, uint32_t fid)
2359 {
2360         return WERR_ACCESS_DENIED;
2361 }
2362
2363 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)
2364 {
2365         p->rng_fault_state = True;
2366         return WERR_NOT_SUPPORTED;
2367 }
2368
2369 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t level, union srvsvc_NetCharDevInfo *info)
2370 {
2371         p->rng_fault_state = True;
2372         return WERR_NOT_SUPPORTED;
2373 }
2374
2375 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t opcode)
2376 {
2377         p->rng_fault_state = True;
2378         return WERR_NOT_SUPPORTED;
2379 }
2380
2381 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)
2382 {
2383         p->rng_fault_state = True;
2384         return WERR_NOT_SUPPORTED;
2385 }
2386
2387 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, const char *user, uint32_t level, union srvsvc_NetCharDevQInfo *info)
2388 {
2389         p->rng_fault_state = True;
2390         return WERR_NOT_SUPPORTED;
2391 }
2392
2393 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)
2394 {
2395         p->rng_fault_state = True;
2396         return WERR_NOT_SUPPORTED;
2397 }
2398
2399 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, const char *server_unc, const char *queue_name)
2400 {
2401         p->rng_fault_state = True;
2402         return WERR_NOT_SUPPORTED;
2403 }
2404
2405 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, const char *server_unc, const char *queue_name, const char *computer_name)
2406 {
2407         p->rng_fault_state = True;
2408         return WERR_NOT_SUPPORTED;
2409 }
2410
2411 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, const char *server_unc, uint32_t fid, uint32_t level, union srvsvc_NetFileInfo *info)
2412 {
2413         p->rng_fault_state = True;
2414         return WERR_NOT_SUPPORTED;
2415 }
2416
2417 WERROR _srvsvc_NetShareCheck(pipes_struct *p, const char *server_unc, const char *device_name, enum srvsvc_ShareType *type)
2418 {
2419         p->rng_fault_state = True;
2420         return WERR_NOT_SUPPORTED;
2421 }
2422
2423 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, const char *server_unc, const char *service, uint32_t level, uint32_t options, struct srvsvc_Statistics *stats)
2424 {
2425         p->rng_fault_state = True;
2426         return WERR_NOT_SUPPORTED;
2427 }
2428
2429 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2430 {
2431         p->rng_fault_state = True;
2432         return WERR_NOT_SUPPORTED;
2433 }
2434
2435 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)
2436 {
2437         p->rng_fault_state = True;
2438         return WERR_NOT_SUPPORTED;
2439 }
2440
2441 WERROR _srvsvc_NetTransportDel(pipes_struct *p, const char *server_unc, uint32_t unknown, struct srvsvc_NetTransportInfo0 transport)
2442 {
2443         p->rng_fault_state = True;
2444         return WERR_NOT_SUPPORTED;
2445 }
2446
2447 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, const char *server_unc, const char *transport, uint32_t servicebits, uint32_t updateimmediately)
2448 {
2449         p->rng_fault_state = True;
2450         return WERR_NOT_SUPPORTED;
2451 }
2452
2453 WERROR _srvsvc_NetPathType(pipes_struct *p, const char *server_unc, const char *path, uint32_t pathflags, uint32_t *pathtype)
2454 {
2455         p->rng_fault_state = True;
2456         return WERR_NOT_SUPPORTED;
2457 }
2458
2459 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)
2460 {
2461         p->rng_fault_state = True;
2462         return WERR_NOT_SUPPORTED;
2463 }
2464
2465 WERROR _srvsvc_NetPathCompare(pipes_struct *p, const char *server_unc, const char *path1, const char *path2, uint32_t pathtype, uint32_t pathflags)
2466 {
2467         p->rng_fault_state = True;
2468         return WERR_NOT_SUPPORTED;
2469 }
2470
2471 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p)
2472 {
2473         p->rng_fault_state = True;
2474         return WERR_NOT_SUPPORTED;
2475 }
2476
2477 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, const char *server_unc, const char *name1, const char *name2, uint32_t name_type, uint32_t flags)
2478 {
2479         p->rng_fault_state = True;
2480         return WERR_NOT_SUPPORTED;
2481 }
2482
2483 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, const char *server_unc, const char *share, uint32_t reserved, struct policy_handle *hnd)
2484 {
2485         p->rng_fault_state = True;
2486         return WERR_NOT_SUPPORTED;
2487 }
2488
2489 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct policy_handle *hnd)
2490 {
2491         p->rng_fault_state = True;
2492         return WERR_NOT_SUPPORTED;
2493 }
2494
2495 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2496 {
2497         p->rng_fault_state = True;
2498         return WERR_NOT_SUPPORTED;
2499 }
2500
2501 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)
2502 {
2503         p->rng_fault_state = True;
2504         return WERR_NOT_SUPPORTED;
2505 }
2506
2507 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p)
2508 {
2509         p->rng_fault_state = True;
2510         return WERR_NOT_SUPPORTED;
2511 }
2512
2513 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p)
2514 {
2515         p->rng_fault_state = True;
2516         return WERR_NOT_SUPPORTED;
2517 }
2518
2519 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p)
2520 {
2521         p->rng_fault_state = True;
2522         return WERR_NOT_SUPPORTED;
2523 }
2524
2525 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p)
2526 {
2527         p->rng_fault_state = True;
2528         return WERR_NOT_SUPPORTED;
2529 }
2530
2531 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p)
2532 {
2533         p->rng_fault_state = True;
2534         return WERR_NOT_SUPPORTED;
2535 }
2536
2537 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p)
2538 {
2539         p->rng_fault_state = True;
2540         return WERR_NOT_SUPPORTED;
2541 }
2542
2543 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p)
2544 {
2545         p->rng_fault_state = True;
2546         return WERR_NOT_SUPPORTED;
2547 }
2548
2549 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p)
2550 {
2551         p->rng_fault_state = True;
2552         return WERR_NOT_SUPPORTED;
2553 }
2554
2555 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p)
2556 {
2557         p->rng_fault_state = True;
2558         return WERR_NOT_SUPPORTED;
2559 }
2560
2561 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p)
2562 {
2563         p->rng_fault_state = True;
2564         return WERR_NOT_SUPPORTED;
2565 }
2566
2567 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p)
2568 {
2569         p->rng_fault_state = True;
2570         return WERR_NOT_SUPPORTED;
2571 }