Ok here it is my latest work on privileges
[vlendec/samba-autobuild/.git] / source3 / rpc_server / srv_srvsvc_nt.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Jeremy Allison                                        2001.
6  *  Copyright (C) Nigel Williams                                        2001.
7  *  
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         int len_net_name;
360         pstring remark;
361
362         char *net_name = lp_servicename(snum);
363         pstrcpy(remark, lp_comment(snum));
364         standard_sub_conn(p->conn, remark, sizeof(remark));
365
366         len_net_name = strlen(net_name);
367
368         init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
369         init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
370 }
371
372 /*******************************************************************
373  Fill in a share info level 502 structure.
374  ********************************************************************/
375
376 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
377 {
378         int len_net_name;
379         pstring net_name;
380         pstring remark;
381         pstring path;
382         pstring passwd;
383         SEC_DESC *sd;
384         size_t sd_size;
385         TALLOC_CTX *ctx = p->mem_ctx;
386
387
388         ZERO_STRUCTP(sh502);
389
390         pstrcpy(net_name, lp_servicename(snum));
391         pstrcpy(remark, lp_comment(snum));
392         standard_sub_conn(p->conn, remark,sizeof(remark));
393         pstrcpy(path, "C:");
394         pstrcat(path, lp_pathname(snum));
395
396         /*
397          * Change / to \\ so that win2k will see it as a valid path.  This was added to
398          * enable use of browsing in win2k add share dialog.
399          */ 
400
401         string_replace(path, '/', '\\');
402
403         pstrcpy(passwd, "");
404         len_net_name = strlen(net_name);
405
406         sd = get_share_security(ctx, snum, &sd_size);
407
408         init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
409         init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size);
410 }
411
412 /***************************************************************************
413  Fill in a share info level 1004 structure.
414  ***************************************************************************/
415
416 static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
417 {
418         pstring remark;
419
420         pstrcpy(remark, lp_comment(snum));
421         standard_sub_conn(p->conn, remark, sizeof(remark));
422
423         ZERO_STRUCTP(sh1004);
424   
425         init_srv_share_info1004(&sh1004->info_1004, remark);
426         init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
427 }
428
429 /***************************************************************************
430  Fill in a share info level 1005 structure.
431  ***************************************************************************/
432
433 static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum)
434 {
435         sh1005->share_info_flags = 0;
436
437         if(lp_host_msdfs() && lp_msdfs_root(snum))
438                 sh1005->share_info_flags |= 
439                         SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
440         sh1005->share_info_flags |= 
441                 lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
442 }
443 /***************************************************************************
444  Fill in a share info level 1006 structure.
445  ***************************************************************************/
446
447 static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
448 {
449         sh1006->max_uses = -1;
450 }
451
452 /***************************************************************************
453  Fill in a share info level 1007 structure.
454  ***************************************************************************/
455
456 static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
457 {
458         pstring alternate_directory_name = "";
459         uint32 flags = 0;
460
461         ZERO_STRUCTP(sh1007);
462   
463         init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name);
464         init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name);
465 }
466
467 /*******************************************************************
468  Fill in a share info level 1501 structure.
469  ********************************************************************/
470
471 static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
472 {
473         SEC_DESC *sd;
474         size_t sd_size;
475         TALLOC_CTX *ctx = p->mem_ctx;
476
477         ZERO_STRUCTP(sh1501);
478
479         sd = get_share_security(ctx, snum, &sd_size);
480
481         sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
482 }
483
484 /*******************************************************************
485  True if it ends in '$'.
486  ********************************************************************/
487
488 static BOOL is_hidden_share(int snum)
489 {
490         const char *net_name = lp_servicename(snum);
491
492         return (net_name[strlen(net_name) - 1] == '$') ? True : False;
493 }
494
495 /*******************************************************************
496  Fill in a share info structure.
497  ********************************************************************/
498
499 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
500                uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
501 {
502         int num_entries = 0;
503         int num_services = lp_numservices();
504         int snum;
505         TALLOC_CTX *ctx = p->mem_ctx;
506
507         DEBUG(5,("init_srv_share_info_ctr\n"));
508
509         ZERO_STRUCTPN(ctr);
510
511         ctr->info_level = ctr->switch_value = info_level;
512         *resume_hnd = 0;
513
514         /* Count the number of entries. */
515         for (snum = 0; snum < num_services; snum++) {
516                 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
517                         num_entries++;
518         }
519
520         *total_entries = num_entries;
521         ctr->num_entries2 = ctr->num_entries = num_entries;
522         ctr->ptr_share_info = ctr->ptr_entries = 1;
523
524         if (!num_entries)
525                 return True;
526
527         switch (info_level) {
528         case 0:
529         {
530                 SRV_SHARE_INFO_0 *info0;
531                 int i = 0;
532
533                 info0 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_0));
534
535                 for (snum = *resume_hnd; snum < num_services; snum++) {
536                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
537                                 init_srv_share_info_0(p, &info0[i++], snum);
538                         }
539                 }
540
541                 ctr->share.info0 = info0;
542                 break;
543
544         }
545
546         case 1:
547         {
548                 SRV_SHARE_INFO_1 *info1;
549                 int i = 0;
550
551                 info1 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1));
552
553                 for (snum = *resume_hnd; snum < num_services; snum++) {
554                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
555                                 init_srv_share_info_1(p, &info1[i++], snum);
556                         }
557                 }
558
559                 ctr->share.info1 = info1;
560                 break;
561         }
562
563         case 2:
564         {
565                 SRV_SHARE_INFO_2 *info2;
566                 int i = 0;
567
568                 info2 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_2));
569
570                 for (snum = *resume_hnd; snum < num_services; snum++) {
571                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
572                                 init_srv_share_info_2(p, &info2[i++], snum);
573                         }
574                 }
575
576                 ctr->share.info2 = info2;
577                 break;
578         }
579
580         case 501:
581         {
582                 SRV_SHARE_INFO_501 *info501;
583                 int i = 0;
584         
585                 info501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_501));
586
587                 for (snum = *resume_hnd; snum < num_services; snum++) {
588                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
589                                 init_srv_share_info_501(p, &info501[i++], snum);
590                         }
591                 }
592         
593                 ctr->share.info501 = info501;
594                 break;
595         }
596
597         case 502:
598         {
599                 SRV_SHARE_INFO_502 *info502;
600                 int i = 0;
601
602                 info502 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_502));
603
604                 for (snum = *resume_hnd; snum < num_services; snum++) {
605                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
606                                 init_srv_share_info_502(p, &info502[i++], snum);
607                         }
608                 }
609
610                 ctr->share.info502 = info502;
611                 break;
612         }
613
614         /* here for completeness but not currently used with enum (1004 - 1501)*/
615         
616         case 1004:
617         {
618                 SRV_SHARE_INFO_1004 *info1004;
619                 int i = 0;
620
621                 info1004 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1004));
622
623                 for (snum = *resume_hnd; snum < num_services; snum++) {
624                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
625                                 init_srv_share_info_1004(p, &info1004[i++], snum);
626                         }
627                 }
628
629                 ctr->share.info1004 = info1004;
630                 break;
631         }
632
633         case 1005:
634         {
635                 SRV_SHARE_INFO_1005 *info1005;
636                 int i = 0;
637
638                 info1005 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1005));
639
640                 for (snum = *resume_hnd; snum < num_services; snum++) {
641                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
642                                 init_srv_share_info_1005(p, &info1005[i++], snum);
643                         }
644                 }
645
646                 ctr->share.info1005 = info1005;
647                 break;
648         }
649
650         case 1006:
651         {
652                 SRV_SHARE_INFO_1006 *info1006;
653                 int i = 0;
654
655                 info1006 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1006));
656
657                 for (snum = *resume_hnd; snum < num_services; snum++) {
658                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
659                                 init_srv_share_info_1006(p, &info1006[i++], snum);
660                         }
661                 }
662
663                 ctr->share.info1006 = info1006;
664                 break;
665         }
666
667         case 1007:
668         {
669                 SRV_SHARE_INFO_1007 *info1007;
670                 int i = 0;
671
672                 info1007 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1007));
673
674                 for (snum = *resume_hnd; snum < num_services; snum++) {
675                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
676                                 init_srv_share_info_1007(p, &info1007[i++], snum);
677                         }
678                 }
679
680                 ctr->share.info1007 = info1007;
681                 break;
682         }
683
684         case 1501:
685         {
686                 SRV_SHARE_INFO_1501 *info1501;
687                 int i = 0;
688
689                 info1501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1501));
690
691                 for (snum = *resume_hnd; snum < num_services; snum++) {
692                         if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
693                                 init_srv_share_info_1501(p, &info1501[i++], snum);
694                         }
695                 }
696
697                 ctr->share.info1501 = info1501;
698                 break;
699         }
700         default:
701                 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
702                 return False;
703         }
704
705         return True;
706 }
707
708 /*******************************************************************
709  Inits a SRV_R_NET_SHARE_ENUM structure.
710 ********************************************************************/
711
712 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
713                                       uint32 info_level, uint32 resume_hnd, BOOL all)  
714 {
715         DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
716
717         if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
718                                     &resume_hnd, &r_n->total_entries, all)) {
719                 r_n->status = WERR_OK;
720         } else {
721                 r_n->status = WERR_UNKNOWN_LEVEL;
722         }
723
724         init_enum_hnd(&r_n->enum_hnd, resume_hnd);
725 }
726
727 /*******************************************************************
728  Inits a SRV_R_NET_SHARE_GET_INFO structure.
729 ********************************************************************/
730
731 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
732                                   char *share_name, uint32 info_level)
733 {
734         WERROR status = WERR_OK;
735         int snum;
736
737         DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
738
739         r_n->info.switch_value = info_level;
740
741         snum = find_service(share_name);
742
743         if (snum >= 0) {
744                 switch (info_level) {
745                 case 0:
746                         init_srv_share_info_0(p, &r_n->info.share.info0, snum);
747                         break;
748                 case 1:
749                         init_srv_share_info_1(p, &r_n->info.share.info1, snum);
750                         break;
751                 case 2:
752                         init_srv_share_info_2(p, &r_n->info.share.info2, snum);
753                         break;
754                 case 501:
755                         init_srv_share_info_501(p, &r_n->info.share.info501, snum);
756                         break;
757                 case 502:
758                         init_srv_share_info_502(p, &r_n->info.share.info502, snum);
759                         break;
760
761                         /* here for completeness */
762                 case 1004:
763                         init_srv_share_info_1004(p, &r_n->info.share.info1004, snum);
764                         break;
765                 case 1005:
766                         init_srv_share_info_1005(p, &r_n->info.share.info1005, snum);
767                         break;
768
769                         /* here for completeness 1006 - 1501 */
770                 case 1006:
771                         init_srv_share_info_1006(p, &r_n->info.share.info1006, snum);
772                         break;
773                 case 1007:
774                         init_srv_share_info_1007(p, &r_n->info.share.info1007, snum);
775                         break;
776                 case 1501:
777                         init_srv_share_info_1501(p, &r_n->info.share.info1501, snum);
778                         break;
779                 default:
780                         DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
781                         status = WERR_UNKNOWN_LEVEL;
782                         break;
783                 }
784         } else {
785                 status = WERR_INVALID_NAME;
786         }
787
788         r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
789         r_n->status = status;
790 }
791
792 /*******************************************************************
793  fill in a sess info level 1 structure.
794  ********************************************************************/
795
796 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
797 {
798         init_srv_sess_info0(se0, name);
799         init_srv_sess_info0_str(str0, name);
800 }
801
802 /*******************************************************************
803  fill in a sess info level 0 structure.
804  ********************************************************************/
805
806 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
807 {
808         struct sessionid *session_list;
809         uint32 num_entries = 0;
810         (*stot) = list_sessions(&session_list);
811
812         if (ss0 == NULL) {
813                 (*snum) = 0;
814                 SAFE_FREE(session_list);
815                 return;
816         }
817
818         DEBUG(5,("init_srv_sess_0_ss0\n"));
819
820         if (snum) {
821                 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
822                         init_srv_sess_0_info(&ss0->info_0[num_entries],
823                                                                  &ss0->info_0_str[num_entries], session_list[(*snum)].remote_machine);
824
825                         /* move on to creating next session */
826                         /* move on to creating next sess */
827                         num_entries++;
828                 }
829
830                 ss0->num_entries_read  = num_entries;
831                 ss0->ptr_sess_info     = num_entries > 0 ? 1 : 0;
832                 ss0->num_entries_read2 = num_entries;
833                 
834                 if ((*snum) >= (*stot)) {
835                         (*snum) = 0;
836                 }
837
838         } else {
839                 ss0->num_entries_read = 0;
840                 ss0->ptr_sess_info = 0;
841                 ss0->num_entries_read2 = 0;
842         }
843         SAFE_FREE(session_list);
844 }
845
846 /*******************************************************************
847  fill in a sess info level 1 structure.
848  ********************************************************************/
849
850 static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
851                                 char *name, char *user,
852                                 uint32 num_opens,
853                                 uint32 open_time, uint32 idle_time,
854                                 uint32 usr_flgs)
855 {
856         init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
857         init_srv_sess_info1_str(str1, name, user);
858 }
859
860 /*******************************************************************
861  fill in a sess info level 1 structure.
862  ********************************************************************/
863
864 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
865 {
866         struct sessionid *session_list;
867         uint32 num_entries = 0;
868         (*stot) = list_sessions(&session_list);
869
870         if (ss1 == NULL) {
871                 (*snum) = 0;
872                 SAFE_FREE(session_list);
873                 return;
874         }
875
876         DEBUG(5,("init_srv_sess_1_ss1\n"));
877
878         if (snum) {
879                 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
880                         init_srv_sess_1_info(&ss1->info_1[num_entries],
881                                              &ss1->info_1_str[num_entries],
882                                             session_list[*snum].remote_machine,
883                                              session_list[*snum].username,
884                                              1, 10, 5, 0);
885
886                         /* move on to creating next session */
887                         /* move on to creating next sess */
888                         num_entries++;
889                 }
890
891                 ss1->num_entries_read  = num_entries;
892                 ss1->ptr_sess_info     = num_entries > 0 ? 1 : 0;
893                 ss1->num_entries_read2 = num_entries;
894                 
895                 if ((*snum) >= (*stot)) {
896                         (*snum) = 0;
897                 }
898
899         } else {
900                 ss1->num_entries_read = 0;
901                 ss1->ptr_sess_info = 0;
902                 ss1->num_entries_read2 = 0;
903                 
904                 (*stot) = 0;
905         }
906 }
907
908 /*******************************************************************
909  makes a SRV_R_NET_SESS_ENUM structure.
910 ********************************************************************/
911
912 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
913                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
914 {
915         WERROR status = WERR_OK;
916         DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
917
918         ctr->switch_value = switch_value;
919
920         switch (switch_value) {
921         case 0:
922                 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
923                 ctr->ptr_sess_ctr = 1;
924                 break;
925         case 1:
926                 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
927                 ctr->ptr_sess_ctr = 1;
928                 break;
929         default:
930                 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
931                 (*resume_hnd) = 0;
932                 (*total_entries) = 0;
933                 ctr->ptr_sess_ctr = 0;
934                 status = WERR_UNKNOWN_LEVEL;
935                 break;
936         }
937
938         return status;
939 }
940
941 /*******************************************************************
942  makes a SRV_R_NET_SESS_ENUM structure.
943 ********************************************************************/
944
945 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
946                                 uint32 resume_hnd, int sess_level, int switch_value)  
947 {
948         DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
949
950         r_n->sess_level  = sess_level;
951
952         if (sess_level == -1)
953                 r_n->status = WERR_UNKNOWN_LEVEL;
954         else
955                 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
956
957         if (!W_ERROR_IS_OK(r_n->status))
958                 resume_hnd = 0;
959
960         init_enum_hnd(&r_n->enum_hnd, resume_hnd);
961 }
962
963 /*******************************************************************
964  fill in a conn info level 0 structure.
965  ********************************************************************/
966
967 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
968 {
969         uint32 num_entries = 0;
970         (*stot) = 1;
971
972         if (ss0 == NULL) {
973                 (*snum) = 0;
974                 return;
975         }
976
977         DEBUG(5,("init_srv_conn_0_ss0\n"));
978
979         if (snum) {
980                 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
981
982                         init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
983
984                         /* move on to creating next connection */
985                         /* move on to creating next conn */
986                         num_entries++;
987                 }
988
989                 ss0->num_entries_read  = num_entries;
990                 ss0->ptr_conn_info     = num_entries > 0 ? 1 : 0;
991                 ss0->num_entries_read2 = num_entries;
992                 
993                 if ((*snum) >= (*stot)) {
994                         (*snum) = 0;
995                 }
996
997         } else {
998                 ss0->num_entries_read = 0;
999                 ss0->ptr_conn_info = 0;
1000                 ss0->num_entries_read2 = 0;
1001
1002                 (*stot) = 0;
1003         }
1004 }
1005
1006 /*******************************************************************
1007  fill in a conn info level 1 structure.
1008  ********************************************************************/
1009
1010 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1011                                 uint32 id, uint32 type,
1012                                 uint32 num_opens, uint32 num_users, uint32 open_time,
1013                                 const char *usr_name, const char *net_name)
1014 {
1015         init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1016         init_srv_conn_info1_str(str1, usr_name, net_name);
1017 }
1018
1019 /*******************************************************************
1020  fill in a conn info level 1 structure.
1021  ********************************************************************/
1022
1023 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1024 {
1025         uint32 num_entries = 0;
1026         (*stot) = 1;
1027
1028         if (ss1 == NULL) {
1029                 (*snum) = 0;
1030                 return;
1031         }
1032
1033         DEBUG(5,("init_srv_conn_1_ss1\n"));
1034
1035         if (snum) {
1036                 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1037                         init_srv_conn_1_info(&ss1->info_1[num_entries],
1038                                                                  &ss1->info_1_str[num_entries],
1039                                              (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1040
1041                         /* move on to creating next connection */
1042                         /* move on to creating next conn */
1043                         num_entries++;
1044                 }
1045
1046                 ss1->num_entries_read  = num_entries;
1047                 ss1->ptr_conn_info     = num_entries > 0 ? 1 : 0;
1048                 ss1->num_entries_read2 = num_entries;
1049                 
1050
1051                 if ((*snum) >= (*stot)) {
1052                         (*snum) = 0;
1053                 }
1054
1055         } else {
1056                 ss1->num_entries_read = 0;
1057                 ss1->ptr_conn_info = 0;
1058                 ss1->num_entries_read2 = 0;
1059                 
1060                 (*stot) = 0;
1061         }
1062 }
1063
1064 /*******************************************************************
1065  makes a SRV_R_NET_CONN_ENUM structure.
1066 ********************************************************************/
1067
1068 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1069                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1070 {
1071         WERROR status = WERR_OK;
1072         DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1073
1074         ctr->switch_value = switch_value;
1075
1076         switch (switch_value) {
1077         case 0:
1078                 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1079                 ctr->ptr_conn_ctr = 1;
1080                 break;
1081         case 1:
1082                 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1083                 ctr->ptr_conn_ctr = 1;
1084                 break;
1085         default:
1086                 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1087                 (*resume_hnd = 0);
1088                 (*total_entries) = 0;
1089                 ctr->ptr_conn_ctr = 0;
1090                 status = WERR_UNKNOWN_LEVEL;
1091                 break;
1092         }
1093
1094         return status;
1095 }
1096
1097 /*******************************************************************
1098  makes a SRV_R_NET_CONN_ENUM structure.
1099 ********************************************************************/
1100
1101 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1102                                 uint32 resume_hnd, int conn_level, int switch_value)  
1103 {
1104         DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1105
1106         r_n->conn_level  = conn_level;
1107         if (conn_level == -1)
1108                 r_n->status = WERR_UNKNOWN_LEVEL;
1109         else
1110                 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1111
1112         if (!W_ERROR_IS_OK(r_n->status))
1113                 resume_hnd = 0;
1114
1115         init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1116 }
1117
1118 /*******************************************************************
1119  makes a SRV_R_NET_FILE_ENUM structure.
1120 ********************************************************************/
1121
1122 static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
1123                                      int switch_value, uint32 *resume_hnd, 
1124                                      uint32 *total_entries)  
1125 {
1126         WERROR status = WERR_OK;
1127         TALLOC_CTX *ctx = p->mem_ctx;
1128         DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
1129         *total_entries = 1; /* dummy entries only, for */
1130
1131         ctr->switch_value = switch_value;
1132         ctr->num_entries = *total_entries - *resume_hnd;
1133         ctr->num_entries2 = ctr->num_entries;
1134
1135         switch (switch_value) {
1136         case 3: {
1137                 int i;
1138                 if (*total_entries > 0) {
1139                         ctr->ptr_entries = 1;
1140                         ctr->file.info3 = talloc(ctx, ctr->num_entries * 
1141                                                  sizeof(SRV_FILE_INFO_3));
1142                 }
1143                 for (i=0 ;i<ctr->num_entries;i++) {
1144                         init_srv_file_info3(&ctr->file.info3[i].info_3, i+*resume_hnd, 0x35, 0, "\\PIPE\\samr", "dummy user");
1145                         init_srv_file_info3_str(&ctr->file.info3[i].info_3_str,  "\\PIPE\\samr", "dummy user");
1146                         
1147                 }
1148                 ctr->ptr_file_info = 1;
1149                 *resume_hnd = 0;
1150                 break;
1151         }
1152         default:
1153                 DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
1154                 (*resume_hnd = 0);
1155                 (*total_entries) = 0;
1156                 ctr->ptr_entries = 0;
1157                 status = WERR_UNKNOWN_LEVEL;
1158                 break;
1159         }
1160
1161         return status;
1162 }
1163
1164 /*******************************************************************
1165  makes a SRV_R_NET_FILE_ENUM structure.
1166 ********************************************************************/
1167
1168 static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n,
1169                                 uint32 resume_hnd, int file_level, int switch_value)  
1170 {
1171         DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
1172
1173         r_n->file_level  = file_level;
1174         if (file_level == 0)
1175                 r_n->status = WERR_UNKNOWN_LEVEL;
1176         else
1177                 r_n->status = init_srv_file_info_ctr(p, &r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
1178
1179         if (!W_ERROR_IS_OK(r_n->status))
1180                 resume_hnd = 0;
1181
1182         init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1183 }
1184
1185 /*******************************************************************
1186 net server get info
1187 ********************************************************************/
1188
1189 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)
1190 {
1191         WERROR status = WERR_OK;
1192         SRV_INFO_CTR *ctr = (SRV_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_INFO_CTR));
1193
1194         if (!ctr)
1195                 return WERR_NOMEM;
1196
1197         ZERO_STRUCTP(ctr);
1198
1199         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1200
1201         if (!pipe_access_check(p)) {
1202                 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1203                 return WERR_ACCESS_DENIED;
1204         }
1205
1206         switch (q_u->switch_value) {
1207
1208                 /* Technically level 102 should only be available to
1209                    Administrators but there isn't anything super-secret
1210                    here, as most of it is made up. */
1211
1212         case 102:
1213                 init_srv_info_102(&ctr->srv.sv102,
1214                                   500, global_myname(), 
1215                                   string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1216                                   lp_major_announce_version(), lp_minor_announce_version(),
1217                                   lp_default_server_announce(),
1218                                   0xffffffff, /* users */
1219                                   0xf, /* disc */
1220                                   0, /* hidden */
1221                                   240, /* announce */
1222                                   3000, /* announce delta */
1223                                   100000, /* licenses */
1224                                   "c:\\"); /* user path */
1225                 break;
1226         case 101:
1227                 init_srv_info_101(&ctr->srv.sv101,
1228                                   500, global_myname(),
1229                                   lp_major_announce_version(), lp_minor_announce_version(),
1230                                   lp_default_server_announce(),
1231                                   string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1232                 break;
1233         case 100:
1234                 init_srv_info_100(&ctr->srv.sv100, 500, global_myname());
1235                 break;
1236         default:
1237                 status = WERR_UNKNOWN_LEVEL;
1238                 break;
1239         }
1240
1241         /* set up the net server get info structure */
1242         init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1243
1244         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1245
1246         return r_u->status;
1247 }
1248
1249 /*******************************************************************
1250 net server set info
1251 ********************************************************************/
1252
1253 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)
1254 {
1255         WERROR status = WERR_OK;
1256
1257         DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1258
1259         /* Set up the net server set info structure. */
1260
1261         init_srv_r_net_srv_set_info(r_u, 0x0, status);
1262
1263         DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1264
1265         return r_u->status;
1266 }
1267
1268 /*******************************************************************
1269 net file enum
1270 ********************************************************************/
1271
1272 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1273 {
1274         DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1275
1276         /* set up the */
1277         init_srv_r_net_file_enum(p, r_u,
1278                                 get_enum_hnd(&q_u->enum_hnd),
1279                                 q_u->file_level,
1280                                 q_u->ctr.switch_value);
1281
1282         DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1283
1284         return r_u->status;
1285 }
1286
1287 /*******************************************************************
1288 net conn enum
1289 ********************************************************************/
1290
1291 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1292 {
1293         DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1294
1295         r_u->ctr = (SRV_CONN_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_CONN_INFO_CTR));
1296         if (!r_u->ctr)
1297                 return WERR_NOMEM;
1298
1299         ZERO_STRUCTP(r_u->ctr);
1300
1301         /* set up the */
1302         init_srv_r_net_conn_enum(r_u,
1303                                 get_enum_hnd(&q_u->enum_hnd),
1304                                 q_u->conn_level,
1305                                 q_u->ctr->switch_value);
1306
1307         DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1308
1309         return r_u->status;
1310 }
1311
1312 /*******************************************************************
1313 net sess enum
1314 ********************************************************************/
1315
1316 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1317 {
1318         DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1319
1320         r_u->ctr = (SRV_SESS_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_SESS_INFO_CTR));
1321         if (!r_u->ctr)
1322                 return WERR_NOMEM;
1323
1324         ZERO_STRUCTP(r_u->ctr);
1325
1326         /* set up the */
1327         init_srv_r_net_sess_enum(r_u,
1328                                 get_enum_hnd(&q_u->enum_hnd),
1329                                 q_u->sess_level,
1330                                 q_u->ctr->switch_value);
1331
1332         DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1333
1334         return r_u->status;
1335 }
1336
1337 /*******************************************************************
1338  Net share enum all.
1339 ********************************************************************/
1340
1341 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1342 {
1343         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1344
1345         if (!pipe_access_check(p)) {
1346                 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1347                 return WERR_ACCESS_DENIED;
1348         }
1349
1350         /* Create the list of shares for the response. */
1351         init_srv_r_net_share_enum(p, r_u,
1352                                 q_u->ctr.info_level,
1353                                 get_enum_hnd(&q_u->enum_hnd), True);
1354
1355         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1356
1357         return r_u->status;
1358 }
1359
1360 /*******************************************************************
1361  Net share enum.
1362 ********************************************************************/
1363
1364 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1365 {
1366         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1367
1368         if (!pipe_access_check(p)) {
1369                 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1370                 return WERR_ACCESS_DENIED;
1371         }
1372
1373         /* Create the list of shares for the response. */
1374         init_srv_r_net_share_enum(p, r_u,
1375                                   q_u->ctr.info_level,
1376                                   get_enum_hnd(&q_u->enum_hnd), False);
1377
1378         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1379
1380         return r_u->status;
1381 }
1382
1383 /*******************************************************************
1384  Net share get info.
1385 ********************************************************************/
1386
1387 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)
1388 {
1389         fstring share_name;
1390
1391         DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1392
1393         /* Create the list of shares for the response. */
1394         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1395         init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1396
1397         DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1398
1399         return r_u->status;
1400 }
1401
1402 /*******************************************************************
1403  Check a given DOS pathname is valid for a share.
1404 ********************************************************************/
1405
1406 static char *valid_share_pathname(char *dos_pathname)
1407 {
1408         char *ptr;
1409
1410         /* Convert any '\' paths to '/' */
1411         unix_format(dos_pathname);
1412         unix_clean_name(dos_pathname);
1413
1414         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1415         ptr = dos_pathname;
1416         if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1417                 ptr += 2;
1418
1419         /* Only abolute paths allowed. */
1420         if (*ptr != '/')
1421                 return NULL;
1422
1423         return ptr;
1424 }
1425
1426 static BOOL exist_share_pathname(char *unix_pathname)
1427 {
1428         pstring saved_pathname;
1429         int ret;
1430
1431         /* Can we cd to it ? */
1432
1433         /* First save our current directory. */
1434         if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
1435                 return False;
1436
1437         ret = chdir(unix_pathname);
1438
1439         /* We *MUST* be able to chdir back. Abort if we can't. */
1440         if (chdir(saved_pathname) == -1)
1441                 smb_panic("valid_share_pathname: Unable to restore current directory.\n");
1442
1443         if (ret == -1) return False;
1444
1445         return True;
1446 }
1447
1448 /*******************************************************************
1449  Net share set info. Modify share details.
1450 ********************************************************************/
1451
1452 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)
1453 {
1454         struct current_user user;
1455         pstring command;
1456         fstring share_name;
1457         fstring comment;
1458         pstring pathname;
1459         int type;
1460         int snum;
1461         int ret;
1462         char *path;
1463         SEC_DESC *psd = NULL;
1464
1465         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1466
1467         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1468
1469         r_u->parm_error = 0;
1470
1471         if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1472                 return WERR_ACCESS_DENIED;
1473
1474         snum = find_service(share_name);
1475
1476         /* Does this share exist ? */
1477         if (snum < 0)
1478                 return WERR_INVALID_NAME;
1479
1480         /* No change to printer shares. */
1481         if (lp_print_ok(snum))
1482                 return WERR_ACCESS_DENIED;
1483
1484         get_current_user(&user,p);
1485
1486         if (user.uid != sec_initial_uid())
1487                 return WERR_ACCESS_DENIED;
1488
1489         switch (q_u->info_level) {
1490         case 1:
1491                 pstrcpy(pathname, lp_pathname(snum));
1492                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1493                 type = q_u->info.share.info2.info_2.type;
1494                 psd = NULL;
1495                 break;
1496         case 2:
1497                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1498                 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1499                 type = q_u->info.share.info2.info_2.type;
1500                 psd = NULL;
1501                 break;
1502 #if 0
1503                 /* not supported on set but here for completeness */
1504         case 501:
1505                 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1506                 type = q_u->info.share.info501.info_501.type;
1507                 psd = NULL;
1508                 break;
1509 #endif
1510         case 502:
1511                 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1512                 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1513                 type = q_u->info.share.info502.info_502.type;
1514                 psd = q_u->info.share.info502.info_502_str.sd;
1515                 map_generic_share_sd_bits(psd);
1516                 break;
1517         case 1004:
1518                 pstrcpy(pathname, lp_pathname(snum));
1519                 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1520                 type = STYPE_DISKTREE;
1521                 break;
1522         case 1005:
1523                 /* XP re-sets the csc policy even if it wasn't changed by the
1524                    user, so we must compare it to see if it's what is set in
1525                    smb.conf, so that we can contine other ops like setting
1526                    ACLs on a share */
1527                 if (((q_u->info.share.info1005.share_info_flags &
1528                       SHARE_1005_CSC_POLICY_MASK) >>
1529                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1530                         return WERR_OK;
1531                 else {
1532                         DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1533                         return WERR_ACCESS_DENIED;
1534                 }
1535                 break;
1536         case 1006:
1537         case 1007:
1538                 return WERR_ACCESS_DENIED;
1539                 break;
1540         case 1501:
1541                 pstrcpy(pathname, lp_pathname(snum));
1542                 fstrcpy(comment, lp_comment(snum));
1543                 psd = q_u->info.share.info1501.sdb->sec;
1544                 map_generic_share_sd_bits(psd);
1545                 type = STYPE_DISKTREE;
1546                 break;
1547         default:
1548                 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1549                 return WERR_UNKNOWN_LEVEL;
1550         }
1551
1552         /* We can only modify disk shares. */
1553         if (type != STYPE_DISKTREE)
1554                 return WERR_ACCESS_DENIED;
1555                 
1556         /* Check if the pathname is valid. */
1557         if (!(path = valid_share_pathname( pathname )))
1558                 return WERR_OBJECT_PATH_INVALID;
1559
1560         /* Ensure share name, pathname and comment don't contain '"' characters. */
1561         string_replace(share_name, '"', ' ');
1562         string_replace(path, '"', ' ');
1563         string_replace(comment, '"', ' ');
1564
1565         DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1566                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1567
1568         /* Only call modify function if something changed. */
1569
1570         if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
1571                 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1572                         return WERR_ACCESS_DENIED;
1573
1574                 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1575                                 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1576
1577                 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1578                 if ((ret = smbrun(command, NULL)) != 0) {
1579                         DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1580                         return WERR_ACCESS_DENIED;
1581                 }
1582
1583                 /* Check if the new share pathname exist, if not return an error */
1584                 if (!exist_share_pathname(path)) {
1585                         DEBUG(1, ("_srv_net_share_set_info: change share command was ok but path (%s) has not been created!\n", path));
1586                         return WERR_OBJECT_PATH_INVALID;
1587                 }
1588
1589                 /* Tell everyone we updated smb.conf. */
1590                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1591
1592         } else {
1593                 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1594         }
1595
1596         /* Replace SD if changed. */
1597         if (psd) {
1598                 SEC_DESC *old_sd;
1599                 size_t sd_size;
1600
1601                 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1602
1603                 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1604                         if (!set_share_security(p->mem_ctx, share_name, psd))
1605                                 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1606                                         share_name ));
1607                 }
1608         }
1609
1610         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1611
1612         return WERR_OK;
1613 }
1614
1615 /*******************************************************************
1616  Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1617 ********************************************************************/
1618
1619 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1620 {
1621         struct current_user user;
1622         pstring command;
1623         fstring share_name;
1624         fstring comment;
1625         pstring pathname;
1626         int type;
1627         int snum;
1628         int ret;
1629         char *path;
1630         SEC_DESC *psd = NULL;
1631
1632         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1633
1634         r_u->parm_error = 0;
1635
1636         get_current_user(&user,p);
1637
1638         if (user.uid != sec_initial_uid()) {
1639                 DEBUG(10,("_srv_net_share_add: uid != sec_initial_uid(). Access denied.\n"));
1640                 return WERR_ACCESS_DENIED;
1641         }
1642
1643         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1644                 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1645                 return WERR_ACCESS_DENIED;
1646         }
1647
1648         switch (q_u->info_level) {
1649         case 0:
1650                 /* No path. Not enough info in a level 0 to do anything. */
1651                 return WERR_ACCESS_DENIED;
1652         case 1:
1653                 /* Not enough info in a level 1 to do anything. */
1654                 return WERR_ACCESS_DENIED;
1655         case 2:
1656                 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1657                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1658                 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1659                 type = q_u->info.share.info2.info_2.type;
1660                 break;
1661         case 501:
1662                 /* No path. Not enough info in a level 501 to do anything. */
1663                 return WERR_ACCESS_DENIED;
1664         case 502:
1665                 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1666                 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1667                 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1668                 type = q_u->info.share.info502.info_502.type;
1669                 psd = q_u->info.share.info502.info_502_str.sd;
1670                 map_generic_share_sd_bits(psd);
1671                 break;
1672
1673                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */ 
1674
1675         case 1004:
1676         case 1005:
1677         case 1006:
1678         case 1007:
1679                 return WERR_ACCESS_DENIED;
1680                 break;
1681         case 1501:
1682                 /* DFS only level. */
1683                 return WERR_ACCESS_DENIED;
1684         default:
1685                 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1686                 return WERR_UNKNOWN_LEVEL;
1687         }
1688
1689         if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1690                 return WERR_ACCESS_DENIED;
1691
1692         snum = find_service(share_name);
1693
1694         /* Share already exists. */
1695         if (snum >= 0)
1696                 return WERR_ALREADY_EXISTS;
1697
1698         /* We can only add disk shares. */
1699         if (type != STYPE_DISKTREE)
1700                 return WERR_ACCESS_DENIED;
1701                 
1702         /* Check if the pathname is valid. */
1703         if (!(path = valid_share_pathname( pathname )))
1704                 return WERR_OBJECT_PATH_INVALID;
1705
1706         /* Ensure share name, pathname and comment don't contain '"' characters. */
1707         string_replace(share_name, '"', ' ');
1708         string_replace(path, '"', ' ');
1709         string_replace(comment, '"', ' ');
1710
1711         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1712                         lp_add_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1713
1714         DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1715         if ((ret = smbrun(command, NULL)) != 0) {
1716                 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1717                 return WERR_ACCESS_DENIED;
1718         }
1719
1720         /* Check if the new share pathname exist, if not try to delete the
1721          * share and return an error */
1722         if (!exist_share_pathname(path)) {
1723                 DEBUG(1, ("_srv_net_share_add: add share command was ok but path (%s) has not been created!\n", path));
1724                 DEBUG(1, ("_srv_net_share_add: trying to rollback and delete the share\n"));
1725
1726                 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1727                         DEBUG(1, ("_srv_net_share_add: Error! delete share command is not defined! Please check share (%s) in the config file\n", share_name));
1728                         return WERR_OBJECT_PATH_INVALID;
1729                 }
1730
1731                 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1732                                 lp_delete_share_cmd(), dyn_CONFIGFILE, share_name);
1733
1734                 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1735                 if ((ret = smbrun(command, NULL)) != 0) {
1736                         DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1737                         DEBUG(1, ("_srv_net_share_add: Error! delete share command failed! Please check share (%s) in the config file\n", share_name));
1738                 }
1739
1740                 return WERR_OBJECT_PATH_INVALID;
1741         }
1742
1743         if (psd) {
1744                 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1745                         DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1746                 }
1747         }
1748
1749         /* Tell everyone we updated smb.conf. */
1750         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1751
1752         /*
1753          * We don't call reload_services() here, the message will
1754          * cause this to be done before the next packet is read
1755          * from the client. JRA.
1756          */
1757
1758         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1759
1760         return WERR_OK;
1761 }
1762
1763 /*******************************************************************
1764  Net share delete. Call "delete share command" with the share name as
1765  a parameter.
1766 ********************************************************************/
1767
1768 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1769 {
1770         struct current_user user;
1771         pstring command;
1772         fstring share_name;
1773         int ret;
1774         int snum;
1775
1776         DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1777
1778         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1779
1780         if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1781                 return WERR_ACCESS_DENIED;
1782
1783         snum = find_service(share_name);
1784
1785         if (snum < 0)
1786                 return WERR_NO_SUCH_SHARE;
1787
1788         /* No change to printer shares. */
1789         if (lp_print_ok(snum))
1790                 return WERR_ACCESS_DENIED;
1791
1792         get_current_user(&user,p);
1793
1794         if (user.uid != sec_initial_uid())
1795                 return WERR_ACCESS_DENIED;
1796
1797         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1798                 return WERR_ACCESS_DENIED;
1799
1800         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1801                         lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1802
1803         DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1804         if ((ret = smbrun(command, NULL)) != 0) {
1805                 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1806                 return WERR_ACCESS_DENIED;
1807         }
1808
1809         /* Delete the SD in the database. */
1810         delete_share_security(snum);
1811
1812         /* Tell everyone we updated smb.conf. */
1813         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1814
1815         lp_killservice(snum);
1816
1817         return WERR_OK;
1818 }
1819
1820 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1821 {
1822         DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1823
1824         return _srv_net_share_del(p, q_u, r_u);
1825 }
1826
1827 /*******************************************************************
1828 time of day
1829 ********************************************************************/
1830
1831 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1832 {
1833         TIME_OF_DAY_INFO *tod;
1834         struct tm *t;
1835         time_t unixdate = time(NULL);
1836
1837         tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1838         if (!tod)
1839                 return WERR_NOMEM;
1840
1841         ZERO_STRUCTP(tod);
1842  
1843         r_u->tod = tod;
1844         r_u->ptr_srv_tod = 0x1;
1845         r_u->status = WERR_OK;
1846
1847         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1848
1849         t = gmtime(&unixdate);
1850
1851         /* set up the */
1852         init_time_of_day_info(tod,
1853                               unixdate,
1854                               0,
1855                               t->tm_hour,
1856                               t->tm_min,
1857                               t->tm_sec,
1858                               0,
1859                               TimeDiff(unixdate)/60,
1860                               10000,
1861                               t->tm_mday,
1862                               t->tm_mon + 1,
1863                               1900+t->tm_year,
1864                               t->tm_wday);
1865         
1866         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1867
1868         return r_u->status;
1869 }
1870
1871 /***********************************************************************************
1872  Win9x NT tools get security descriptor.
1873 ***********************************************************************************/
1874
1875 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1876                         SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1877 {
1878         SEC_DESC *psd = NULL;
1879         size_t sd_size;
1880         DATA_BLOB null_pw;
1881         pstring filename;
1882         pstring qualname;
1883         files_struct *fsp = NULL;
1884         SMB_STRUCT_STAT st;
1885         BOOL bad_path;
1886         int access_mode;
1887         int action;
1888         NTSTATUS nt_status;
1889         struct current_user user;
1890         connection_struct *conn = NULL;
1891         BOOL became_user = False; 
1892
1893         ZERO_STRUCT(st);
1894
1895         r_u->status = WERR_OK;
1896
1897         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1898
1899         /* Null password is ok - we are already an authenticated user... */
1900         null_pw = data_blob(NULL, 0);
1901
1902         get_current_user(&user, p);
1903
1904         become_root();
1905         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1906         unbecome_root();
1907
1908         if (conn == NULL) {
1909                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1910                 r_u->status = ntstatus_to_werror(nt_status);
1911                 goto error_exit;
1912         }
1913
1914         if (!become_user(conn, conn->vuid)) {
1915                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1916                 r_u->status = WERR_ACCESS_DENIED;
1917                 goto error_exit;
1918         }
1919         became_user = True;
1920
1921         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1922         unix_convert(filename, conn, NULL, &bad_path, &st);
1923         fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1924                                 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1925
1926         if (!fsp) {
1927                 /* Perhaps it is a directory */
1928                 if (errno == EISDIR)
1929                         fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1930                                         (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1931
1932                 if (!fsp) {
1933                         DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1934                         r_u->status = WERR_ACCESS_DENIED;
1935                         goto error_exit;
1936                 }
1937         }
1938
1939         sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1940
1941         if (sd_size == 0) {
1942                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1943                 r_u->status = WERR_ACCESS_DENIED;
1944                 goto error_exit;
1945         }
1946
1947         r_u->ptr_response = 1;
1948         r_u->size_response = sd_size;
1949         r_u->ptr_secdesc = 1;
1950         r_u->size_secdesc = sd_size;
1951         r_u->sec_desc = psd;
1952
1953         psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1954
1955         close_file(fsp, True);
1956         unbecome_user();
1957         close_cnum(conn, user.vuid);
1958         return r_u->status;
1959
1960 error_exit:
1961
1962         if(fsp) {
1963                 close_file(fsp, True);
1964         }
1965
1966         if (became_user)
1967                 unbecome_user();
1968
1969         if (conn) 
1970                 close_cnum(conn, user.vuid);
1971
1972         return r_u->status;
1973 }
1974
1975 /***********************************************************************************
1976  Win9x NT tools set security descriptor.
1977 ***********************************************************************************/
1978
1979 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1980                                                                         SRV_R_NET_FILE_SET_SECDESC *r_u)
1981 {
1982         BOOL ret;
1983         pstring filename;
1984         pstring qualname;
1985         DATA_BLOB null_pw;
1986         files_struct *fsp = NULL;
1987         SMB_STRUCT_STAT st;
1988         BOOL bad_path;
1989         int access_mode;
1990         int action;
1991         NTSTATUS nt_status;
1992         struct current_user user;
1993         connection_struct *conn = NULL;
1994         BOOL became_user = False;
1995
1996         ZERO_STRUCT(st);
1997
1998         r_u->status = WERR_OK;
1999
2000         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2001
2002         /* Null password is ok - we are already an authenticated user... */
2003         null_pw = data_blob(NULL, 0);
2004
2005         get_current_user(&user, p);
2006
2007         become_root();
2008         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2009         unbecome_root();
2010
2011         if (conn == NULL) {
2012                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2013                 r_u->status = ntstatus_to_werror(nt_status);
2014                 goto error_exit;
2015         }
2016
2017         if (!become_user(conn, conn->vuid)) {
2018                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2019                 r_u->status = WERR_ACCESS_DENIED;
2020                 goto error_exit;
2021         }
2022         became_user = True;
2023
2024         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2025         unix_convert(filename, conn, NULL, &bad_path, &st);
2026
2027         fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
2028                         (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
2029
2030         if (!fsp) {
2031                 /* Perhaps it is a directory */
2032                 if (errno == EISDIR)
2033                         fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
2034                                                 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
2035
2036                 if (!fsp) {
2037                         DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2038                         r_u->status = WERR_ACCESS_DENIED;
2039                         goto error_exit;
2040                 }
2041         }
2042
2043         ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2044
2045         if (ret == False) {
2046                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2047                 r_u->status = WERR_ACCESS_DENIED;
2048                 goto error_exit;
2049         }
2050
2051         close_file(fsp, True);
2052         unbecome_user();
2053         close_cnum(conn, user.vuid);
2054         return r_u->status;
2055
2056 error_exit:
2057
2058         if(fsp) {
2059                 close_file(fsp, True);
2060         }
2061
2062         if (became_user)
2063                 unbecome_user();
2064
2065         if (conn) 
2066                 close_cnum(conn, user.vuid);
2067
2068         return r_u->status;
2069 }
2070
2071 /***********************************************************************************
2072  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2073  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2074  These disks would the disks listed by this function.
2075  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2076  "Nigel Williams" <nigel@veritas.com>.
2077 ***********************************************************************************/
2078
2079 static const char *server_disks[] = {"C:"};
2080
2081 static uint32 get_server_disk_count(void)
2082 {
2083         return sizeof(server_disks)/sizeof(server_disks[0]);
2084 }
2085
2086 static uint32 init_server_disk_enum(uint32 *resume)
2087 {
2088         uint32 server_disk_count = get_server_disk_count();
2089
2090         /*resume can be an offset into the list for now*/
2091
2092         if(*resume & 0x80000000)
2093                 *resume = 0;
2094
2095         if(*resume > server_disk_count)
2096                 *resume = server_disk_count;
2097
2098         return server_disk_count - *resume;
2099 }
2100
2101 static const char *next_server_disk_enum(uint32 *resume)
2102 {
2103         const char *disk;
2104
2105         if(init_server_disk_enum(resume) == 0)
2106                 return NULL;
2107
2108         disk = server_disks[*resume];
2109
2110         (*resume)++;
2111
2112         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2113
2114         return disk;
2115 }
2116
2117 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2118 {
2119         uint32 i;
2120         const char *disk_name;
2121         TALLOC_CTX *ctx = p->mem_ctx;
2122         uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2123
2124         r_u->status=WERR_OK;
2125
2126         r_u->total_entries = init_server_disk_enum(&resume);
2127
2128         r_u->disk_enum_ctr.unknown = 0; 
2129
2130         {
2131                 DISK_INFO *dinfo;
2132
2133                 int dinfo_size = MAX_SERVER_DISK_ENTRIES * sizeof(*dinfo);
2134           
2135                 if(!(dinfo =  talloc(ctx, dinfo_size))) {
2136                         return WERR_NOMEM;
2137                 }
2138
2139                 r_u->disk_enum_ctr.disk_info = dinfo;
2140         }
2141
2142         r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2143
2144         /*allow one DISK_INFO for null terminator*/
2145
2146         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2147
2148                 r_u->disk_enum_ctr.entries_read++;
2149
2150                 /*copy disk name into a unicode string*/
2151
2152                 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);    
2153         }
2154
2155         /* add a terminating null string.  Is this there if there is more data to come? */
2156
2157         r_u->disk_enum_ctr.entries_read++;
2158
2159         init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2160
2161         init_enum_hnd(&r_u->enum_hnd, resume);
2162
2163         return r_u->status;
2164 }
2165
2166 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2167 {
2168         int snum;
2169         fstring share_name;
2170
2171         r_u->status=WERR_OK;
2172
2173         switch(q_u->type) {
2174
2175         case 0x9:
2176
2177                 /*check if share name is ok*/
2178                 /*also check if we already have a share with this name*/
2179
2180                 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
2181                 snum = find_service(share_name);
2182
2183                 /* Share already exists. */
2184                 if (snum >= 0)
2185                         r_u->status = WERR_ALREADY_EXISTS;
2186                 break;
2187
2188         default:
2189                 /*unsupported type*/
2190                 r_u->status = WERR_UNKNOWN_LEVEL;
2191                 break;
2192         }
2193
2194         return r_u->status;
2195 }