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