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