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