r19448: Convert delete_share_security to struct share_params plus some cleanups
[ira/wip.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
507         DEBUG(5,("init_srv_share_info_ctr\n"));
508
509         ZERO_STRUCTP(ctr);
510
511         if (resume_hnd) {
512                 *resume_hnd = 0;
513         }
514
515         /* Ensure all the usershares are loaded. */
516         become_root();
517         load_usershare_shares();
518         unbecome_root();
519
520         *total_entries = 0;
521
522         if (!(shares = share_list_all(ctx))) {
523                 DEBUG(5, ("Could not list shares\n"));
524                 return WERR_ACCESS_DENIED;
525         }
526
527         switch (info_level) {
528         case 0:
529                 ctr->ctr0 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr0);
530                 break;
531         case 1:
532                 ctr->ctr1 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1);
533                 break;
534         case 2:
535                 ctr->ctr2 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr2);
536                 break;
537         case 501:
538                 ctr->ctr501 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr501);
539                 break;
540         case 502:
541                 ctr->ctr502 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr502);
542                 break;
543         case 1004:
544                 ctr->ctr1004 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1004);
545                 break;
546         case 1005:
547                 ctr->ctr1005 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1005);
548                 break;
549         case 1006:
550                 ctr->ctr1006 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1006);
551                 break;
552         case 1007:
553                 ctr->ctr1007 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1007);
554                 break;
555         case 1501:
556                 ctr->ctr1501 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1501);
557                 break;
558         default:
559                         DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
560                                  "value %d\n", info_level));
561                         return WERR_UNKNOWN_LEVEL;
562         }
563
564         while ((share = next_share(shares)) != NULL) {
565                 if (!lp_browseable(share->service)) {
566                         continue;
567                 }
568                 if (!all_shares && is_hidden_share(share)) {
569                         continue;
570                 }
571
572                 switch (info_level) {
573                 case 0:
574                 {
575                         struct srvsvc_NetShareInfo0 i;
576                         init_srv_share_info_0(p, &i, share);
577                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
578                                      &ctr->ctr0->array, &ctr->ctr0->count);
579                         if (ctr->ctr0->array == NULL) {
580                                 return WERR_NOMEM;
581                         }
582                         *total_entries = ctr->ctr0->count;
583                         break;
584                 }
585
586                 case 1:
587                 {
588                         struct srvsvc_NetShareInfo1 i;
589                         init_srv_share_info_1(p, &i, share);
590                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
591                                      &ctr->ctr1->array, &ctr->ctr1->count);
592                         if (ctr->ctr1->array == NULL) {
593                                 return WERR_NOMEM;
594                         }
595                         *total_entries = ctr->ctr1->count;
596                         break;
597                 }
598
599                 case 2:
600                 {
601                         struct srvsvc_NetShareInfo2 i;
602                         init_srv_share_info_2(p, &i, share);
603                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
604                                      &ctr->ctr2->array, &ctr->ctr2->count);
605                         if (ctr->ctr2->array == NULL) {
606                                 return WERR_NOMEM;
607                         }
608                         *total_entries = ctr->ctr2->count;
609                         break;
610                 }
611
612                 case 501:
613                 {
614                         struct srvsvc_NetShareInfo501 i;
615                         init_srv_share_info_501(p, &i, share);
616                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
617                                      &ctr->ctr501->array, &ctr->ctr501->count);
618                         if (ctr->ctr501->array == NULL) {
619                                 return WERR_NOMEM;
620                         }
621                         *total_entries = ctr->ctr501->count;
622                         break;
623                 }
624
625                 case 502:
626                 {
627                         struct srvsvc_NetShareInfo502 i;
628                         init_srv_share_info_502(p, &i, share);
629                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
630                                      &ctr->ctr502->array, &ctr->ctr502->count);
631                         if (ctr->ctr502->array == NULL) {
632                                 return WERR_NOMEM;
633                         }
634                         *total_entries = ctr->ctr502->count;
635                         break;
636                 }
637
638                 /* here for completeness but not currently used with enum
639                  * (1004 - 1501)*/
640         
641                 case 1004:
642                 {
643                         struct srvsvc_NetShareInfo1004 i;
644                         init_srv_share_info_1004(p, &i, share);
645                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
646                                      &ctr->ctr1004->array, &ctr->ctr1004->count);
647                         if (ctr->ctr1004->array == NULL) {
648                                 return WERR_NOMEM;
649                         }
650                         *total_entries = ctr->ctr1004->count;
651                         break;
652                 }
653
654                 case 1005:
655                 {
656                         struct srvsvc_NetShareInfo1005 i;
657                         init_srv_share_info_1005(p, &i, share);
658                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
659                                      &ctr->ctr1005->array, &ctr->ctr1005->count);
660                         if (ctr->ctr1005->array == NULL) {
661                                 return WERR_NOMEM;
662                         }
663                         *total_entries = ctr->ctr1005->count;
664                         break;
665                 }
666
667                 case 1006:
668                 {
669                         struct srvsvc_NetShareInfo1006 i;
670                         init_srv_share_info_1006(p, &i, share);
671                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
672                                      &ctr->ctr1006->array, &ctr->ctr1006->count);
673                         if (ctr->ctr1006->array == NULL) {
674                                 return WERR_NOMEM;
675                         }
676                         *total_entries = ctr->ctr1006->count;
677                         break;
678                 }
679
680                 case 1007:
681                 {
682                         struct srvsvc_NetShareInfo1007 i;
683                         init_srv_share_info_1007(p, &i, share);
684                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
685                                      &ctr->ctr1007->array, &ctr->ctr1007->count);
686                         if (ctr->ctr1007->array == NULL) {
687                                 return WERR_NOMEM;
688                         }
689                         *total_entries = ctr->ctr1007->count;
690                         break;
691                 }
692
693                 case 1501:
694                 {
695                         struct sec_desc_buf i;
696                         init_srv_share_info_1501(p, &i, share);
697                         ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
698                                      &ctr->ctr1501->array, &ctr->ctr1501->count);
699                         if (ctr->ctr1501->array == NULL) {
700                                 return WERR_NOMEM;
701                         }
702                         *total_entries = ctr->ctr1501->count;
703                         break;
704                 }
705                 }
706
707                 TALLOC_FREE(share);
708         }
709
710         return WERR_OK;
711 }
712
713 /*******************************************************************
714  fill in a sess info level 0 structure.
715  ********************************************************************/
716
717 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
718 {
719         struct sessionid *session_list;
720         uint32 num_entries = 0;
721         (*stot) = list_sessions(&session_list);
722
723         if (ss0 == NULL) {
724                 if (snum) {
725                         (*snum) = 0;
726                 }
727                 SAFE_FREE(session_list);
728                 return;
729         }
730
731         DEBUG(5,("init_srv_sess_0_ss0\n"));
732
733         ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
734
735         if (snum) {
736                 for (; (*snum) < (*stot); (*snum)++) {
737                         ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
738                         num_entries++;
739                 }
740
741                 ss0->count = num_entries;
742                 
743                 if ((*snum) >= (*stot)) {
744                         (*snum) = 0;
745                 }
746
747         } else {
748                 ss0->array = NULL;
749                 ss0->count = 0;
750         }
751         SAFE_FREE(session_list);
752 }
753
754 /*******************************************************************
755 ********************************************************************/
756
757 static void sess_file_fn( const struct share_mode_entry *e, 
758                           const char *sharepath, const char *fname,
759                           void *private_data )
760 {
761         struct sess_file_count *sess = (struct sess_file_count *)private_data;
762  
763         if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
764                 sess->count++;
765         }
766         
767         return;
768 }
769
770 /*******************************************************************
771 ********************************************************************/
772
773 static int net_count_files( uid_t uid, pid_t pid )
774 {
775         struct sess_file_count s_file_cnt;
776
777         s_file_cnt.count = 0;
778         s_file_cnt.uid = uid;
779         s_file_cnt.pid = pid;
780         
781         share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
782         
783         return s_file_cnt.count;
784 }
785
786 /*******************************************************************
787  fill in a sess info level 1 structure.
788  ********************************************************************/
789
790 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
791 {
792         struct sessionid *session_list;
793         uint32 num_entries = 0;
794         time_t now = time(NULL);
795
796         if ( !snum ) {
797                 ss1->count = 0;
798                 ss1->array = NULL;
799                 
800                 (*stot) = 0;
801
802                 return;
803         }
804         
805         if (ss1 == NULL) {
806                 if (snum != NULL)
807                         (*snum) = 0;
808                 return;
809         }
810
811         (*stot) = list_sessions(&session_list);
812
813         ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
814         
815         for (; (*snum) < (*stot); (*snum)++) {
816                 uint32 num_files;
817                 uint32 connect_time;
818                 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
819                 BOOL guest;
820                         
821                 if ( !pw ) {
822                         DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
823                                 session_list[*snum].username));
824                         continue;
825                 }
826                                 
827                 connect_time = (uint32)(now - session_list[*snum].connect_start);
828                 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
829                 guest = strequal( session_list[*snum].username, lp_guestaccount() );
830                                         
831                 ss1->array[num_entries].client = session_list[*snum].remote_machine;
832                 ss1->array[num_entries].user = session_list[*snum].username; 
833                 ss1->array[num_entries].num_open = num_files;
834                 ss1->array[num_entries].time = connect_time;
835                 ss1->array[num_entries].idle_time = 0;
836                 ss1->array[num_entries].user_flags = guest;
837
838                 num_entries++;
839         }
840
841         ss1->count = num_entries;
842         
843         if ((*snum) >= (*stot)) {
844                 (*snum) = 0;
845         }
846
847         SAFE_FREE(session_list);
848 }
849
850 /*******************************************************************
851  makes a SRV_R_NET_SESS_ENUM structure.
852 ********************************************************************/
853
854 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
855                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
856 {
857         WERROR status = WERR_OK;
858         DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
859
860         switch (switch_value) {
861         case 0:
862                 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
863                 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
864                 break;
865         case 1:
866                 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
867                 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
868                 break;
869         default:
870                 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
871                 if (resume_hnd != NULL)
872                         (*resume_hnd) = 0;
873                 (*total_entries) = 0;
874                 ctr->ctr0 = NULL;
875                 status = WERR_UNKNOWN_LEVEL;
876                 break;
877         }
878
879         return status;
880 }
881
882 /*******************************************************************
883  fill in a conn info level 0 structure.
884  ********************************************************************/
885
886 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
887 {
888         uint32 num_entries = 0;
889         (*stot) = 1;
890
891         if (ss0 == NULL) {
892                 if (snum != NULL)
893                         (*snum) = 0;
894                 return;
895         }
896
897         DEBUG(5,("init_srv_conn_0_ss0\n"));
898
899         if (snum) {
900                 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
901                 for (; (*snum) < (*stot); (*snum)++) {
902
903                         ss0->array[num_entries].conn_id = (*stot);
904
905                         /* move on to creating next connection */
906                         /* move on to creating next conn */
907                         num_entries++;
908                 }
909
910                 ss0->count = num_entries;
911                 
912                 if ((*snum) >= (*stot)) {
913                         (*snum) = 0;
914                 }
915
916         } else {
917                 ss0->array = NULL;
918                 ss0->count = 0;
919
920                 (*stot) = 0;
921         }
922 }
923
924 /*******************************************************************
925  fill in a conn info level 1 structure.
926  ********************************************************************/
927
928 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
929 {
930         uint32 num_entries = 0;
931         (*stot) = 1;
932
933         if (ss1 == NULL) {
934                 if (snum != NULL)
935                         (*snum) = 0;
936                 return;
937         }
938
939         DEBUG(5,("init_srv_conn_1_ss1\n"));
940
941         if (snum) {
942                 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
943                 for (; (*snum) < (*stot); (*snum)++) {
944                         ss1->array[num_entries].conn_id = (*stot);
945                         ss1->array[num_entries].conn_type = 0x3;
946                         ss1->array[num_entries].num_open = 1;
947                         ss1->array[num_entries].num_users = 1;
948                         ss1->array[num_entries].conn_time = 3;
949                         ss1->array[num_entries].user = "dummy_user";
950                         ss1->array[num_entries].share = "IPC$";
951
952                         /* move on to creating next connection */
953                         /* move on to creating next conn */
954                         num_entries++;
955                 }
956
957                 ss1->count = num_entries;
958
959                 if ((*snum) >= (*stot)) {
960                         (*snum) = 0;
961                 }
962
963         } else {
964                 ss1->count = 0;
965                 ss1->array = NULL;
966                 
967                 (*stot) = 0;
968         }
969 }
970
971 /*******************************************************************
972  makes a SRV_R_NET_CONN_ENUM structure.
973 ********************************************************************/
974
975 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
976                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
977 {
978         WERROR status = WERR_OK;
979         DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
980
981         switch (switch_value) {
982         case 0:
983                 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
984                 break;
985         case 1:
986                 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
987                 break;
988         default:
989                 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
990                 ctr->ctr0 = NULL;
991                 (*resume_hnd) = 0;
992                 (*total_entries) = 0;
993                 status = WERR_UNKNOWN_LEVEL;
994                 break;
995         }
996
997         return status;
998 }
999
1000 /*******************************************************************
1001  makes a SRV_R_NET_FILE_ENUM structure.
1002 ********************************************************************/
1003
1004 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, uint32 *resume_hnd, uint32 *num_entries )
1005 {
1006         TALLOC_CTX *ctx = get_talloc_ctx();
1007         WERROR status;
1008
1009         /* TODO -- Windows enumerates 
1010            (b) active pipes
1011            (c) open directories and files */
1012
1013         ctr->ctr3 = talloc_zero(p->mem_ctx, struct srvsvc_NetFileCtr3);
1014         
1015         status = net_enum_files( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1016         if ( !W_ERROR_IS_OK(status))
1017                 return status;
1018                 
1019         status = net_enum_pipes( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1020         if ( !W_ERROR_IS_OK(status))
1021                 return status;
1022
1023         ctr->ctr3->count = *num_entries;
1024         
1025         return WERR_OK;
1026 }
1027
1028 /*******************************************************************
1029 *******************************************************************/
1030
1031 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)
1032 {
1033         switch ( *level ) {
1034         case 3:
1035                 return net_file_enum_3(p, ctr, resume_handle, totalentries );   
1036         default:
1037                 return WERR_UNKNOWN_LEVEL;
1038         }
1039         
1040         return WERR_OK;
1041 }
1042
1043 /*******************************************************************
1044 net server get info
1045 ********************************************************************/
1046
1047 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo *info)
1048 {
1049         WERROR status = WERR_OK;
1050
1051         ZERO_STRUCTP(info);
1052
1053         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1054
1055         if (!pipe_access_check(p)) {
1056                 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1057                 return WERR_ACCESS_DENIED;
1058         }
1059
1060         switch (level) {
1061
1062                 /* Technically level 102 should only be available to
1063                    Administrators but there isn't anything super-secret
1064                    here, as most of it is made up. */
1065
1066         case 102:
1067                 info->info102 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1068
1069                 info->info102->platform_id = 500;
1070                 info->info102->version_major = lp_major_announce_version();
1071                 info->info102->version_minor = lp_minor_announce_version();
1072                 info->info102->server_name = global_myname(); 
1073                 info->info102->server_type = lp_default_server_announce();
1074                 info->info102->userpath = "C:\\";
1075                 info->info102->licenses = 10000;
1076                 info->info102->anndelta = 3000;
1077                 info->info102->disc = 0xf;
1078                 info->info102->users = 0xffffffff;
1079                 info->info102->hidden = 0;
1080                 info->info102->announce = 240;
1081                 info->info102->comment = lp_serverstring();
1082                 break;
1083         case 101:
1084                 info->info101 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1085                         info->info101->platform_id = 500;
1086                         info->info101->server_name = global_myname();
1087                         info->info101->version_major = lp_major_announce_version();
1088                         info->info101->version_minor = lp_minor_announce_version();
1089                         info->info101->server_type = lp_default_server_announce();
1090                         info->info101->comment = lp_serverstring();
1091                 break;
1092         case 100:
1093                 info->info100 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1094                 info->info100->platform_id = 500;
1095                 info->info100->server_name = global_myname();
1096                 break;
1097         default:
1098                 return WERR_UNKNOWN_LEVEL;
1099                 break;
1100         }
1101
1102         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1103
1104         return status;
1105 }
1106
1107 /*******************************************************************
1108 net server set info
1109 ********************************************************************/
1110
1111 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo info, uint32_t *parm_error)
1112 {
1113         /* Set up the net server set info structure. */
1114         *parm_error = 0;
1115         return WERR_OK;
1116 }
1117
1118 /*******************************************************************
1119 net conn enum
1120 ********************************************************************/
1121
1122 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)
1123 {
1124         DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1125
1126         ZERO_STRUCTP(ctr);
1127
1128         /* set up the */
1129         return init_srv_conn_info_ctr(p, ctr, *level, resume_handle, totalentries);
1130 }
1131
1132 /*******************************************************************
1133 net sess enum
1134 ********************************************************************/
1135
1136 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)
1137 {
1138         DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1139
1140         ZERO_STRUCTP(ctr);
1141
1142         /* set up the */
1143         return init_srv_sess_info_ctr(p, ctr,
1144                                 *level, 
1145                                 resume_handle,
1146                                 totalentries);
1147 }
1148
1149 /*******************************************************************
1150 net sess del
1151 ********************************************************************/
1152
1153 WERROR _srvsvc_NetSessDel(pipes_struct *p, const char *server_unc, const char *client, const char *user)
1154 {
1155         struct sessionid *session_list;
1156         int num_sessions, snum;
1157         WERROR status;
1158
1159         char *machine = talloc_strdup(p->mem_ctx, server_unc);
1160
1161         /* strip leading backslashes if any */
1162         while (machine[0] == '\\') {
1163                 memmove(machine, &machine[1], strlen(machine));
1164         }
1165
1166         num_sessions = list_sessions(&session_list);
1167
1168         DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1169
1170         status = WERR_ACCESS_DENIED;
1171
1172         /* fail out now if you are not root or not a domain admin */
1173
1174         if ((p->pipe_user.ut.uid != sec_initial_uid()) && 
1175                 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1176
1177                 goto done;
1178         }
1179
1180         for (snum = 0; snum < num_sessions; snum++) {
1181
1182                 if ((strequal(session_list[snum].username, user) || user[0] == '\0' ) &&
1183                     strequal(session_list[snum].remote_machine, machine)) {
1184                 
1185                         if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))
1186                                 status = WERR_OK;
1187                 }
1188         }
1189
1190         DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1191
1192
1193 done:
1194         SAFE_FREE(session_list);
1195
1196         return status;
1197 }
1198
1199 /*******************************************************************
1200  Net share enum all.
1201 ********************************************************************/
1202
1203 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)
1204 {
1205         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1206
1207         if (!pipe_access_check(p)) {
1208                 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1209                 return WERR_ACCESS_DENIED;
1210         }
1211
1212         /* Create the list of shares for the response. */
1213         return init_srv_share_info_ctr(p, ctr, *level,
1214                                               resume_handle, totalentries, True);
1215 }
1216
1217 /*******************************************************************
1218  Net share enum.
1219 ********************************************************************/
1220
1221 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)
1222 {
1223         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1224
1225         if (!pipe_access_check(p)) {
1226                 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1227                 return WERR_ACCESS_DENIED;
1228         }
1229
1230         /* Create the list of shares for the response. */
1231         return init_srv_share_info_ctr(p, ctr, *level,
1232                                               resume_handle, totalentries, False);
1233 }
1234
1235 /*******************************************************************
1236  Net share get info.
1237 ********************************************************************/
1238
1239 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t level, union srvsvc_NetShareInfo *info)
1240 {
1241         const struct share_params *params;
1242
1243         params = get_share_params(p->mem_ctx, share_name);
1244
1245         if (params != NULL) {
1246                 switch (level) {
1247                 case 0:
1248                         info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1249                         init_srv_share_info_0(p, info->info0,
1250                                               params);
1251                         break;
1252                 case 1:
1253                         info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1254                         init_srv_share_info_1(p, info->info1,
1255                                               params);
1256                         break;
1257                 case 2:
1258                         info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1259                         init_srv_share_info_2(p, info->info2,
1260                                               params);
1261                         break;
1262                 case 501:
1263                         info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1264                         init_srv_share_info_501(p, info->info501,
1265                                                 params);
1266                         break;
1267                 case 502:
1268                         info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1269                         init_srv_share_info_502(p, info->info502,
1270                                                 params);
1271                         break;
1272
1273                         /* here for completeness */
1274                 case 1004:
1275                         info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1276                         init_srv_share_info_1004(p, info->info1004,
1277                                                  params);
1278                         break;
1279                 case 1005:
1280                         info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1281                         init_srv_share_info_1005(p, info->info1005,
1282                                                  params);
1283                         break;
1284
1285                         /* here for completeness 1006 - 1501 */
1286                 case 1006:
1287                         info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1288                         init_srv_share_info_1006(p, info->info1006,
1289                                                  params);
1290                         break;
1291                 case 1007:
1292                         info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1293                         init_srv_share_info_1007(p, info->info1007,
1294                                                  params);
1295                         break;
1296                 case 1501:
1297                         info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1298                         init_srv_share_info_1501(p, info->info1501,
1299                                                  params);
1300                         break;
1301                 default:
1302                         DEBUG(5,("init_srv_net_share_get_info: unsupported "
1303                                  "switch value %d\n", level));
1304                         return WERR_UNKNOWN_LEVEL;
1305                         break;
1306                 }
1307         } else {
1308                 return WERR_INVALID_NAME;
1309         }
1310
1311         return WERR_OK;
1312 }
1313
1314 /*******************************************************************
1315  Check a given DOS pathname is valid for a share.
1316 ********************************************************************/
1317
1318 char *valid_share_pathname(char *dos_pathname)
1319 {
1320         char *ptr;
1321
1322         /* Convert any '\' paths to '/' */
1323         unix_format(dos_pathname);
1324         unix_clean_name(dos_pathname);
1325
1326         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1327         ptr = dos_pathname;
1328         if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1329                 ptr += 2;
1330
1331         /* Only absolute paths allowed. */
1332         if (*ptr != '/')
1333                 return NULL;
1334
1335         return ptr;
1336 }
1337
1338 /*******************************************************************
1339  Net share set info. Modify share details.
1340 ********************************************************************/
1341
1342 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)
1343 {
1344         pstring command;
1345         pstring comment;
1346         pstring pathname;
1347         int type;
1348         int snum;
1349         int ret;
1350         char *path;
1351         SEC_DESC *psd = NULL;
1352         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1353         BOOL is_disk_op = False;
1354         int max_connections = 0;
1355         fstring tmp_share_name;
1356
1357         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1358
1359         *parm_error = 0;
1360
1361         if ( strequal(share_name,"IPC$") 
1362                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1363                 || strequal(share_name,"global") )
1364         {
1365                 return WERR_ACCESS_DENIED;
1366         }
1367
1368         fstrcpy(tmp_share_name, share_name);
1369         snum = find_service(tmp_share_name);
1370
1371         /* Does this share exist ? */
1372         if (snum < 0)
1373                 return WERR_NET_NAME_NOT_FOUND;
1374
1375         /* No change to printer shares. */
1376         if (lp_print_ok(snum))
1377                 return WERR_ACCESS_DENIED;
1378
1379         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1380         
1381         /* fail out now if you are not root and not a disk op */
1382         
1383         if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1384                 return WERR_ACCESS_DENIED;
1385
1386         switch (level) {
1387         case 1:
1388                 pstrcpy(pathname, lp_pathname(snum));
1389                 pstrcpy(comment, info.info1->comment);
1390                 type = info.info1->type;
1391                 psd = NULL;
1392                 break;
1393         case 2:
1394                 pstrcpy(comment, info.info2->comment);
1395                 pstrcpy(pathname, info.info2->path);
1396                 type = info.info2->type;
1397                 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1398                 psd = NULL;
1399                 break;
1400 #if 0
1401                 /* not supported on set but here for completeness */
1402         case 501:
1403                 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1404                 type = q_u->info.share.info501.info_501.type;
1405                 psd = NULL;
1406                 break;
1407 #endif
1408         case 502:
1409                 pstrcpy(comment, info.info502->comment);
1410                 pstrcpy(pathname, info.info502->path);
1411                 type = info.info502->type;
1412                 psd = info.info502->sd;
1413                 map_generic_share_sd_bits(psd);
1414                 break;
1415         case 1004:
1416                 pstrcpy(pathname, lp_pathname(snum));
1417                 pstrcpy(comment, info.info1004->comment);
1418                 type = STYPE_DISKTREE;
1419                 break;
1420         case 1005:
1421                 /* XP re-sets the csc policy even if it wasn't changed by the
1422                    user, so we must compare it to see if it's what is set in
1423                    smb.conf, so that we can contine other ops like setting
1424                    ACLs on a share */
1425                 if (((info.info1005->dfs_flags &
1426                       SHARE_1005_CSC_POLICY_MASK) >>
1427                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1428                         return WERR_OK;
1429                 else {
1430                         DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1431                         return WERR_ACCESS_DENIED;
1432                 }
1433         case 1006:
1434         case 1007:
1435                 return WERR_ACCESS_DENIED;
1436         case 1501:
1437                 pstrcpy(pathname, lp_pathname(snum));
1438                 pstrcpy(comment, lp_comment(snum));
1439                 psd = info.info1501->sd;
1440                 map_generic_share_sd_bits(psd);
1441                 type = STYPE_DISKTREE;
1442                 break;
1443         default:
1444                 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", level));
1445                 return WERR_UNKNOWN_LEVEL;
1446         }
1447
1448         /* We can only modify disk shares. */
1449         if (type != STYPE_DISKTREE)
1450                 return WERR_ACCESS_DENIED;
1451                 
1452         /* Check if the pathname is valid. */
1453         if (!(path = valid_share_pathname( pathname )))
1454                 return WERR_OBJECT_PATH_INVALID;
1455
1456         /* Ensure share name, pathname and comment don't contain '"' characters. */
1457         string_replace(tmp_share_name, '"', ' ');
1458         string_replace(path, '"', ' ');
1459         string_replace(comment, '"', ' ');
1460
1461         DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1462                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1463
1464         /* Only call modify function if something changed. */
1465         
1466         if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) 
1467                 || (lp_max_connections(snum) != max_connections) ) 
1468         {
1469                 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1470                         DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1471                         return WERR_ACCESS_DENIED;
1472                 }
1473
1474                 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1475                                 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections ); 
1476
1477                 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1478                                 
1479                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1480         
1481                 if ( is_disk_op )
1482                         become_root();
1483                         
1484                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1485                         /* Tell everyone we updated smb.conf. */
1486                         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1487                 }
1488                 
1489                 if ( is_disk_op )
1490                         unbecome_root();
1491                         
1492                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1493
1494                 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));              
1495         
1496                 if ( ret != 0 )
1497                         return WERR_ACCESS_DENIED;
1498         } else {
1499                 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1500         }
1501
1502         /* Replace SD if changed. */
1503         if (psd) {
1504                 SEC_DESC *old_sd;
1505                 size_t sd_size;
1506
1507                 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1508                                             &sd_size);
1509
1510                 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1511                         if (!set_share_security(p->mem_ctx, share_name, psd))
1512                                 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1513                                         share_name ));
1514                 }
1515         }
1516                         
1517         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1518
1519         return WERR_OK;
1520 }
1521
1522 /*******************************************************************
1523  Net share add. Call 'add_share_command "sharename" "pathname" 
1524  "comment" "max connections = "
1525 ********************************************************************/
1526
1527 WERROR _srvsvc_NetShareAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetShareInfo info, uint32_t *parm_error)
1528 {
1529         pstring command;
1530         pstring share_name;
1531         pstring comment;
1532         pstring pathname;
1533         char *path;
1534         int type;
1535         int snum;
1536         int ret;
1537         SEC_DESC *psd = NULL;
1538         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1539         BOOL is_disk_op;
1540         int max_connections = 0;
1541
1542         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1543
1544         *parm_error = 0;
1545
1546         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1547
1548         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1549                 return WERR_ACCESS_DENIED;
1550
1551         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1552                 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1553                 return WERR_ACCESS_DENIED;
1554         }
1555         
1556         switch (level) {
1557         case 0:
1558                 /* No path. Not enough info in a level 0 to do anything. */
1559                 return WERR_ACCESS_DENIED;
1560         case 1:
1561                 /* Not enough info in a level 1 to do anything. */
1562                 return WERR_ACCESS_DENIED;
1563         case 2:
1564                 pstrcpy(share_name, info.info2->name);
1565                 pstrcpy(comment, info.info2->comment);
1566                 pstrcpy(pathname, info.info2->path);
1567                 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1568                 type = info.info2->type;
1569                 break;
1570         case 501:
1571                 /* No path. Not enough info in a level 501 to do anything. */
1572                 return WERR_ACCESS_DENIED;
1573         case 502:
1574                 pstrcpy(share_name, info.info502->name);
1575                 pstrcpy(comment, info.info502->comment);
1576                 pstrcpy(pathname, info.info502->path);
1577                 type = info.info502->type;
1578                 psd = info.info502->sd;
1579                 map_generic_share_sd_bits(psd);
1580                 break;
1581
1582                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */ 
1583
1584         case 1004:
1585         case 1005:
1586         case 1006:
1587         case 1007:
1588                 return WERR_ACCESS_DENIED;
1589         case 1501:
1590                 /* DFS only level. */
1591                 return WERR_ACCESS_DENIED;
1592         default:
1593                 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", level));
1594                 return WERR_UNKNOWN_LEVEL;
1595         }
1596
1597         /* check for invalid share names */
1598
1599         if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1600                 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1601                 return WERR_INVALID_NAME;
1602         }
1603
1604         if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1605                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1606         {
1607                 return WERR_ACCESS_DENIED;
1608         }
1609
1610         snum = find_service(share_name);
1611
1612         /* Share already exists. */
1613         if (snum >= 0)
1614                 return WERR_ALREADY_EXISTS;
1615
1616         /* We can only add disk shares. */
1617         if (type != STYPE_DISKTREE)
1618                 return WERR_ACCESS_DENIED;
1619                 
1620         /* Check if the pathname is valid. */
1621         if (!(path = valid_share_pathname( pathname )))
1622                 return WERR_OBJECT_PATH_INVALID;
1623
1624         /* Ensure share name, pathname and comment don't contain '"' characters. */
1625         string_replace(share_name, '"', ' ');
1626         string_replace(path, '"', ' ');
1627         string_replace(comment, '"', ' ');
1628
1629         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1630                         lp_add_share_cmd(), 
1631                         dyn_CONFIGFILE, 
1632                         share_name, 
1633                         path, 
1634                         comment, 
1635                         max_connections);
1636                         
1637         DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1638         
1639         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1640         
1641         if ( is_disk_op )
1642                 become_root();
1643
1644         if ( (ret = smbrun(command, NULL)) == 0 ) {
1645                 /* Tell everyone we updated smb.conf. */
1646                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1647         }
1648
1649         if ( is_disk_op )
1650                 unbecome_root();
1651                 
1652         /********* END SeDiskOperatorPrivilege BLOCK *********/
1653
1654         DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1655
1656         if ( ret != 0 )
1657                 return WERR_ACCESS_DENIED;
1658
1659         if (psd) {
1660                 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1661                         DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1662                 }
1663         }
1664
1665         /*
1666          * We don't call reload_services() here, the message will
1667          * cause this to be done before the next packet is read
1668          * from the client. JRA.
1669          */
1670
1671         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1672
1673         return WERR_OK;
1674 }
1675
1676 /*******************************************************************
1677  Net share delete. Call "delete share command" with the share name as
1678  a parameter.
1679 ********************************************************************/
1680
1681 WERROR _srvsvc_NetShareDel(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1682 {
1683         char *command;
1684         int ret;
1685         struct share_params *params;
1686         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1687         BOOL is_disk_op;
1688
1689         DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1690
1691         if ( strequal(share_name,"IPC$") 
1692                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1693                 || strequal(share_name,"global") )
1694         {
1695                 return WERR_ACCESS_DENIED;
1696         }
1697
1698         if (!(params = get_share_params(p->mem_ctx, share_name))) {
1699                 return WERR_NO_SUCH_SHARE;
1700         }
1701
1702         /* No change to printer shares. */
1703         if (lp_print_ok(params->service))
1704                 return WERR_ACCESS_DENIED;
1705
1706         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1707
1708         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1709                 return WERR_ACCESS_DENIED;
1710
1711         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1712                 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1713                 return WERR_ACCESS_DENIED;
1714         }
1715
1716         if (asprintf(&command, "%s \"%s\" \"%s\"",
1717                      lp_delete_share_cmd(), dyn_CONFIGFILE,
1718                      lp_servicename(params->service)) == -1) {
1719                 return WERR_NOMEM;
1720         }
1721
1722         DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1723
1724         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1725         
1726         if ( is_disk_op )
1727                 become_root();
1728
1729         if ( (ret = smbrun(command, NULL)) == 0 ) {
1730                 /* Tell everyone we updated smb.conf. */
1731                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1732         }
1733
1734         if ( is_disk_op )
1735                 unbecome_root();
1736
1737         SAFE_FREE(command);
1738                 
1739         /********* END SeDiskOperatorPrivilege BLOCK *********/
1740
1741         DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1742
1743         if ( ret != 0 )
1744                 return WERR_ACCESS_DENIED;
1745
1746         /* Delete the SD in the database. */
1747         delete_share_security(params);
1748
1749         lp_killservice(params->service);
1750
1751         return WERR_OK;
1752 }
1753
1754 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1755 {
1756         DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1757
1758         return _srvsvc_NetShareDel(p, server_unc, share_name, reserved);
1759 }
1760
1761 /*******************************************************************
1762 time of day
1763 ********************************************************************/
1764
1765 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, const char *server_unc, struct srvsvc_NetRemoteTODInfo *tod)
1766 {
1767         struct tm *t;
1768         time_t unixdate = time(NULL);
1769         WERROR status = WERR_OK;
1770
1771         /* We do this call first as if we do it *after* the gmtime call
1772            it overwrites the pointed-to values. JRA */
1773
1774         uint32 zone = get_time_zone(unixdate)/60;
1775
1776         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1777
1778         t = gmtime(&unixdate);
1779
1780         /* set up the */
1781         tod->elapsed = unixdate;
1782         tod->msecs = 0;
1783         tod->hours = t->tm_hour;
1784         tod->mins = t->tm_min;
1785         tod->secs = t->tm_sec;
1786         tod->hunds = 0;
1787         tod->timezone = zone;
1788         tod->tinterval = 10000;
1789         tod->day = t->tm_mday;
1790         tod->month = t->tm_mon + 1;
1791         tod->year = 1900+t->tm_year;
1792         tod->weekday = t->tm_wday;
1793         
1794         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1795
1796         return status;
1797 }
1798
1799 /***********************************************************************************
1800  Win9x NT tools get security descriptor.
1801 ***********************************************************************************/
1802
1803 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)
1804 {
1805         SEC_DESC *psd = NULL;
1806         size_t sd_size;
1807         DATA_BLOB null_pw;
1808         files_struct *fsp = NULL;
1809         SMB_STRUCT_STAT st;
1810         BOOL bad_path;
1811         NTSTATUS nt_status;
1812         connection_struct *conn = NULL;
1813         BOOL became_user = False; 
1814         WERROR status = WERR_OK;
1815         pstring tmp_file;
1816
1817         ZERO_STRUCT(st);
1818
1819
1820         /* Null password is ok - we are already an authenticated user... */
1821         null_pw = data_blob(NULL, 0);
1822
1823         become_root();
1824         conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1825         unbecome_root();
1826
1827         if (conn == NULL) {
1828                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", share));
1829                 status = ntstatus_to_werror(nt_status);
1830                 goto error_exit;
1831         }
1832
1833         if (!become_user(conn, conn->vuid)) {
1834                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1835                 status = WERR_ACCESS_DENIED;
1836                 goto error_exit;
1837         }
1838         became_user = True;
1839
1840         pstrcpy(tmp_file, file);
1841         unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1842         if (bad_path) {
1843                 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", file));
1844                 status = WERR_ACCESS_DENIED;
1845                 goto error_exit;
1846         }
1847
1848         if (!check_name(file,conn)) {
1849                 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", file));
1850                 status = WERR_ACCESS_DENIED;
1851                 goto error_exit;
1852         }
1853
1854         nt_status = open_file_stat(conn, file, &st, &fsp);
1855         if (!NT_STATUS_IS_OK(nt_status)) {
1856                 /* Perhaps it is a directory */
1857                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1858                         nt_status = open_directory(conn, file, &st,
1859                                         READ_CONTROL_ACCESS,
1860                                         FILE_SHARE_READ|FILE_SHARE_WRITE,
1861                                         FILE_OPEN,
1862                                         0,
1863                                         NULL, &fsp);
1864
1865                 if (!NT_STATUS_IS_OK(nt_status)) {
1866                         DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", file));
1867                         status = WERR_ACCESS_DENIED;
1868                         goto error_exit;
1869                 }
1870         }
1871
1872         sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1873
1874         if (sd_size == 0) {
1875                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", file));
1876                 status = WERR_ACCESS_DENIED;
1877                 goto error_exit;
1878         }
1879
1880         sd_buf->sd_size= sd_size;
1881         sd_buf->sd = psd;
1882
1883         psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1884
1885         close_file(fsp, NORMAL_CLOSE);
1886         unbecome_user();
1887         close_cnum(conn, p->pipe_user.vuid);
1888         return status;
1889
1890 error_exit:
1891
1892         if(fsp) {
1893                 close_file(fsp, NORMAL_CLOSE);
1894         }
1895
1896         if (became_user)
1897                 unbecome_user();
1898
1899         if (conn) 
1900                 close_cnum(conn, p->pipe_user.vuid);
1901
1902         return status;
1903 }
1904
1905 /***********************************************************************************
1906  Win9x NT tools set security descriptor.
1907 ***********************************************************************************/
1908
1909 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)
1910 {
1911         BOOL ret;
1912         DATA_BLOB null_pw;
1913         files_struct *fsp = NULL;
1914         SMB_STRUCT_STAT st;
1915         BOOL bad_path;
1916         NTSTATUS nt_status;
1917         connection_struct *conn = NULL;
1918         BOOL became_user = False;
1919         WERROR status = WERR_OK;
1920         pstring tmp_file;
1921
1922         ZERO_STRUCT(st);
1923
1924         /* Null password is ok - we are already an authenticated user... */
1925         null_pw = data_blob(NULL, 0);
1926
1927         become_root();
1928         conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1929         unbecome_root();
1930
1931         if (conn == NULL) {
1932                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", share));
1933                 status = ntstatus_to_werror(nt_status);
1934                 goto error_exit;
1935         }
1936
1937         if (!become_user(conn, conn->vuid)) {
1938                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1939                 status = WERR_ACCESS_DENIED;
1940                 goto error_exit;
1941         }
1942         became_user = True;
1943
1944         pstrcpy(tmp_file, file);
1945         unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1946         if (bad_path) {
1947                 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", file));
1948                 status = WERR_ACCESS_DENIED;
1949                 goto error_exit;
1950         }
1951
1952         if (!check_name(file,conn)) {
1953                 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", file));
1954                 status = WERR_ACCESS_DENIED;
1955                 goto error_exit;
1956         }
1957
1958
1959         nt_status = open_file_stat(conn, file, &st, &fsp);
1960
1961         if (!NT_STATUS_IS_OK(nt_status)) {
1962                 /* Perhaps it is a directory */
1963                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1964                         nt_status = open_directory(conn, file, &st,
1965                                                 FILE_READ_ATTRIBUTES,
1966                                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
1967                                                 FILE_OPEN,
1968                                                 0,
1969                                                 NULL, &fsp);
1970
1971                 if (!NT_STATUS_IS_OK(nt_status)) {
1972                         DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", file));
1973                         status = WERR_ACCESS_DENIED;
1974                         goto error_exit;
1975                 }
1976         }
1977
1978         ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, securityinformation, sd_buf.sd);
1979
1980         if (ret == False) {
1981                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", file));
1982                 status = WERR_ACCESS_DENIED;
1983                 goto error_exit;
1984         }
1985
1986         close_file(fsp, NORMAL_CLOSE);
1987         unbecome_user();
1988         close_cnum(conn, p->pipe_user.vuid);
1989         return status;
1990
1991 error_exit:
1992
1993         if(fsp) {
1994                 close_file(fsp, NORMAL_CLOSE);
1995         }
1996
1997         if (became_user) {
1998                 unbecome_user();
1999         }
2000
2001         if (conn) {
2002                 close_cnum(conn, p->pipe_user.vuid);
2003         }
2004
2005         return status;
2006 }
2007
2008 /***********************************************************************************
2009  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2010  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2011  These disks would the disks listed by this function.
2012  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2013  "Nigel Williams" <nigel@veritas.com>.
2014 ***********************************************************************************/
2015
2016 static const char *server_disks[] = {"C:"};
2017
2018 static uint32 get_server_disk_count(void)
2019 {
2020         return sizeof(server_disks)/sizeof(server_disks[0]);
2021 }
2022
2023 static uint32 init_server_disk_enum(uint32 *resume)
2024 {
2025         uint32 server_disk_count = get_server_disk_count();
2026
2027         /*resume can be an offset into the list for now*/
2028
2029         if(*resume & 0x80000000)
2030                 *resume = 0;
2031
2032         if(*resume > server_disk_count)
2033                 *resume = server_disk_count;
2034
2035         return server_disk_count - *resume;
2036 }
2037
2038 static const char *next_server_disk_enum(uint32 *resume)
2039 {
2040         const char *disk;
2041
2042         if(init_server_disk_enum(resume) == 0)
2043                 return NULL;
2044
2045         disk = server_disks[*resume];
2046
2047         (*resume)++;
2048
2049         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2050
2051         return disk;
2052 }
2053
2054 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)
2055 {
2056         uint32 i;
2057         const char *disk_name;
2058
2059         WERROR status = WERR_OK;
2060
2061         *totalentries = init_server_disk_enum(resume_handle);
2062         info->count = 0;
2063
2064         if(!(info->disks =  TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2065                 return WERR_NOMEM;
2066         }
2067
2068         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2069
2070         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(resume_handle)); i++) {
2071
2072                 info->count++;
2073                 (*totalentries)++;
2074
2075                 /*copy disk name into a unicode string*/
2076
2077                 info->disks[i].disk = disk_name; 
2078         }
2079
2080         /* add a terminating null string.  Is this there if there is more data to come? */
2081
2082         info->count++;
2083         (*totalentries)++;
2084
2085         info->disks[i].disk = "";
2086
2087         return status;
2088 }
2089
2090 /********************************************************************
2091 ********************************************************************/
2092
2093 WERROR _srvsvc_NetNameValidate(pipes_struct *p, const char *server_unc, const char *name, uint32_t name_type, uint32_t flags)
2094 {
2095         int len;
2096
2097         if ((flags != 0x0) && (flags != 0x80000000)) {
2098                 return WERR_INVALID_PARAM;
2099         }
2100
2101         switch ( name_type ) {
2102         case 0x9:
2103                 len = strlen_m(name);
2104
2105                 if ((flags == 0x0) && (len > 81)) {
2106                         DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", name));
2107                         return WERR_INVALID_NAME;
2108                 }
2109                 if ((flags == 0x80000000) && (len > 13)) {
2110                         DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", name));
2111                         return WERR_INVALID_NAME;
2112                 }
2113
2114                 if ( ! validate_net_name( name, INVALID_SHARENAME_CHARS, sizeof(name) ) ) {
2115                         DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", name));
2116                         return WERR_INVALID_NAME;
2117                 }
2118                 break;
2119
2120         default:
2121                 return WERR_UNKNOWN_LEVEL;
2122         }
2123
2124         return WERR_OK;
2125 }
2126
2127
2128 /********************************************************************
2129 ********************************************************************/
2130
2131 WERROR _srvsvc_NetFileClose(pipes_struct *p, const char *server_unc, uint32_t fid)
2132 {
2133         return WERR_ACCESS_DENIED;
2134 }
2135
2136 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)
2137 {
2138         p->rng_fault_state = True;
2139         return WERR_NOT_SUPPORTED;
2140 }
2141
2142 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t level, union srvsvc_NetCharDevInfo *info)
2143 {
2144         p->rng_fault_state = True;
2145         return WERR_NOT_SUPPORTED;
2146 }
2147
2148 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t opcode)
2149 {
2150         p->rng_fault_state = True;
2151         return WERR_NOT_SUPPORTED;
2152 }
2153
2154 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)
2155 {
2156         p->rng_fault_state = True;
2157         return WERR_NOT_SUPPORTED;
2158 }
2159
2160 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, const char *user, uint32_t level, union srvsvc_NetCharDevQInfo *info)
2161 {
2162         p->rng_fault_state = True;
2163         return WERR_NOT_SUPPORTED;
2164 }
2165
2166 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)
2167 {
2168         p->rng_fault_state = True;
2169         return WERR_NOT_SUPPORTED;
2170 }
2171
2172 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, const char *server_unc, const char *queue_name)
2173 {
2174         p->rng_fault_state = True;
2175         return WERR_NOT_SUPPORTED;
2176 }
2177
2178 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, const char *server_unc, const char *queue_name, const char *computer_name)
2179 {
2180         p->rng_fault_state = True;
2181         return WERR_NOT_SUPPORTED;
2182 }
2183
2184 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, const char *server_unc, uint32_t fid, uint32_t level, union srvsvc_NetFileInfo *info)
2185 {
2186         p->rng_fault_state = True;
2187         return WERR_NOT_SUPPORTED;
2188 }
2189
2190 WERROR _srvsvc_NetShareCheck(pipes_struct *p, const char *server_unc, const char *device_name, enum srvsvc_ShareType *type)
2191 {
2192         p->rng_fault_state = True;
2193         return WERR_NOT_SUPPORTED;
2194 }
2195
2196 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, const char *server_unc, const char *service, uint32_t level, uint32_t options, struct srvsvc_Statistics *stats)
2197 {
2198         p->rng_fault_state = True;
2199         return WERR_NOT_SUPPORTED;
2200 }
2201
2202 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2203 {
2204         p->rng_fault_state = True;
2205         return WERR_NOT_SUPPORTED;
2206 }
2207
2208 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)
2209 {
2210         p->rng_fault_state = True;
2211         return WERR_NOT_SUPPORTED;
2212 }
2213
2214 WERROR _srvsvc_NetTransportDel(pipes_struct *p, const char *server_unc, uint32_t unknown, struct srvsvc_NetTransportInfo0 transport)
2215 {
2216         p->rng_fault_state = True;
2217         return WERR_NOT_SUPPORTED;
2218 }
2219
2220 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, const char *server_unc, const char *transport, uint32_t servicebits, uint32_t updateimmediately)
2221 {
2222         p->rng_fault_state = True;
2223         return WERR_NOT_SUPPORTED;
2224 }
2225
2226 WERROR _srvsvc_NetPathType(pipes_struct *p, const char *server_unc, const char *path, uint32_t pathflags, uint32_t *pathtype)
2227 {
2228         p->rng_fault_state = True;
2229         return WERR_NOT_SUPPORTED;
2230 }
2231
2232 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)
2233 {
2234         p->rng_fault_state = True;
2235         return WERR_NOT_SUPPORTED;
2236 }
2237
2238 WERROR _srvsvc_NetPathCompare(pipes_struct *p, const char *server_unc, const char *path1, const char *path2, uint32_t pathtype, uint32_t pathflags)
2239 {
2240         p->rng_fault_state = True;
2241         return WERR_NOT_SUPPORTED;
2242 }
2243
2244 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p)
2245 {
2246         p->rng_fault_state = True;
2247         return WERR_NOT_SUPPORTED;
2248 }
2249
2250 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, const char *server_unc, const char *name1, const char *name2, uint32_t name_type, uint32_t flags)
2251 {
2252         p->rng_fault_state = True;
2253         return WERR_NOT_SUPPORTED;
2254 }
2255
2256 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, const char *server_unc, const char *share, uint32_t reserved, struct policy_handle *hnd)
2257 {
2258         p->rng_fault_state = True;
2259         return WERR_NOT_SUPPORTED;
2260 }
2261
2262 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct policy_handle *hnd)
2263 {
2264         p->rng_fault_state = True;
2265         return WERR_NOT_SUPPORTED;
2266 }
2267
2268 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2269 {
2270         p->rng_fault_state = True;
2271         return WERR_NOT_SUPPORTED;
2272 }
2273
2274 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)
2275 {
2276         p->rng_fault_state = True;
2277         return WERR_NOT_SUPPORTED;
2278 }
2279
2280 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p)
2281 {
2282         p->rng_fault_state = True;
2283         return WERR_NOT_SUPPORTED;
2284 }
2285
2286 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p)
2287 {
2288         p->rng_fault_state = True;
2289         return WERR_NOT_SUPPORTED;
2290 }
2291
2292 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p)
2293 {
2294         p->rng_fault_state = True;
2295         return WERR_NOT_SUPPORTED;
2296 }
2297
2298 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p)
2299 {
2300         p->rng_fault_state = True;
2301         return WERR_NOT_SUPPORTED;
2302 }
2303
2304 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p)
2305 {
2306         p->rng_fault_state = True;
2307         return WERR_NOT_SUPPORTED;
2308 }
2309
2310 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p)
2311 {
2312         p->rng_fault_state = True;
2313         return WERR_NOT_SUPPORTED;
2314 }
2315
2316 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p)
2317 {
2318         p->rng_fault_state = True;
2319         return WERR_NOT_SUPPORTED;
2320 }
2321
2322 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p)
2323 {
2324         p->rng_fault_state = True;
2325         return WERR_NOT_SUPPORTED;
2326 }
2327
2328 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p)
2329 {
2330         p->rng_fault_state = True;
2331         return WERR_NOT_SUPPORTED;
2332 }
2333
2334 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p)
2335 {
2336         p->rng_fault_state = True;
2337         return WERR_NOT_SUPPORTED;
2338 }
2339
2340 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p)
2341 {
2342         p->rng_fault_state = True;
2343         return WERR_NOT_SUPPORTED;
2344 }