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