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