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