ec39c2a482d25030bc7c6f5c4f90fc78d5667b26
[tprouty/samba.git] / source / rpc_server / srv_srvsvc_nt.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Jeremy Allison               2001.
6  *  Copyright (C) Nigel Williams               2001.
7  *  Copyright (C) Gerald (Jerry) Carter        2006.
8  *  Copyright (C) Jelmer Vernooij                          2006.
9  *  
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 /* This is the implementation of the srvsvc pipe. */
26
27 #include "includes.h"
28
29 #define MAX_SERVER_DISK_ENTRIES 15
30
31 extern struct generic_mapping file_generic_mapping;
32 extern userdom_struct current_user_info;
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
36
37 /* Use for enumerating connections, pipes, & files */
38
39 struct file_enum_count {
40         TALLOC_CTX *ctx;
41         uint32 count;
42         struct srvsvc_NetFileInfo3 *info;
43 };
44
45 struct sess_file_count {
46         pid_t pid;
47         uid_t uid;
48         int count;
49 };
50
51 /****************************************************************************
52  Count the entries belonging to a service in the connection db.
53 ****************************************************************************/
54
55 static int pipe_enum_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p)
56 {
57         struct pipe_open_rec prec;
58         struct file_enum_count *fenum = (struct file_enum_count *)p;
59  
60         if (dbuf.dsize != sizeof(struct pipe_open_rec))
61                 return 0;
62
63         memcpy(&prec, dbuf.dptr, sizeof(struct pipe_open_rec));
64  
65         if ( process_exists(prec.pid) ) {
66                 struct srvsvc_NetFileInfo3 *f;
67                 int i = fenum->count;
68                 pstring fullpath;
69                 
70                 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
71                 
72                 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
73                 if ( !f ) {
74                         DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
75                         return 1;
76                 }
77
78                 fenum->info = f;
79                 
80                 fenum->info[i].fid = (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum);
81                 fenum->info[i].permissions = (FILE_READ_DATA|FILE_WRITE_DATA);
82                 fenum->info[i].num_locks = 0;
83                 fenum->info[i].user = uidtoname( prec.uid );
84                 fenum->info[i].path = fullpath;
85                         
86                 fenum->count++;
87         }
88
89         return 0;
90 }
91
92 /*******************************************************************
93 ********************************************************************/
94
95 static WERROR net_enum_pipes( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info, 
96                               uint32 *count, uint32 *resume )
97 {
98         struct file_enum_count fenum;
99         TDB_CONTEXT *conn_tdb = conn_tdb_ctx();
100
101         if ( !conn_tdb ) {
102                 DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
103                 return WERR_ACCESS_DENIED;
104         }
105         
106         fenum.ctx = ctx;
107         fenum.info = *info;
108         fenum.count = *count;
109
110         if (tdb_traverse(conn_tdb, pipe_enum_fn, &fenum) == -1) {
111                 DEBUG(0,("net_enum_pipes: traverse of connections.tdb failed with error %s.\n",
112                         tdb_errorstr(conn_tdb) ));
113                 return WERR_NOMEM;
114         }
115         
116         *info  = fenum.info;
117         *count = fenum.count;
118         
119         return WERR_OK;}
120
121 /*******************************************************************
122 ********************************************************************/
123
124 /* global needed to make use of the share_mode_forall() callback */
125 static struct file_enum_count f_enum_cnt;
126
127 static void enum_file_fn( const struct share_mode_entry *e, 
128                           const char *sharepath, const char *fname,
129                           void *dummy )
130 {
131         struct file_enum_count *fenum = &f_enum_cnt;
132  
133         /* If the pid was not found delete the entry from connections.tdb */
134
135         if ( process_exists(e->pid) ) {
136                 struct srvsvc_NetFileInfo3 *f;
137                 int i = fenum->count;
138                 files_struct fsp;
139                 struct byte_range_lock *brl;
140                 int num_locks = 0;
141                 pstring fullpath;
142                 uint32 permissions;
143                 
144                 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );                   
145                 if ( !f ) {
146                         DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
147                         return;
148                 }
149                 fenum->info = f;
150
151                 /* need to count the number of locks on a file */
152                 
153                 ZERO_STRUCT( fsp );             
154                 fsp.dev   = e->dev;
155                 fsp.inode = e->inode;
156                 
157                 if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) {
158                         num_locks = brl->num_locks;
159                         TALLOC_FREE( brl );
160                 }
161                 
162                 if ( strcmp( fname, "." ) == 0 ) {
163                         pstr_sprintf( fullpath, "C:%s", sharepath );
164                 } else {
165                         pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
166                 }
167                 string_replace( fullpath, '/', '\\' );
168                 
169                 /* mask out create (what ever that is) */
170                 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
171
172                 fenum->info[i].fid = e->share_file_id;
173                 fenum->info[i].permissions = permissions;
174                 fenum->info[i].num_locks = num_locks;
175                 fenum->info[i].user = uidtoname(e->uid);
176                 fenum->info[i].path = fullpath;
177                         
178                 fenum->count++;
179         }
180
181         return;
182
183 }
184
185 /*******************************************************************
186 ********************************************************************/
187
188 static WERROR net_enum_files( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info, 
189                               uint32 *count, uint32 *resume )
190 {
191         f_enum_cnt.ctx = ctx;
192         f_enum_cnt.count = *count;
193         f_enum_cnt.info = *info;
194         
195         share_mode_forall( enum_file_fn, NULL );
196         
197         *info  = f_enum_cnt.info;
198         *count = f_enum_cnt.count;
199         
200         return WERR_OK;
201 }
202
203 /*******************************************************************
204  Utility function to get the 'type' of a share from a share definition.
205  ********************************************************************/
206 static uint32 get_share_type(const struct share_params *params)
207 {
208         char *net_name = lp_servicename(params->service);
209         int len_net_name = strlen(net_name);
210         
211         /* work out the share type */
212         uint32 type = STYPE_DISKTREE;
213
214         if (lp_print_ok(params->service))
215                 type = STYPE_PRINTQ;
216         if (strequal(lp_fstype(params->service), "IPC"))
217                 type = STYPE_IPC;
218         if (net_name[len_net_name] == '$')
219                 type |= STYPE_HIDDEN;
220
221         return type;
222 }
223         
224 /*******************************************************************
225  Fill in a share info level 0 structure.
226  ********************************************************************/
227
228 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *sh0,
229                                   const struct share_params *params)
230 {
231         sh0->name = lp_servicename(params->service);
232 }
233
234 /*******************************************************************
235  Fill in a share info level 1 structure.
236  ********************************************************************/
237
238 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1,
239                                   const struct share_params *params)
240 {
241         connection_struct *conn = p->conn;
242
243         sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
244                                      conn->user, conn->connectpath, conn->gid,
245                                      get_current_username(),
246                                      current_user_info.domain,
247                                      lp_comment(params->service));
248
249         sh1->name = lp_servicename(params->service);
250         sh1->type = get_share_type(params);
251 }
252
253 /*******************************************************************
254  Fill in a share info level 2 structure.
255  ********************************************************************/
256
257 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2,
258                                   const struct share_params *params)
259 {
260         connection_struct *conn = p->conn;
261         char *remark;
262         char *path;
263         int max_connections = lp_max_connections(params->service);
264         uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
265         int count = 0;
266         char *net_name = lp_servicename(params->service);
267         
268         remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
269                                      conn->user, conn->connectpath, conn->gid,
270                                      get_current_username(),
271                                      current_user_info.domain,
272                                      lp_comment(params->service));
273         path = talloc_asprintf(p->mem_ctx, "C:%s",
274                                lp_pathname(params->service));
275
276         /*
277          * Change / to \\ so that win2k will see it as a valid path.  This was
278          * added to enable use of browsing in win2k add share dialog.
279          */ 
280
281         string_replace(path, '/', '\\');
282
283         count = count_current_connections( net_name, False  );
284         sh2->name = net_name;
285         sh2->type = get_share_type(params);
286         sh2->comment = remark;
287         sh2->permissions = 0;
288         sh2->max_users = max_uses;
289         sh2->current_users = count;
290         sh2->path = path;
291         sh2->password = "";
292 }
293
294 /*******************************************************************
295  Map any generic bits to file specific bits.
296 ********************************************************************/
297
298 static void map_generic_share_sd_bits(SEC_DESC *psd)
299 {
300         int i;
301         SEC_ACL *ps_dacl = NULL;
302
303         if (!psd)
304                 return;
305
306         ps_dacl = psd->dacl;
307         if (!ps_dacl)
308                 return;
309
310         for (i = 0; i < ps_dacl->num_aces; i++) {
311                 SEC_ACE *psa = &ps_dacl->aces[i];
312                 uint32 orig_mask = psa->access_mask;
313
314                 se_map_generic(&psa->access_mask, &file_generic_mapping);
315                 psa->access_mask |= orig_mask;
316         }       
317 }
318
319 /*******************************************************************
320  Fill in a share info level 501 structure.
321 ********************************************************************/
322
323 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501,
324                                     const struct share_params *params)
325 {
326         connection_struct *conn = p->conn;
327         char *remark;
328         const char *net_name = lp_servicename(params->service);
329
330         remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
331                                      conn->user, conn->connectpath, conn->gid,
332                                      get_current_username(),
333                                      current_user_info.domain,
334                                      lp_comment(params->service));
335
336
337         sh501->name = net_name;
338         sh501->type = get_share_type(params);
339         sh501->comment = remark;
340         sh501->csc_policy = (lp_csc_policy(params->service) << 4);
341 }
342
343 /*******************************************************************
344  Fill in a share info level 502 structure.
345  ********************************************************************/
346
347 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *sh502,
348                                     const struct share_params *params)
349 {
350         int max_connections = lp_max_connections(params->service);
351         uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
352         connection_struct *conn = p->conn;
353         int count; 
354         char *net_name;
355         char *remark;
356         char *path;
357         SEC_DESC *sd;
358         size_t sd_size;
359         TALLOC_CTX *ctx = p->mem_ctx;
360
361
362         ZERO_STRUCTP(sh502);
363
364         net_name = lp_servicename(params->service);
365         count = count_current_connections( net_name, False  );
366
367         remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
368                                      conn->user, conn->connectpath, conn->gid,
369                                      get_current_username(),
370                                      current_user_info.domain,
371                                      lp_comment(params->service));
372
373         path = talloc_asprintf(p->mem_ctx, "C:%s",
374                                lp_pathname(params->service));
375
376         /*
377          * Change / to \\ so that win2k will see it as a valid path.  This was
378          * added to enable use of browsing in win2k add share dialog.
379          */ 
380
381         string_replace(path, '/', '\\');
382
383         sd = get_share_security(ctx, lp_servicename(params->service),
384                                 &sd_size);
385
386         sh502->name = net_name;
387         sh502->type = get_share_type(params);
388         sh502->comment = remark;
389         sh502->path = path;
390         sh502->password = "";
391         sh502->sd = sd;
392         sh502->permissions = 0;
393         sh502->max_users = max_uses;
394         sh502->current_users = count;
395         sh502->unknown = 1;
396 }
397
398 /***************************************************************************
399  Fill in a share info level 1004 structure.
400  ***************************************************************************/
401
402 static void init_srv_share_info_1004(pipes_struct *p,
403                                      struct srvsvc_NetShareInfo1004* sh1004,
404                                      const struct share_params *params)
405 {
406         connection_struct *conn = p->conn;
407         char *remark;
408
409         remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
410                                      conn->user, conn->connectpath, conn->gid,
411                                      get_current_username(),
412                                      current_user_info.domain,
413                                      lp_comment(params->service));
414
415         ZERO_STRUCTP(sh1004);
416
417         sh1004->comment = remark;
418 }
419
420 /***************************************************************************
421  Fill in a share info level 1005 structure.
422  ***************************************************************************/
423
424 static void init_srv_share_info_1005(pipes_struct *p,
425                                      struct srvsvc_NetShareInfo1005* sh1005,
426                                      const struct share_params *params)
427 {
428         sh1005->dfs_flags = 0;
429
430         if(lp_host_msdfs() && lp_msdfs_root(params->service))
431                 sh1005->dfs_flags |= 
432                         SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
433         sh1005->dfs_flags |= 
434                 lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT;
435 }
436 /***************************************************************************
437  Fill in a share info level 1006 structure.
438  ***************************************************************************/
439
440 static void init_srv_share_info_1006(pipes_struct *p,
441                                      struct srvsvc_NetShareInfo1006* sh1006,
442                                      const struct share_params *params)
443 {
444         sh1006->max_users = -1;
445 }
446
447 /***************************************************************************
448  Fill in a share info level 1007 structure.
449  ***************************************************************************/
450
451 static void init_srv_share_info_1007(pipes_struct *p,
452                                      struct srvsvc_NetShareInfo1007* sh1007,
453                                      const struct share_params *params)
454 {
455         uint32 flags = 0;
456
457         ZERO_STRUCTP(sh1007);
458   
459         sh1007->flags = flags;
460         sh1007->alternate_directory_name = "";
461 }
462
463 /*******************************************************************
464  Fill in a share info level 1501 structure.
465  ********************************************************************/
466
467 static void init_srv_share_info_1501(pipes_struct *p,
468                                      struct sec_desc_buf *sh1501,
469                                      const struct share_params *params)
470 {
471         SEC_DESC *sd;
472         size_t sd_size;
473         TALLOC_CTX *ctx = p->mem_ctx;
474
475         ZERO_STRUCTP(sh1501);
476
477         sd = get_share_security(ctx, lp_servicename(params->service),
478                                 &sd_size);
479
480         sh1501->sd = sd;
481 }
482
483 /*******************************************************************
484  True if it ends in '$'.
485  ********************************************************************/
486
487 static BOOL is_hidden_share(const struct share_params *params)
488 {
489         const char *net_name = lp_servicename(params->service);
490
491         return (net_name[strlen(net_name) - 1] == '$');
492 }
493
494 /*******************************************************************
495  Fill in a share info structure.
496  ********************************************************************/
497
498 static WERROR init_srv_share_info_ctr(pipes_struct *p,
499                                       union srvsvc_NetShareCtr *ctr,
500                                       uint32 info_level, uint32 *resume_hnd,
501                                       uint32 *total_entries, BOOL all_shares)
502 {
503         TALLOC_CTX *ctx = p->mem_ctx;
504         struct share_iterator *shares;
505         struct share_params *share;
506
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         pstring command;
1684         int ret;
1685         int snum;
1686         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1687         BOOL is_disk_op;
1688         fstring tmp_share_name;
1689
1690         DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1691
1692         if ( strequal(share_name,"IPC$") 
1693                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1694                 || strequal(share_name,"global") )
1695         {
1696                 return WERR_ACCESS_DENIED;
1697         }
1698
1699         fstrcpy(tmp_share_name, share_name);
1700         snum = find_service(tmp_share_name);
1701
1702         if (snum < 0)
1703                 return WERR_NO_SUCH_SHARE;
1704
1705         /* No change to printer shares. */
1706         if (lp_print_ok(snum))
1707                 return WERR_ACCESS_DENIED;
1708
1709         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1710
1711         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1712                 return WERR_ACCESS_DENIED;
1713
1714         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1715                 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1716                 return WERR_ACCESS_DENIED;
1717         }
1718                 
1719         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1720                         lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
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         /********* END SeDiskOperatorPrivilege BLOCK *********/
1738
1739         DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1740
1741         if ( ret != 0 )
1742                 return WERR_ACCESS_DENIED;
1743
1744         /* Delete the SD in the database. */
1745         delete_share_security(snum);
1746
1747         lp_killservice(snum);
1748
1749         return WERR_OK;
1750 }
1751
1752 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1753 {
1754         DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1755
1756         return _srvsvc_NetShareDel(p, server_unc, share_name, reserved);
1757 }
1758
1759 /*******************************************************************
1760 time of day
1761 ********************************************************************/
1762
1763 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, const char *server_unc, struct srvsvc_NetRemoteTODInfo *tod)
1764 {
1765         struct tm *t;
1766         time_t unixdate = time(NULL);
1767         WERROR status = WERR_OK;
1768
1769         /* We do this call first as if we do it *after* the gmtime call
1770            it overwrites the pointed-to values. JRA */
1771
1772         uint32 zone = get_time_zone(unixdate)/60;
1773
1774         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1775
1776         t = gmtime(&unixdate);
1777
1778         /* set up the */
1779         tod->elapsed = unixdate;
1780         tod->msecs = 0;
1781         tod->hours = t->tm_hour;
1782         tod->mins = t->tm_min;
1783         tod->secs = t->tm_sec;
1784         tod->hunds = 0;
1785         tod->timezone = zone;
1786         tod->tinterval = 10000;
1787         tod->day = t->tm_mday;
1788         tod->month = t->tm_mon + 1;
1789         tod->year = 1900+t->tm_year;
1790         tod->weekday = t->tm_wday;
1791         
1792         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1793
1794         return status;
1795 }
1796
1797 /***********************************************************************************
1798  Win9x NT tools get security descriptor.
1799 ***********************************************************************************/
1800
1801 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)
1802 {
1803         SEC_DESC *psd = NULL;
1804         size_t sd_size;
1805         DATA_BLOB null_pw;
1806         files_struct *fsp = NULL;
1807         SMB_STRUCT_STAT st;
1808         BOOL bad_path;
1809         NTSTATUS nt_status;
1810         connection_struct *conn = NULL;
1811         BOOL became_user = False; 
1812         WERROR status = WERR_OK;
1813         pstring tmp_file;
1814
1815         ZERO_STRUCT(st);
1816
1817
1818         /* Null password is ok - we are already an authenticated user... */
1819         null_pw = data_blob(NULL, 0);
1820
1821         become_root();
1822         conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1823         unbecome_root();
1824
1825         if (conn == NULL) {
1826                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", share));
1827                 status = ntstatus_to_werror(nt_status);
1828                 goto error_exit;
1829         }
1830
1831         if (!become_user(conn, conn->vuid)) {
1832                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1833                 status = WERR_ACCESS_DENIED;
1834                 goto error_exit;
1835         }
1836         became_user = True;
1837
1838         pstrcpy(tmp_file, file);
1839         unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1840         if (bad_path) {
1841                 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", file));
1842                 status = WERR_ACCESS_DENIED;
1843                 goto error_exit;
1844         }
1845
1846         if (!check_name(file,conn)) {
1847                 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", file));
1848                 status = WERR_ACCESS_DENIED;
1849                 goto error_exit;
1850         }
1851
1852         nt_status = open_file_stat(conn, file, &st, &fsp);
1853         if (!NT_STATUS_IS_OK(nt_status)) {
1854                 /* Perhaps it is a directory */
1855                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1856                         nt_status = open_directory(conn, file, &st,
1857                                         READ_CONTROL_ACCESS,
1858                                         FILE_SHARE_READ|FILE_SHARE_WRITE,
1859                                         FILE_OPEN,
1860                                         0,
1861                                         NULL, &fsp);
1862
1863                 if (!NT_STATUS_IS_OK(nt_status)) {
1864                         DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", file));
1865                         status = WERR_ACCESS_DENIED;
1866                         goto error_exit;
1867                 }
1868         }
1869
1870         sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1871
1872         if (sd_size == 0) {
1873                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", file));
1874                 status = WERR_ACCESS_DENIED;
1875                 goto error_exit;
1876         }
1877
1878         sd_buf->sd_size= sd_size;
1879         sd_buf->sd = psd;
1880
1881         psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1882
1883         close_file(fsp, NORMAL_CLOSE);
1884         unbecome_user();
1885         close_cnum(conn, p->pipe_user.vuid);
1886         return status;
1887
1888 error_exit:
1889
1890         if(fsp) {
1891                 close_file(fsp, NORMAL_CLOSE);
1892         }
1893
1894         if (became_user)
1895                 unbecome_user();
1896
1897         if (conn) 
1898                 close_cnum(conn, p->pipe_user.vuid);
1899
1900         return status;
1901 }
1902
1903 /***********************************************************************************
1904  Win9x NT tools set security descriptor.
1905 ***********************************************************************************/
1906
1907 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)
1908 {
1909         BOOL ret;
1910         DATA_BLOB null_pw;
1911         files_struct *fsp = NULL;
1912         SMB_STRUCT_STAT st;
1913         BOOL bad_path;
1914         NTSTATUS nt_status;
1915         connection_struct *conn = NULL;
1916         BOOL became_user = False;
1917         WERROR status = WERR_OK;
1918         pstring tmp_file;
1919
1920         ZERO_STRUCT(st);
1921
1922         /* Null password is ok - we are already an authenticated user... */
1923         null_pw = data_blob(NULL, 0);
1924
1925         become_root();
1926         conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1927         unbecome_root();
1928
1929         if (conn == NULL) {
1930                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", share));
1931                 status = ntstatus_to_werror(nt_status);
1932                 goto error_exit;
1933         }
1934
1935         if (!become_user(conn, conn->vuid)) {
1936                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1937                 status = WERR_ACCESS_DENIED;
1938                 goto error_exit;
1939         }
1940         became_user = True;
1941
1942         pstrcpy(tmp_file, file);
1943         unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1944         if (bad_path) {
1945                 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", file));
1946                 status = WERR_ACCESS_DENIED;
1947                 goto error_exit;
1948         }
1949
1950         if (!check_name(file,conn)) {
1951                 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", file));
1952                 status = WERR_ACCESS_DENIED;
1953                 goto error_exit;
1954         }
1955
1956
1957         nt_status = open_file_stat(conn, file, &st, &fsp);
1958
1959         if (!NT_STATUS_IS_OK(nt_status)) {
1960                 /* Perhaps it is a directory */
1961                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1962                         nt_status = open_directory(conn, file, &st,
1963                                                 FILE_READ_ATTRIBUTES,
1964                                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
1965                                                 FILE_OPEN,
1966                                                 0,
1967                                                 NULL, &fsp);
1968
1969                 if (!NT_STATUS_IS_OK(nt_status)) {
1970                         DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", file));
1971                         status = WERR_ACCESS_DENIED;
1972                         goto error_exit;
1973                 }
1974         }
1975
1976         ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, securityinformation, sd_buf.sd);
1977
1978         if (ret == False) {
1979                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", file));
1980                 status = WERR_ACCESS_DENIED;
1981                 goto error_exit;
1982         }
1983
1984         close_file(fsp, NORMAL_CLOSE);
1985         unbecome_user();
1986         close_cnum(conn, p->pipe_user.vuid);
1987         return status;
1988
1989 error_exit:
1990
1991         if(fsp) {
1992                 close_file(fsp, NORMAL_CLOSE);
1993         }
1994
1995         if (became_user) {
1996                 unbecome_user();
1997         }
1998
1999         if (conn) {
2000                 close_cnum(conn, p->pipe_user.vuid);
2001         }
2002
2003         return status;
2004 }
2005
2006 /***********************************************************************************
2007  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2008  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2009  These disks would the disks listed by this function.
2010  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2011  "Nigel Williams" <nigel@veritas.com>.
2012 ***********************************************************************************/
2013
2014 static const char *server_disks[] = {"C:"};
2015
2016 static uint32 get_server_disk_count(void)
2017 {
2018         return sizeof(server_disks)/sizeof(server_disks[0]);
2019 }
2020
2021 static uint32 init_server_disk_enum(uint32 *resume)
2022 {
2023         uint32 server_disk_count = get_server_disk_count();
2024
2025         /*resume can be an offset into the list for now*/
2026
2027         if(*resume & 0x80000000)
2028                 *resume = 0;
2029
2030         if(*resume > server_disk_count)
2031                 *resume = server_disk_count;
2032
2033         return server_disk_count - *resume;
2034 }
2035
2036 static const char *next_server_disk_enum(uint32 *resume)
2037 {
2038         const char *disk;
2039
2040         if(init_server_disk_enum(resume) == 0)
2041                 return NULL;
2042
2043         disk = server_disks[*resume];
2044
2045         (*resume)++;
2046
2047         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2048
2049         return disk;
2050 }
2051
2052 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)
2053 {
2054         uint32 i;
2055         const char *disk_name;
2056
2057         WERROR status = WERR_OK;
2058
2059         *totalentries = init_server_disk_enum(resume_handle);
2060         info->count = 0;
2061
2062         if(!(info->disks =  TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2063                 return WERR_NOMEM;
2064         }
2065
2066         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2067
2068         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(resume_handle)); i++) {
2069
2070                 info->count++;
2071                 (*totalentries)++;
2072
2073                 /*copy disk name into a unicode string*/
2074
2075                 info->disks[i].disk = disk_name; 
2076         }
2077
2078         /* add a terminating null string.  Is this there if there is more data to come? */
2079
2080         info->count++;
2081         (*totalentries)++;
2082
2083         info->disks[i].disk = "";
2084
2085         return status;
2086 }
2087
2088 /********************************************************************
2089 ********************************************************************/
2090
2091 WERROR _srvsvc_NetNameValidate(pipes_struct *p, const char *server_unc, const char *name, uint32_t name_type, uint32_t flags)
2092 {
2093         int len;
2094
2095         if ((flags != 0x0) && (flags != 0x80000000)) {
2096                 return WERR_INVALID_PARAM;
2097         }
2098
2099         switch ( name_type ) {
2100         case 0x9:
2101                 len = strlen_m(name);
2102
2103                 if ((flags == 0x0) && (len > 81)) {
2104                         DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", name));
2105                         return WERR_INVALID_NAME;
2106                 }
2107                 if ((flags == 0x80000000) && (len > 13)) {
2108                         DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", name));
2109                         return WERR_INVALID_NAME;
2110                 }
2111
2112                 if ( ! validate_net_name( name, INVALID_SHARENAME_CHARS, sizeof(name) ) ) {
2113                         DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", name));
2114                         return WERR_INVALID_NAME;
2115                 }
2116                 break;
2117
2118         default:
2119                 return WERR_UNKNOWN_LEVEL;
2120         }
2121
2122         return WERR_OK;
2123 }
2124
2125
2126 /********************************************************************
2127 ********************************************************************/
2128
2129 WERROR _srvsvc_NetFileClose(pipes_struct *p, const char *server_unc, uint32_t fid)
2130 {
2131         return WERR_ACCESS_DENIED;
2132 }
2133
2134 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)
2135 {
2136         p->rng_fault_state = True;
2137         return WERR_NOT_SUPPORTED;
2138 }
2139
2140 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t level, union srvsvc_NetCharDevInfo *info)
2141 {
2142         p->rng_fault_state = True;
2143         return WERR_NOT_SUPPORTED;
2144 }
2145
2146 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t opcode)
2147 {
2148         p->rng_fault_state = True;
2149         return WERR_NOT_SUPPORTED;
2150 }
2151
2152 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)
2153 {
2154         p->rng_fault_state = True;
2155         return WERR_NOT_SUPPORTED;
2156 }
2157
2158 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, const char *user, uint32_t level, union srvsvc_NetCharDevQInfo *info)
2159 {
2160         p->rng_fault_state = True;
2161         return WERR_NOT_SUPPORTED;
2162 }
2163
2164 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)
2165 {
2166         p->rng_fault_state = True;
2167         return WERR_NOT_SUPPORTED;
2168 }
2169
2170 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, const char *server_unc, const char *queue_name)
2171 {
2172         p->rng_fault_state = True;
2173         return WERR_NOT_SUPPORTED;
2174 }
2175
2176 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, const char *server_unc, const char *queue_name, const char *computer_name)
2177 {
2178         p->rng_fault_state = True;
2179         return WERR_NOT_SUPPORTED;
2180 }
2181
2182 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, const char *server_unc, uint32_t fid, uint32_t level, union srvsvc_NetFileInfo *info)
2183 {
2184         p->rng_fault_state = True;
2185         return WERR_NOT_SUPPORTED;
2186 }
2187
2188 WERROR _srvsvc_NetShareCheck(pipes_struct *p, const char *server_unc, const char *device_name, enum srvsvc_ShareType *type)
2189 {
2190         p->rng_fault_state = True;
2191         return WERR_NOT_SUPPORTED;
2192 }
2193
2194 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, const char *server_unc, const char *service, uint32_t level, uint32_t options, struct srvsvc_Statistics *stats)
2195 {
2196         p->rng_fault_state = True;
2197         return WERR_NOT_SUPPORTED;
2198 }
2199
2200 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2201 {
2202         p->rng_fault_state = True;
2203         return WERR_NOT_SUPPORTED;
2204 }
2205
2206 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)
2207 {
2208         p->rng_fault_state = True;
2209         return WERR_NOT_SUPPORTED;
2210 }
2211
2212 WERROR _srvsvc_NetTransportDel(pipes_struct *p, const char *server_unc, uint32_t unknown, struct srvsvc_NetTransportInfo0 transport)
2213 {
2214         p->rng_fault_state = True;
2215         return WERR_NOT_SUPPORTED;
2216 }
2217
2218 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, const char *server_unc, const char *transport, uint32_t servicebits, uint32_t updateimmediately)
2219 {
2220         p->rng_fault_state = True;
2221         return WERR_NOT_SUPPORTED;
2222 }
2223
2224 WERROR _srvsvc_NetPathType(pipes_struct *p, const char *server_unc, const char *path, uint32_t pathflags, uint32_t *pathtype)
2225 {
2226         p->rng_fault_state = True;
2227         return WERR_NOT_SUPPORTED;
2228 }
2229
2230 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)
2231 {
2232         p->rng_fault_state = True;
2233         return WERR_NOT_SUPPORTED;
2234 }
2235
2236 WERROR _srvsvc_NetPathCompare(pipes_struct *p, const char *server_unc, const char *path1, const char *path2, uint32_t pathtype, uint32_t pathflags)
2237 {
2238         p->rng_fault_state = True;
2239         return WERR_NOT_SUPPORTED;
2240 }
2241
2242 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p)
2243 {
2244         p->rng_fault_state = True;
2245         return WERR_NOT_SUPPORTED;
2246 }
2247
2248 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, const char *server_unc, const char *name1, const char *name2, uint32_t name_type, uint32_t flags)
2249 {
2250         p->rng_fault_state = True;
2251         return WERR_NOT_SUPPORTED;
2252 }
2253
2254 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, const char *server_unc, const char *share, uint32_t reserved, struct policy_handle *hnd)
2255 {
2256         p->rng_fault_state = True;
2257         return WERR_NOT_SUPPORTED;
2258 }
2259
2260 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct policy_handle *hnd)
2261 {
2262         p->rng_fault_state = True;
2263         return WERR_NOT_SUPPORTED;
2264 }
2265
2266 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2267 {
2268         p->rng_fault_state = True;
2269         return WERR_NOT_SUPPORTED;
2270 }
2271
2272 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)
2273 {
2274         p->rng_fault_state = True;
2275         return WERR_NOT_SUPPORTED;
2276 }
2277
2278 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p)
2279 {
2280         p->rng_fault_state = True;
2281         return WERR_NOT_SUPPORTED;
2282 }
2283
2284 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p)
2285 {
2286         p->rng_fault_state = True;
2287         return WERR_NOT_SUPPORTED;
2288 }
2289
2290 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p)
2291 {
2292         p->rng_fault_state = True;
2293         return WERR_NOT_SUPPORTED;
2294 }
2295
2296 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p)
2297 {
2298         p->rng_fault_state = True;
2299         return WERR_NOT_SUPPORTED;
2300 }
2301
2302 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p)
2303 {
2304         p->rng_fault_state = True;
2305         return WERR_NOT_SUPPORTED;
2306 }
2307
2308 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p)
2309 {
2310         p->rng_fault_state = True;
2311         return WERR_NOT_SUPPORTED;
2312 }
2313
2314 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p)
2315 {
2316         p->rng_fault_state = True;
2317         return WERR_NOT_SUPPORTED;
2318 }
2319
2320 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p)
2321 {
2322         p->rng_fault_state = True;
2323         return WERR_NOT_SUPPORTED;
2324 }
2325
2326 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p)
2327 {
2328         p->rng_fault_state = True;
2329         return WERR_NOT_SUPPORTED;
2330 }
2331
2332 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p)
2333 {
2334         p->rng_fault_state = True;
2335         return WERR_NOT_SUPPORTED;
2336 }
2337
2338 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p)
2339 {
2340         p->rng_fault_state = True;
2341         return WERR_NOT_SUPPORTED;
2342 }