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