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