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