r20875: Pass DCE/RPC server call arguments as a struct rather than as separate arguments.
[sfrench/samba-autobuild/.git] / source3 / rpc_server / srv_srvsvc_nt.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Jeremy Allison               2001.
6  *  Copyright (C) Nigel Williams               2001.
7  *  Copyright (C) Gerald (Jerry) Carter        2006.
8  *  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, struct srvsvc_NetFileEnum *r)
1067 {
1068         switch ( *r->in.level ) {
1069         case 3:
1070                 return net_file_enum_3(p, r->in.ctr, r->in.resume_handle, r->out.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, struct srvsvc_NetSrvGetInfo *r)
1083 {
1084         WERROR status = WERR_OK;
1085
1086         ZERO_STRUCTP(r->out.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 (r->in.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                 r->out.info->info102 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1103
1104                 r->out.info->info102->platform_id = 500;
1105                 r->out.info->info102->version_major = lp_major_announce_version();
1106                 r->out.info->info102->version_minor = lp_minor_announce_version();
1107                 r->out.info->info102->server_name = global_myname(); 
1108                 r->out.info->info102->server_type = lp_default_server_announce();
1109                 r->out.info->info102->userpath = "C:\\";
1110                 r->out.info->info102->licenses = 10000;
1111                 r->out.info->info102->anndelta = 3000;
1112                 r->out.info->info102->disc = 0xf;
1113                 r->out.info->info102->users = 0xffffffff;
1114                 r->out.info->info102->hidden = 0;
1115                 r->out.info->info102->announce = 240;
1116                 r->out.info->info102->comment = lp_serverstring();
1117                 break;
1118         case 101:
1119                 r->out.info->info101 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1120                         r->out.info->info101->platform_id = 500;
1121                         r->out.info->info101->server_name = global_myname();
1122                         r->out.info->info101->version_major = lp_major_announce_version();
1123                         r->out.info->info101->version_minor = lp_minor_announce_version();
1124                         r->out.info->info101->server_type = lp_default_server_announce();
1125                         r->out.info->info101->comment = lp_serverstring();
1126                 break;
1127         case 100:
1128                 r->out.info->info100 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1129                 r->out.info->info100->platform_id = 500;
1130                 r->out.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, struct srvsvc_NetSrvSetInfo *r)
1147 {
1148         /* Set up the net server set info structure. */
1149         if (r->out.parm_error) {
1150                 *r->out.parm_error = 0;
1151         }
1152         return WERR_OK;
1153 }
1154
1155 /*******************************************************************
1156 net conn enum
1157 ********************************************************************/
1158
1159 WERROR _srvsvc_NetConnEnum(pipes_struct *p, struct srvsvc_NetConnEnum *r)
1160 {
1161         DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1162
1163         ZERO_STRUCTP(r->out.ctr);
1164
1165         /* set up the */
1166         return init_srv_conn_info_ctr(p, r->out.ctr, *r->in.level, r->in.resume_handle, r->out.totalentries);
1167 }
1168
1169 /*******************************************************************
1170 net sess enum
1171 ********************************************************************/
1172
1173 WERROR _srvsvc_NetSessEnum(pipes_struct *p, struct srvsvc_NetSessEnum *r)
1174 {
1175         DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1176
1177         ZERO_STRUCTP(r->out.ctr);
1178
1179         /* set up the */
1180         return init_srv_sess_info_ctr(p, r->out.ctr,
1181                                 *r->in.level, 
1182                                 r->in.resume_handle,
1183                                 r->out.totalentries);
1184 }
1185
1186 /*******************************************************************
1187 net sess del
1188 ********************************************************************/
1189
1190 WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r)
1191 {
1192         struct sessionid *session_list;
1193         int num_sessions, snum;
1194         WERROR status;
1195
1196         char *machine = talloc_strdup(p->mem_ctx, r->in.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, r->in.user) || r->in.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, struct srvsvc_NetShareEnumAll *r)
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, r->out.ctr, *r->in.level,
1251                                               r->in.resume_handle, r->out.totalentries, True);
1252 }
1253
1254 /*******************************************************************
1255  Net share enum.
1256 ********************************************************************/
1257
1258 WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *r)
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, r->out.ctr, *r->in.level,
1269                                               r->in.resume_handle, r->out.totalentries, False);
1270 }
1271
1272 /*******************************************************************
1273  Net share get info.
1274 ********************************************************************/
1275
1276 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r)
1277 {
1278         const struct share_params *params;
1279
1280         params = get_share_params(p->mem_ctx, r->in.share_name);
1281
1282         if (params != NULL) {
1283                 switch (r->in.level) {
1284                 case 0:
1285                         r->out.info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1286                         init_srv_share_info_0(p, r->out.info->info0, params);
1287                         break;
1288                 case 1:
1289                         r->out.info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1290                         init_srv_share_info_1(p, r->out.info->info1, params);
1291                         break;
1292                 case 2:
1293                         r->out.info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1294                         init_srv_share_info_2(p, r->out.info->info2, params);
1295                         break;
1296                 case 501:
1297                         r->out.info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1298                         init_srv_share_info_501(p, r->out.info->info501, params);
1299                         break;
1300                 case 502:
1301                         r->out.info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1302                         init_srv_share_info_502(p, r->out.info->info502, params);
1303                         break;
1304
1305                         /* here for completeness */
1306                 case 1004:
1307                         r->out.info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1308                         init_srv_share_info_1004(p, r->out.info->info1004, params);
1309                         break;
1310                 case 1005:
1311                         r->out.info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1312                         init_srv_share_info_1005(p, r->out.info->info1005, params);
1313                         break;
1314
1315                         /* here for completeness 1006 - 1501 */
1316                 case 1006:
1317                         r->out.info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1318                         init_srv_share_info_1006(p, r->out.info->info1006,
1319                                                  params);
1320                         break;
1321                 case 1007:
1322                         r->out.info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1323                         init_srv_share_info_1007(p, r->out.info->info1007,
1324                                                  params);
1325                         break;
1326                 case 1501:
1327                         r->out.info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1328                         init_srv_share_info_1501(p, r->out.info->info1501,
1329                                                  params);
1330                         break;
1331                 default:
1332                         DEBUG(5,("init_srv_net_share_get_info: unsupported "
1333                                  "switch value %d\n", r->in.level));
1334                         return WERR_UNKNOWN_LEVEL;
1335                         break;
1336                 }
1337         } else {
1338                 return WERR_INVALID_NAME;
1339         }
1340
1341         return WERR_OK;
1342 }
1343
1344 /*******************************************************************
1345  Check a given DOS pathname is valid for a share.
1346 ********************************************************************/
1347
1348 char *valid_share_pathname(char *dos_pathname)
1349 {
1350         char *ptr;
1351
1352         /* Convert any '\' paths to '/' */
1353         unix_format(dos_pathname);
1354         unix_clean_name(dos_pathname);
1355
1356         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1357         ptr = dos_pathname;
1358         if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1359                 ptr += 2;
1360
1361         /* Only absolute paths allowed. */
1362         if (*ptr != '/')
1363                 return NULL;
1364
1365         return ptr;
1366 }
1367
1368 static void setval_helper(struct registry_key *key, const char *name,
1369                           const char *value, WERROR *err)
1370 {
1371         struct registry_value val;
1372
1373         if (!W_ERROR_IS_OK(*err)) {
1374                 return;
1375         }
1376
1377         ZERO_STRUCT(val);
1378         val.type = REG_SZ;
1379         val.v.sz.str = CONST_DISCARD(char *, value);
1380         val.v.sz.len = strlen(value)+1;
1381
1382         *err = reg_setvalue(key, name, &val);
1383 }
1384
1385 static WERROR add_share(const char *share_name, const char *path,
1386                         const char *comment, uint32 max_connections,
1387                         const struct nt_user_token *token,
1388                         BOOL is_disk_op)
1389 {
1390         if (lp_add_share_cmd() && *lp_add_share_cmd()) {
1391                 char *command;
1392                 int ret;
1393
1394                 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1395                              lp_add_share_cmd(), dyn_CONFIGFILE, share_name,
1396                              path, comment, max_connections) == -1) {
1397                         return WERR_NOMEM;
1398                 }
1399
1400                 DEBUG(10,("add_share: Running [%s]\n", command ));
1401
1402                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1403         
1404                 if ( is_disk_op )
1405                         become_root();
1406
1407                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1408                         /* Tell everyone we updated smb.conf. */
1409                         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED,
1410                                          NULL, 0, False, NULL);
1411                 }
1412
1413                 if ( is_disk_op )
1414                         unbecome_root();
1415                 
1416                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1417
1418                 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n",
1419                          command, ret ));
1420
1421                 /*
1422                  * No fallback to registry shares, the user did define a add
1423                  * share command, so fail here.
1424                  */
1425
1426                 SAFE_FREE(command);
1427                 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1428         }
1429
1430         if (lp_registry_shares()) {
1431                 char *keyname;
1432                 struct registry_key *key;
1433                 enum winreg_CreateAction action;
1434                 WERROR err;
1435                 TALLOC_CTX *mem_ctx;
1436
1437                 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1438                                                 share_name))) {
1439                         return WERR_NOMEM;
1440                 }
1441
1442                 mem_ctx = (TALLOC_CTX *)keyname;
1443
1444                 err = reg_create_path(mem_ctx, keyname, REG_KEY_WRITE,
1445                                       is_disk_op ? get_root_nt_token():token,
1446                                       &action, &key);
1447
1448                 if (action != REG_CREATED_NEW_KEY) {
1449                         err = WERR_ALREADY_EXISTS;
1450                 }
1451
1452                 if (!W_ERROR_IS_OK(err)) {
1453                         TALLOC_FREE(mem_ctx);
1454                         return err;
1455                 }
1456
1457                 setval_helper(key, "path", path, &err);
1458                 if ((comment != NULL) && (comment[0] != '\0')) {
1459                         setval_helper(key, "comment", comment, &err);
1460                 }
1461                 if (max_connections != 0) {
1462                         char tmp[16];
1463                         snprintf(tmp, sizeof(tmp), "%d", max_connections);
1464                         setval_helper(key, "max connections", tmp, &err);
1465                 }
1466
1467                 if (!W_ERROR_IS_OK(err)) {
1468                         /*
1469                          * Hmmmm. We'd need transactions on the registry to
1470                          * get this right....
1471                          */
1472                         reg_delete_path(is_disk_op ? get_root_nt_token():token,
1473                                         keyname);
1474                 }
1475                 TALLOC_FREE(mem_ctx);
1476                 return err;
1477         }
1478
1479         return WERR_ACCESS_DENIED;
1480 }
1481
1482 static WERROR delete_share(const char *sharename, 
1483                            const struct nt_user_token *token,
1484                            BOOL is_disk_op)
1485 {
1486         if (lp_delete_share_cmd() && *lp_delete_share_cmd()) {
1487                 char *command;
1488                 int ret;
1489
1490                 if (asprintf(&command, "%s \"%s\" \"%s\"",
1491                              lp_delete_share_cmd(), dyn_CONFIGFILE,
1492                              sharename)) {
1493                         return WERR_NOMEM;
1494                 }
1495
1496                 DEBUG(10,("delete_share: Running [%s]\n", command ));
1497
1498                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1499         
1500                 if ( is_disk_op )
1501                         become_root();
1502
1503                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1504                         /* Tell everyone we updated smb.conf. */
1505                         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED,
1506                                          NULL, 0, False, NULL);
1507                 }
1508
1509                 if ( is_disk_op )
1510                         unbecome_root();
1511
1512                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1513
1514                 SAFE_FREE(command);
1515
1516                 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n",
1517                          command, ret ));
1518                 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1519         }
1520
1521         if (lp_registry_shares()) {
1522                 char *keyname;
1523                 WERROR err;
1524
1525                 if (asprintf(&keyname, "%s\\%s", KEY_SMBCONF,
1526                              sharename) == -1) {
1527                         return WERR_NOMEM;
1528                 }
1529
1530                 err = reg_delete_path(is_disk_op ? get_root_nt_token():token,
1531                                       keyname);
1532                 SAFE_FREE(keyname);
1533                 return err;
1534         }
1535
1536         return WERR_ACCESS_DENIED;
1537 }
1538
1539 static WERROR change_share(const char *share_name, const char *path,
1540                            const char *comment, uint32 max_connections,
1541                            const struct nt_user_token *token,
1542                            BOOL is_disk_op)
1543 {
1544         if (lp_change_share_cmd() && *lp_change_share_cmd()) {
1545                 char *command;
1546                 int ret;
1547
1548                 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1549                              lp_change_share_cmd(), dyn_CONFIGFILE, share_name,
1550                              path, comment, max_connections) == -1) {
1551                         return WERR_NOMEM;
1552                 }
1553
1554                 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command));
1555                                 
1556                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1557         
1558                 if ( is_disk_op )
1559                         become_root();
1560                         
1561                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1562                         /* Tell everyone we updated smb.conf. */
1563                         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED,
1564                                          NULL, 0, False, NULL);
1565                 }
1566                 
1567                 if ( is_disk_op )
1568                         unbecome_root();
1569                         
1570                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1571
1572                 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned "
1573                          "(%d)\n", command, ret ));
1574
1575                 SAFE_FREE(command);
1576
1577                 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1578         }
1579
1580         if (lp_registry_shares()) {
1581                 char *keyname;
1582                 struct registry_key *key;
1583                 WERROR err;
1584                 TALLOC_CTX *mem_ctx;
1585
1586                 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1587                                                 share_name))) {
1588                         return WERR_NOMEM;
1589                 }
1590
1591                 mem_ctx = (TALLOC_CTX *)keyname;
1592
1593                 err = reg_open_path(mem_ctx, keyname, REG_KEY_WRITE,
1594                                     is_disk_op ? get_root_nt_token():token,
1595                                     &key);
1596                 if (!W_ERROR_IS_OK(err)) {
1597                         TALLOC_FREE(mem_ctx);
1598                         return err;
1599                 }
1600
1601                 setval_helper(key, "path", path, &err);
1602
1603                 reg_deletevalue(key, "comment");
1604                 if ((comment != NULL) && (comment[0] != '\0')) {
1605                         setval_helper(key, "comment", comment, &err);
1606                 }
1607
1608                 reg_deletevalue(key, "max connections");
1609                 if (max_connections != 0) {
1610                         char tmp[16];
1611                         snprintf(tmp, sizeof(tmp), "%d", max_connections);
1612                         setval_helper(key, "max connections", tmp, &err);
1613                 }
1614
1615                 TALLOC_FREE(mem_ctx);
1616                 return err;
1617         }               
1618
1619         return WERR_ACCESS_DENIED;
1620 }
1621
1622 /*******************************************************************
1623  Net share set info. Modify share details.
1624 ********************************************************************/
1625
1626 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r)
1627 {
1628         pstring comment;
1629         pstring pathname;
1630         int type;
1631         int snum;
1632         char *path;
1633         SEC_DESC *psd = NULL;
1634         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1635         BOOL is_disk_op = False;
1636         int max_connections = 0;
1637         fstring tmp_share_name;
1638
1639         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1640
1641         if (r->out.parm_error) {
1642                 *r->out.parm_error = 0;
1643         }
1644
1645         if ( strequal(r->in.share_name,"IPC$") 
1646                 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1647                 || strequal(r->in.share_name,"global") )
1648         {
1649                 return WERR_ACCESS_DENIED;
1650         }
1651
1652         fstrcpy(tmp_share_name, r->in.share_name);
1653         snum = find_service(tmp_share_name);
1654
1655         /* Does this share exist ? */
1656         if (snum < 0)
1657                 return WERR_NET_NAME_NOT_FOUND;
1658
1659         /* No change to printer shares. */
1660         if (lp_print_ok(snum))
1661                 return WERR_ACCESS_DENIED;
1662
1663         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1664                                           &se_diskop );
1665         
1666         /* fail out now if you are not root and not a disk op */
1667         
1668         if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1669                 return WERR_ACCESS_DENIED;
1670
1671         switch (r->in.level) {
1672         case 1:
1673                 pstrcpy(pathname, lp_pathname(snum));
1674                 pstrcpy(comment, r->in.info.info1->comment);
1675                 type = r->in.info.info1->type;
1676                 psd = NULL;
1677                 break;
1678         case 2:
1679                 pstrcpy(comment, r->in.info.info2->comment);
1680                 pstrcpy(pathname, r->in.info.info2->path);
1681                 type = r->in.info.info2->type;
1682                 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1683                         0 : r->in.info.info2->max_users;
1684                 psd = NULL;
1685                 break;
1686         case 502:
1687                 pstrcpy(comment, r->in.info.info502->comment);
1688                 pstrcpy(pathname, r->in.info.info502->path);
1689                 type = r->in.info.info502->type;
1690                 psd = r->in.info.info502->sd;
1691                 map_generic_share_sd_bits(psd);
1692                 break;
1693         case 1004:
1694                 pstrcpy(pathname, lp_pathname(snum));
1695                 pstrcpy(comment, r->in.info.info1004->comment);
1696                 type = STYPE_DISKTREE;
1697                 break;
1698         case 1005:
1699                 /* XP re-sets the csc policy even if it wasn't changed by the
1700                    user, so we must compare it to see if it's what is set in
1701                    smb.conf, so that we can contine other ops like setting
1702                    ACLs on a share */
1703                 if (((r->in.info.info1005->dfs_flags &
1704                       SHARE_1005_CSC_POLICY_MASK) >>
1705                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1706                         return WERR_OK;
1707                 else {
1708                         DEBUG(3, ("_srv_net_share_set_info: client is trying "
1709                                   "to change csc policy from the network; "
1710                                   "must be done with smb.conf\n"));
1711                         return WERR_ACCESS_DENIED;
1712                 }
1713         case 1006:
1714         case 1007:
1715                 return WERR_ACCESS_DENIED;
1716         case 1501:
1717                 pstrcpy(pathname, lp_pathname(snum));
1718                 pstrcpy(comment, lp_comment(snum));
1719                 psd = r->in.info.info1501->sd;
1720                 map_generic_share_sd_bits(psd);
1721                 type = STYPE_DISKTREE;
1722                 break;
1723         default:
1724                 DEBUG(5,("_srv_net_share_set_info: unsupported switch value "
1725                          "%d\n", r->in.level));
1726                 return WERR_UNKNOWN_LEVEL;
1727         }
1728
1729         /* We can only modify disk shares. */
1730         if (type != STYPE_DISKTREE)
1731                 return WERR_ACCESS_DENIED;
1732                 
1733         /* Check if the pathname is valid. */
1734         if (!(path = valid_share_pathname( pathname )))
1735                 return WERR_OBJECT_PATH_INVALID;
1736
1737         /* Ensure share name, pathname and comment don't contain '"'
1738          * characters. */
1739         string_replace(tmp_share_name, '"', ' ');
1740         string_replace(path, '"', ' ');
1741         string_replace(comment, '"', ' ');
1742
1743         DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1744                   lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1745
1746         /* Only call modify function if something changed. */
1747         
1748         if (strcmp(path, lp_pathname(snum))
1749             || strcmp(comment, lp_comment(snum)) 
1750             || (lp_max_connections(snum) != max_connections) ) {
1751                 WERROR err;
1752
1753                 err = change_share(tmp_share_name, path, comment,
1754                                    max_connections, p->pipe_user.nt_user_token,
1755                                    is_disk_op);
1756
1757                 if (!W_ERROR_IS_OK(err)) {
1758                         return err;
1759                 }
1760         }
1761
1762         /* Replace SD if changed. */
1763         if (psd) {
1764                 SEC_DESC *old_sd;
1765                 size_t sd_size;
1766
1767                 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1768                                             &sd_size);
1769
1770                 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1771                         if (!set_share_security(r->in.share_name, psd)) {
1772                                 DEBUG(0,("_srv_net_share_set_info: Failed to "
1773                                          "change security info in share %s.\n",
1774                                          r->in.share_name ));
1775                         }
1776                 }
1777         }
1778                         
1779         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1780
1781         return WERR_OK;
1782 }
1783
1784
1785 /*******************************************************************
1786  Net share add. Call 'add_share_command "sharename" "pathname" 
1787  "comment" "max connections = "
1788 ********************************************************************/
1789
1790 WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r)
1791 {
1792         pstring share_name;
1793         pstring comment;
1794         pstring pathname;
1795         char *path;
1796         int type;
1797         SEC_DESC *psd = NULL;
1798         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1799         BOOL is_disk_op;
1800         uint32 max_connections = 0;
1801         WERROR err;
1802
1803         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1804
1805         if (r->out.parm_error) {
1806                 *r->out.parm_error = 0;
1807         }
1808
1809         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1810                                           &se_diskop );
1811
1812         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1813                 return WERR_ACCESS_DENIED;
1814
1815         switch (r->in.level) {
1816         case 0:
1817                 /* No path. Not enough info in a level 0 to do anything. */
1818                 return WERR_ACCESS_DENIED;
1819         case 1:
1820                 /* Not enough info in a level 1 to do anything. */
1821                 return WERR_ACCESS_DENIED;
1822         case 2:
1823                 pstrcpy(share_name, r->in.info.info2->name);
1824                 pstrcpy(comment, r->in.info.info2->comment);
1825                 pstrcpy(pathname, r->in.info.info2->path);
1826                 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1827                         0 : r->in.info.info2->max_users;
1828                 type = r->in.info.info2->type;
1829                 break;
1830         case 501:
1831                 /* No path. Not enough info in a level 501 to do anything. */
1832                 return WERR_ACCESS_DENIED;
1833         case 502:
1834                 pstrcpy(share_name, r->in.info.info502->name);
1835                 pstrcpy(comment, r->in.info.info502->comment);
1836                 pstrcpy(pathname, r->in.info.info502->path);
1837                 type = r->in.info.info502->type;
1838                 psd = r->in.info.info502->sd;
1839                 map_generic_share_sd_bits(psd);
1840                 break;
1841
1842                 /* none of the following contain share names.  NetShareAdd
1843                  * does not have a separate parameter for the share name */ 
1844
1845         case 1004:
1846         case 1005:
1847         case 1006:
1848         case 1007:
1849                 return WERR_ACCESS_DENIED;
1850         case 1501:
1851                 /* DFS only level. */
1852                 return WERR_ACCESS_DENIED;
1853         default:
1854                 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n",
1855                          r->in.level));
1856                 return WERR_UNKNOWN_LEVEL;
1857         }
1858
1859         /* check for invalid share names */
1860
1861         if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS,
1862                                  sizeof(share_name) ) ) {
1863                 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n",
1864                          share_name));
1865                 return WERR_INVALID_NAME;
1866         }
1867
1868         if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1869              || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1870         {
1871                 return WERR_ACCESS_DENIED;
1872         }
1873
1874         if (get_share_params(p->mem_ctx, share_name) != NULL) {
1875                 /* Share already exists. */
1876                 return WERR_ALREADY_EXISTS;
1877         }
1878
1879         /* We can only add disk shares. */
1880         if (type != STYPE_DISKTREE)
1881                 return WERR_ACCESS_DENIED;
1882                 
1883         /* Check if the pathname is valid. */
1884         if (!(path = valid_share_pathname( pathname )))
1885                 return WERR_OBJECT_PATH_INVALID;
1886
1887         /* Ensure share name, pathname and comment don't contain '"'
1888          * characters. */
1889
1890         string_replace(share_name, '"', ' ');
1891         string_replace(path, '"', ' ');
1892         string_replace(comment, '"', ' ');
1893
1894         err = add_share(share_name, path, comment, max_connections,
1895                         p->pipe_user.nt_user_token, is_disk_op);
1896
1897         if (!W_ERROR_IS_OK(err)) {
1898                 return err;
1899         }
1900
1901         if (psd) {
1902                 if (!set_share_security(share_name, psd)) {
1903                         DEBUG(0,("_srv_net_share_add: Failed to add security "
1904                                  "info to share %s.\n", share_name ));
1905                 }
1906         }
1907
1908         /*
1909          * We don't call reload_services() here, the message will
1910          * cause this to be done before the next packet is read
1911          * from the client. JRA.
1912          */
1913
1914         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1915
1916         return WERR_OK;
1917 }
1918
1919 /*******************************************************************
1920  Net share delete. Call "delete share command" with the share name as
1921  a parameter.
1922 ********************************************************************/
1923
1924 WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r)
1925 {
1926         struct share_params *params;
1927         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1928         BOOL is_disk_op;
1929         WERROR err;
1930
1931         DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1932
1933         if ( strequal(r->in.share_name, "IPC$") 
1934              || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1935              || strequal(r->in.share_name, "global") )
1936         {
1937                 return WERR_ACCESS_DENIED;
1938         }
1939
1940         if (!(params = get_share_params(p->mem_ctx, r->in.share_name))) {
1941                 return WERR_NO_SUCH_SHARE;
1942         }
1943
1944         /* No change to printer shares. */
1945         if (lp_print_ok(params->service))
1946                 return WERR_ACCESS_DENIED;
1947
1948         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1949                                           &se_diskop );
1950
1951         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1952                 return WERR_ACCESS_DENIED;
1953
1954         err = delete_share(lp_servicename(params->service),
1955                            p->pipe_user.nt_user_token, is_disk_op);
1956
1957         if (!W_ERROR_IS_OK(err)) {
1958                 return err;
1959         }
1960
1961         /* Delete the SD in the database. */
1962         delete_share_security(params);
1963
1964         lp_killservice(params->service);
1965
1966         return WERR_OK;
1967 }
1968
1969 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, struct srvsvc_NetShareDelSticky *r)
1970 {
1971         struct srvsvc_NetShareDel s;
1972
1973         DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1974
1975         s.in.server_unc = r->in.server_unc;
1976         s.in.share_name = r->in.share_name;
1977         s.in.reserved = r->in.reserved;
1978
1979         return _srvsvc_NetShareDel(p, &s);
1980 }
1981
1982 /*******************************************************************
1983 time of day
1984 ********************************************************************/
1985
1986 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r)
1987 {
1988         struct tm *t;
1989         time_t unixdate = time(NULL);
1990         WERROR status = WERR_OK;
1991
1992         /* We do this call first as if we do it *after* the gmtime call
1993            it overwrites the pointed-to values. JRA */
1994
1995         uint32 zone = get_time_zone(unixdate)/60;
1996
1997         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1998
1999         t = gmtime(&unixdate);
2000
2001         /* set up the */
2002         r->out.info->elapsed = unixdate;
2003         r->out.info->msecs = 0;
2004         r->out.info->hours = t->tm_hour;
2005         r->out.info->mins = t->tm_min;
2006         r->out.info->secs = t->tm_sec;
2007         r->out.info->hunds = 0;
2008         r->out.info->timezone = zone;
2009         r->out.info->tinterval = 10000;
2010         r->out.info->day = t->tm_mday;
2011         r->out.info->month = t->tm_mon + 1;
2012         r->out.info->year = 1900+t->tm_year;
2013         r->out.info->weekday = t->tm_wday;
2014         
2015         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2016
2017         return status;
2018 }
2019
2020 /***********************************************************************************
2021  Win9x NT tools get security descriptor.
2022 ***********************************************************************************/
2023
2024 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecurity *r)
2025 {
2026         SEC_DESC *psd = NULL;
2027         size_t sd_size;
2028         DATA_BLOB null_pw;
2029         files_struct *fsp = NULL;
2030         SMB_STRUCT_STAT st;
2031         NTSTATUS nt_status;
2032         connection_struct *conn = NULL;
2033         BOOL became_user = False; 
2034         WERROR status = WERR_OK;
2035         pstring tmp_file;
2036
2037         ZERO_STRUCT(st);
2038
2039
2040         /* Null password is ok - we are already an authenticated user... */
2041         null_pw = data_blob(NULL, 0);
2042
2043         become_root();
2044         conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2045         unbecome_root();
2046
2047         if (conn == NULL) {
2048                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", r->in.share));
2049                 status = ntstatus_to_werror(nt_status);
2050                 goto error_exit;
2051         }
2052
2053         if (!become_user(conn, conn->vuid)) {
2054                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2055                 status = WERR_ACCESS_DENIED;
2056                 goto error_exit;
2057         }
2058         became_user = True;
2059
2060         pstrcpy(tmp_file, r->in.file);
2061         nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
2062         if (!NT_STATUS_IS_OK(nt_status)) {
2063                 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", r->in.file));
2064                 status = WERR_ACCESS_DENIED;
2065                 goto error_exit;
2066         }
2067
2068         nt_status = check_name(conn, r->in.file);
2069         if (!NT_STATUS_IS_OK(nt_status)) {
2070                 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", r->in.file));
2071                 status = WERR_ACCESS_DENIED;
2072                 goto error_exit;
2073         }
2074
2075         nt_status = open_file_stat(conn, r->in.file, &st, &fsp);
2076         if (!NT_STATUS_IS_OK(nt_status)) {
2077                 /* Perhaps it is a directory */
2078                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2079                         nt_status = open_directory(conn, r->in.file, &st,
2080                                         READ_CONTROL_ACCESS,
2081                                         FILE_SHARE_READ|FILE_SHARE_WRITE,
2082                                         FILE_OPEN,
2083                                         0,
2084                                         NULL, &fsp);
2085
2086                 if (!NT_STATUS_IS_OK(nt_status)) {
2087                         DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", r->in.file));
2088                         status = WERR_ACCESS_DENIED;
2089                         goto error_exit;
2090                 }
2091         }
2092
2093         sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2094
2095         if (sd_size == 0) {
2096                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", r->in.file));
2097                 status = WERR_ACCESS_DENIED;
2098                 goto error_exit;
2099         }
2100
2101         r->out.sd_buf->sd_size= sd_size;
2102         r->out.sd_buf->sd = psd;
2103
2104         psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2105
2106         close_file(fsp, NORMAL_CLOSE);
2107         unbecome_user();
2108         close_cnum(conn, p->pipe_user.vuid);
2109         return status;
2110
2111 error_exit:
2112
2113         if(fsp) {
2114                 close_file(fsp, NORMAL_CLOSE);
2115         }
2116
2117         if (became_user)
2118                 unbecome_user();
2119
2120         if (conn) 
2121                 close_cnum(conn, p->pipe_user.vuid);
2122
2123         return status;
2124 }
2125
2126 /***********************************************************************************
2127  Win9x NT tools set security descriptor.
2128 ***********************************************************************************/
2129
2130 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r)
2131 {
2132         BOOL ret;
2133         DATA_BLOB null_pw;
2134         files_struct *fsp = NULL;
2135         SMB_STRUCT_STAT st;
2136         NTSTATUS nt_status;
2137         connection_struct *conn = NULL;
2138         BOOL became_user = False;
2139         WERROR status = WERR_OK;
2140         pstring tmp_file;
2141
2142         ZERO_STRUCT(st);
2143
2144         /* Null password is ok - we are already an authenticated user... */
2145         null_pw = data_blob(NULL, 0);
2146
2147         become_root();
2148         conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2149         unbecome_root();
2150
2151         if (conn == NULL) {
2152                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", r->in.share));
2153                 status = ntstatus_to_werror(nt_status);
2154                 goto error_exit;
2155         }
2156
2157         if (!become_user(conn, conn->vuid)) {
2158                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2159                 status = WERR_ACCESS_DENIED;
2160                 goto error_exit;
2161         }
2162         became_user = True;
2163
2164         pstrcpy(tmp_file, r->in.file);
2165         nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
2166         if (!NT_STATUS_IS_OK(nt_status)) {
2167                 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", r->in.file));
2168                 status = WERR_ACCESS_DENIED;
2169                 goto error_exit;
2170         }
2171
2172         nt_status = check_name(conn, r->in.file);
2173         if (!NT_STATUS_IS_OK(nt_status)) {
2174                 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", r->in.file));
2175                 status = WERR_ACCESS_DENIED;
2176                 goto error_exit;
2177         }
2178
2179
2180         nt_status = open_file_stat(conn, r->in.file, &st, &fsp);
2181
2182         if (!NT_STATUS_IS_OK(nt_status)) {
2183                 /* Perhaps it is a directory */
2184                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2185                         nt_status = open_directory(conn, r->in.file, &st,
2186                                                 FILE_READ_ATTRIBUTES,
2187                                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
2188                                                 FILE_OPEN,
2189                                                 0,
2190                                                 NULL, &fsp);
2191
2192                 if (!NT_STATUS_IS_OK(nt_status)) {
2193                         DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", r->in.file));
2194                         status = WERR_ACCESS_DENIED;
2195                         goto error_exit;
2196                 }
2197         }
2198
2199         ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd);
2200
2201         if (ret == False) {
2202                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", r->in.file));
2203                 status = WERR_ACCESS_DENIED;
2204                 goto error_exit;
2205         }
2206
2207         close_file(fsp, NORMAL_CLOSE);
2208         unbecome_user();
2209         close_cnum(conn, p->pipe_user.vuid);
2210         return status;
2211
2212 error_exit:
2213
2214         if(fsp) {
2215                 close_file(fsp, NORMAL_CLOSE);
2216         }
2217
2218         if (became_user) {
2219                 unbecome_user();
2220         }
2221
2222         if (conn) {
2223                 close_cnum(conn, p->pipe_user.vuid);
2224         }
2225
2226         return status;
2227 }
2228
2229 /***********************************************************************************
2230  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2231  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2232  These disks would the disks listed by this function.
2233  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2234  "Nigel Williams" <nigel@veritas.com>.
2235 ***********************************************************************************/
2236
2237 static const char *server_disks[] = {"C:"};
2238
2239 static uint32 get_server_disk_count(void)
2240 {
2241         return sizeof(server_disks)/sizeof(server_disks[0]);
2242 }
2243
2244 static uint32 init_server_disk_enum(uint32 *resume)
2245 {
2246         uint32 server_disk_count = get_server_disk_count();
2247
2248         /*resume can be an offset into the list for now*/
2249
2250         if(*resume & 0x80000000)
2251                 *resume = 0;
2252
2253         if(*resume > server_disk_count)
2254                 *resume = server_disk_count;
2255
2256         return server_disk_count - *resume;
2257 }
2258
2259 static const char *next_server_disk_enum(uint32 *resume)
2260 {
2261         const char *disk;
2262
2263         if(init_server_disk_enum(resume) == 0)
2264                 return NULL;
2265
2266         disk = server_disks[*resume];
2267
2268         (*resume)++;
2269
2270         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2271
2272         return disk;
2273 }
2274
2275 WERROR _srvsvc_NetDiskEnum(pipes_struct *p, struct srvsvc_NetDiskEnum *r)
2276 {
2277         uint32 i;
2278         const char *disk_name;
2279
2280         WERROR status = WERR_OK;
2281
2282         *r->out.totalentries = init_server_disk_enum(r->in.resume_handle);
2283         r->out.info->count = 0;
2284
2285         if(!(r->out.info->disks =  TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2286                 return WERR_NOMEM;
2287         }
2288
2289         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2290
2291         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(r->in.resume_handle)); i++) {
2292
2293                 r->out.info->count++;
2294                 (*r->out.totalentries)++;
2295
2296                 /*copy disk name into a unicode string*/
2297
2298                 r->out.info->disks[i].disk = disk_name; 
2299         }
2300
2301         /* add a terminating null string.  Is this there if there is more data to come? */
2302
2303         r->out.info->count++;
2304         (*r->out.totalentries)++;
2305
2306         r->out.info->disks[i].disk = "";
2307
2308         return status;
2309 }
2310
2311 /********************************************************************
2312 ********************************************************************/
2313
2314 WERROR _srvsvc_NetNameValidate(pipes_struct *p, struct srvsvc_NetNameValidate *r)
2315 {
2316         int len;
2317
2318         if ((r->in.flags != 0x0) && (r->in.flags != 0x80000000)) {
2319                 return WERR_INVALID_PARAM;
2320         }
2321
2322         switch ( r->in.name_type ) {
2323         case 0x9:
2324                 len = strlen_m(r->in.name);
2325
2326                 if ((r->in.flags == 0x0) && (len > 81)) {
2327                         DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", r->in.name));
2328                         return WERR_INVALID_NAME;
2329                 }
2330                 if ((r->in.flags == 0x80000000) && (len > 13)) {
2331                         DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", r->in.name));
2332                         return WERR_INVALID_NAME;
2333                 }
2334
2335                 if ( ! validate_net_name( r->in.name, INVALID_SHARENAME_CHARS, sizeof(r->in.name) ) ) {
2336                         DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", r->in.name));
2337                         return WERR_INVALID_NAME;
2338                 }
2339                 break;
2340
2341         default:
2342                 return WERR_UNKNOWN_LEVEL;
2343         }
2344
2345         return WERR_OK;
2346 }
2347
2348
2349 /********************************************************************
2350 ********************************************************************/
2351
2352 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2353 {
2354         return WERR_ACCESS_DENIED;
2355 }
2356
2357 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2358 {
2359         p->rng_fault_state = True;
2360         return WERR_NOT_SUPPORTED;
2361 }
2362
2363 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2364 {
2365         p->rng_fault_state = True;
2366         return WERR_NOT_SUPPORTED;
2367 }
2368
2369 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2370 {
2371         p->rng_fault_state = True;
2372         return WERR_NOT_SUPPORTED;
2373 }
2374
2375 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2376 {
2377         p->rng_fault_state = True;
2378         return WERR_NOT_SUPPORTED;
2379 }
2380
2381 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2382 {
2383         p->rng_fault_state = True;
2384         return WERR_NOT_SUPPORTED;
2385 }
2386
2387 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2388 {
2389         p->rng_fault_state = True;
2390         return WERR_NOT_SUPPORTED;
2391 }
2392
2393 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2394 {
2395         p->rng_fault_state = True;
2396         return WERR_NOT_SUPPORTED;
2397 }
2398
2399 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2400 {
2401         p->rng_fault_state = True;
2402         return WERR_NOT_SUPPORTED;
2403 }
2404
2405 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2406 {
2407         p->rng_fault_state = True;
2408         return WERR_NOT_SUPPORTED;
2409 }
2410
2411 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2412 {
2413         p->rng_fault_state = True;
2414         return WERR_NOT_SUPPORTED;
2415 }
2416
2417 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2418 {
2419         p->rng_fault_state = True;
2420         return WERR_NOT_SUPPORTED;
2421 }
2422
2423 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2424 {
2425         p->rng_fault_state = True;
2426         return WERR_NOT_SUPPORTED;
2427 }
2428
2429 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2430 {
2431         p->rng_fault_state = True;
2432         return WERR_NOT_SUPPORTED;
2433 }
2434
2435 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2436 {
2437         p->rng_fault_state = True;
2438         return WERR_NOT_SUPPORTED;
2439 }
2440
2441 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2442 {
2443         p->rng_fault_state = True;
2444         return WERR_NOT_SUPPORTED;
2445 }
2446
2447 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2448 {
2449         p->rng_fault_state = True;
2450         return WERR_NOT_SUPPORTED;
2451 }
2452
2453 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2454 {
2455         p->rng_fault_state = True;
2456         return WERR_NOT_SUPPORTED;
2457 }
2458
2459 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2460 {
2461         p->rng_fault_state = True;
2462         return WERR_NOT_SUPPORTED;
2463 }
2464
2465 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2466 {
2467         p->rng_fault_state = True;
2468         return WERR_NOT_SUPPORTED;
2469 }
2470
2471 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2472 {
2473         p->rng_fault_state = True;
2474         return WERR_NOT_SUPPORTED;
2475 }
2476
2477 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2478 {
2479         p->rng_fault_state = True;
2480         return WERR_NOT_SUPPORTED;
2481 }
2482
2483 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2484 {
2485         p->rng_fault_state = True;
2486         return WERR_NOT_SUPPORTED;
2487 }
2488
2489 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2490 {
2491         p->rng_fault_state = True;
2492         return WERR_NOT_SUPPORTED;
2493 }
2494
2495 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2496 {
2497         p->rng_fault_state = True;
2498         return WERR_NOT_SUPPORTED;
2499 }
2500
2501 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2502 {
2503         p->rng_fault_state = True;
2504         return WERR_NOT_SUPPORTED;
2505 }
2506
2507 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2508 {
2509         p->rng_fault_state = True;
2510         return WERR_NOT_SUPPORTED;
2511 }
2512
2513 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2514 {
2515         p->rng_fault_state = True;
2516         return WERR_NOT_SUPPORTED;
2517 }
2518
2519 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *R)
2520 {
2521         p->rng_fault_state = True;
2522         return WERR_NOT_SUPPORTED;
2523 }
2524
2525 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2526 {
2527         p->rng_fault_state = True;
2528         return WERR_NOT_SUPPORTED;
2529 }
2530
2531 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2532 {
2533         p->rng_fault_state = True;
2534         return WERR_NOT_SUPPORTED;
2535 }
2536
2537 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2538 {
2539         p->rng_fault_state = True;
2540         return WERR_NOT_SUPPORTED;
2541 }
2542
2543 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2544 {
2545         p->rng_fault_state = True;
2546         return WERR_NOT_SUPPORTED;
2547 }
2548
2549 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2550 {
2551         p->rng_fault_state = True;
2552         return WERR_NOT_SUPPORTED;
2553 }
2554
2555 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2556 {
2557         p->rng_fault_state = True;
2558         return WERR_NOT_SUPPORTED;
2559 }
2560
2561 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2562 {
2563         p->rng_fault_state = True;
2564         return WERR_NOT_SUPPORTED;
2565 }