Based orginally by work by Kai, this patch moves our NT_TOKEN generation into
[samba.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 extern pstring global_myname;
31
32 /*******************************************************************
33  Utility function to get the 'type' of a share from an snum.
34  ********************************************************************/
35 static uint32 get_share_type(int snum) 
36 {
37         char *net_name = lp_servicename(snum);
38         int len_net_name = strlen(net_name);
39         
40         /* work out the share type */
41         uint32 type = STYPE_DISKTREE;
42
43         if (lp_print_ok(snum))
44                 type = STYPE_PRINTQ;
45         if (strequal(lp_fstype(snum), "IPC"))
46                 type = STYPE_IPC;
47         if (net_name[len_net_name] == '$')
48                 type |= STYPE_HIDDEN;
49
50         return type;
51 }
52         
53 /*******************************************************************
54  Fill in a share info level 0 structure.
55  ********************************************************************/
56
57 static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum)
58 {
59         pstring net_name;
60
61         pstrcpy(net_name, lp_servicename(snum));
62
63         init_srv_share_info0(&sh0->info_0, net_name);
64         init_srv_share_info0_str(&sh0->info_0_str, net_name);
65 }
66
67 /*******************************************************************
68  Fill in a share info level 1 structure.
69  ********************************************************************/
70
71 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
72 {
73         pstring remark;
74
75         char *net_name = lp_servicename(snum);
76         pstrcpy(remark, lp_comment(snum));
77         standard_sub_conn(p->conn, remark,sizeof(remark));
78
79         init_srv_share_info1(&sh1->info_1, net_name, get_share_type(snum), remark);
80         init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
81 }
82
83 /*******************************************************************
84  Fill in a share info level 2 structure.
85  ********************************************************************/
86
87 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
88 {
89         pstring remark;
90         pstring path;
91         pstring passwd;
92
93         char *net_name = lp_servicename(snum);
94         pstrcpy(remark, lp_comment(snum));
95         standard_sub_conn(p->conn, remark,sizeof(remark));
96         pstrcpy(path, "C:");
97         pstrcat(path, lp_pathname(snum));
98
99         /*
100          * Change / to \\ so that win2k will see it as a valid path.  This was added to
101          * enable use of browsing in win2k add share dialog.
102          */ 
103
104         string_replace(path, '/', '\\');
105
106         pstrcpy(passwd, "");
107
108         init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd);
109         init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
110 }
111
112 /*******************************************************************
113  What to do when smb.conf is updated.
114  ********************************************************************/
115
116 static void smb_conf_updated(int msg_type, pid_t src, void *buf, size_t len)
117 {
118         DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
119         reload_services(False);
120 }
121
122 /*******************************************************************
123  Create the share security tdb.
124  ********************************************************************/
125
126 static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
127 #define SHARE_DATABASE_VERSION_V1 1
128 #define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
129
130 BOOL share_info_db_init(void)
131 {
132         static pid_t local_pid;
133         char *vstring = "INFO/version";
134         int32 vers_id;
135  
136         if (share_tdb && local_pid == sys_getpid())
137                 return True;
138         share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
139         if (!share_tdb) {
140                 DEBUG(0,("Failed to open share info database %s (%s)\n",
141                         lock_path("share_info.tdb"), strerror(errno) ));
142                 return False;
143         }
144  
145         local_pid = sys_getpid();
146  
147         /* handle a Samba upgrade */
148         tdb_lock_bystring(share_tdb, vstring);
149
150         /* Cope with byte-reversed older versions of the db. */
151         vers_id = tdb_fetch_int32(share_tdb, vstring);
152         if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
153                 /* Written on a bigendian machine with old fetch_int code. Save as le. */
154                 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
155                 vers_id = SHARE_DATABASE_VERSION_V2;
156         }
157
158         if (vers_id != SHARE_DATABASE_VERSION_V2) {
159                 tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
160                 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
161         }
162         tdb_unlock_bystring(share_tdb, vstring);
163
164         message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
165  
166         return True;
167 }
168
169 /*******************************************************************
170  Fake up a Everyone, full access as a default.
171  ********************************************************************/
172
173 static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
174 {
175         extern DOM_SID global_sid_World;
176         extern struct generic_mapping file_generic_mapping;
177         SEC_ACCESS sa;
178         SEC_ACE ace;
179         SEC_ACL *psa = NULL;
180         SEC_DESC *psd = NULL;
181         uint32 def_access = GENERIC_ALL_ACCESS;
182
183         se_map_generic(&def_access, &file_generic_mapping);
184
185         init_sec_access(&sa, GENERIC_ALL_ACCESS | def_access );
186         init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);
187
188         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
189                 psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, psize);
190         }
191
192         if (!psd) {
193                 DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
194                 return NULL;
195         }
196
197         return psd;
198 }
199
200 /*******************************************************************
201  Pull a security descriptor from the share tdb.
202  ********************************************************************/
203
204 static SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
205 {
206         prs_struct ps;
207         fstring key;
208         SEC_DESC *psd = NULL;
209
210         *psize = 0;
211
212         /* Fetch security descriptor from tdb */
213  
214         slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
215  
216         if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
217                 !sec_io_desc("get_share_security", &psd, &ps, 1)) {
218  
219                 DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
220  
221                 return get_share_security_default(ctx, snum, psize);
222         }
223
224         if (psd)
225                 *psize = sec_desc_size(psd);
226
227         prs_mem_free(&ps);
228         return psd;
229 }
230
231 /*******************************************************************
232  Store a security descriptor in the share db.
233  ********************************************************************/
234
235 static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd)
236 {
237         prs_struct ps;
238         TALLOC_CTX *mem_ctx = NULL;
239         fstring key;
240         BOOL ret = False;
241
242         mem_ctx = talloc_init();
243         if (mem_ctx == NULL)
244                 return False;
245
246         prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
247  
248         if (!sec_io_desc("share_security", &psd, &ps, 1))
249                 goto out;
250  
251         slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name);
252  
253         if (tdb_prs_store(share_tdb, key, &ps)==0) {
254                 ret = True;
255                 DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name ));
256         } else {
257                 DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", share_name ));
258         } 
259
260         /* Free malloc'ed memory */
261  
262 out:
263  
264         prs_mem_free(&ps);
265         if (mem_ctx)
266                 talloc_destroy(mem_ctx);
267         return ret;
268 }
269
270 /*******************************************************************
271  Delete a security descriptor.
272 ********************************************************************/
273
274 static BOOL delete_share_security(int snum)
275 {
276         TDB_DATA kbuf;
277         fstring key;
278
279         slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
280         kbuf.dptr = key;
281         kbuf.dsize = strlen(key)+1;
282
283         if (tdb_delete(share_tdb, kbuf) != 0) {
284                 DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n",
285                                 lp_servicename(snum) ));
286                 return False;
287         }
288
289         return True;
290 }
291
292 /*******************************************************************
293  Map any generic bits to file specific bits.
294 ********************************************************************/
295
296 void map_generic_share_sd_bits(SEC_DESC *psd)
297 {
298         extern struct generic_mapping file_generic_mapping;
299         int i;
300         SEC_ACL *ps_dacl = NULL;
301
302         if (!psd)
303                 return;
304
305         ps_dacl = psd->dacl;
306         if (!ps_dacl)
307                 return;
308
309         for (i = 0; i < ps_dacl->num_aces; i++) {
310                 SEC_ACE *psa = &ps_dacl->ace[i];
311                 uint32 orig_mask = psa->info.mask;
312
313                 se_map_generic(&psa->info.mask, &file_generic_mapping);
314                 psa->info.mask |= orig_mask;
315         }       
316 }
317
318 /*******************************************************************
319  Can this user access with share with the required permissions ?
320 ********************************************************************/
321
322 BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, uint32 desired_access)
323 {
324         uint32 granted;
325         NTSTATUS status;
326         TALLOC_CTX *mem_ctx = NULL;
327         SEC_DESC *psd = NULL;
328         size_t sd_size;
329         NT_USER_TOKEN *token = NULL;
330         BOOL ret = True;
331
332         mem_ctx = talloc_init();
333         if (mem_ctx == NULL)
334                 return False;
335
336         psd = get_share_security(mem_ctx, snum, &sd_size);
337
338         if (!psd)
339                 goto out;
340
341         if (conn->nt_user_token)
342                 token = conn->nt_user_token;
343         else 
344                 token = vuser->nt_user_token;
345
346         ret = se_access_check(psd, token, desired_access, &granted, &status);
347
348 out:
349
350         talloc_destroy(mem_ctx);
351
352         return ret;
353 }
354
355 /*******************************************************************
356  Fill in a share info level 501 structure.
357 ********************************************************************/
358
359 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
360 {
361         int len_net_name;
362         pstring remark;
363
364         char *net_name = lp_servicename(snum);
365         pstrcpy(remark, lp_comment(snum));
366         standard_sub_conn(p->conn, remark, sizeof(remark));
367
368         len_net_name = strlen(net_name);
369
370         init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
371         init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
372 }
373
374 /*******************************************************************
375  Fill in a share info level 502 structure.
376  ********************************************************************/
377
378 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
379 {
380         int len_net_name;
381         pstring net_name;
382         pstring remark;
383         pstring path;
384         pstring passwd;
385         SEC_DESC *sd;
386         size_t sd_size;
387         TALLOC_CTX *ctx = p->mem_ctx;
388
389
390         ZERO_STRUCTP(sh502);
391
392         pstrcpy(net_name, lp_servicename(snum));
393         pstrcpy(remark, lp_comment(snum));
394         standard_sub_conn(p->conn, remark,sizeof(remark));
395         pstrcpy(path, "C:");
396         pstrcat(path, lp_pathname(snum));
397
398         /*
399          * Change / to \\ so that win2k will see it as a valid path.  This was added to
400          * enable use of browsing in win2k add share dialog.
401          */ 
402
403         string_replace(path, '/', '\\');
404
405         pstrcpy(passwd, "");
406         len_net_name = strlen(net_name);
407
408         sd = get_share_security(ctx, snum, &sd_size);
409
410         init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
411         init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size);
412 }
413
414 /***************************************************************************
415  Fill in a share info level 1004 structure.
416  ***************************************************************************/
417
418 static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
419 {
420         pstring remark;
421
422         pstrcpy(remark, lp_comment(snum));
423         standard_sub_conn(p->conn, remark, sizeof(remark));
424
425         ZERO_STRUCTP(sh1004);
426   
427         init_srv_share_info1004(&sh1004->info_1004, remark);
428         init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
429 }
430
431 /***************************************************************************
432  Fill in a share info level 1005 structure.
433  ***************************************************************************/
434
435 static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum)
436 {
437         sh1005->dfs_root_flag = 0;
438
439         if(lp_host_msdfs() && lp_msdfs_root(snum))
440                 sh1005->dfs_root_flag = 3;
441 }
442 /***************************************************************************
443  Fill in a share info level 1006 structure.
444  ***************************************************************************/
445
446 static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
447 {
448         sh1006->max_uses = -1;
449 }
450
451 /***************************************************************************
452  Fill in a share info level 1007 structure.
453  ***************************************************************************/
454
455 static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
456 {
457         pstring alternate_directory_name = "";
458         uint32 flags = 0;
459
460         ZERO_STRUCTP(sh1007);
461   
462         init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name);
463         init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name);
464 }
465
466 /*******************************************************************
467  Fill in a share info level 1501 structure.
468  ********************************************************************/
469
470 static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
471 {
472         SEC_DESC *sd;
473         size_t sd_size;
474         TALLOC_CTX *ctx = p->mem_ctx;
475
476         ZERO_STRUCTP(sh1501);
477
478         sd = get_share_security(ctx, snum, &sd_size);
479
480         sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
481 }
482
483 /*******************************************************************
484  True if it ends in '$'.
485  ********************************************************************/
486
487 static BOOL is_hidden_share(int snum)
488 {
489         pstring net_name;
490
491         pstrcpy(net_name, lp_servicename(snum));
492         return (net_name[strlen(net_name)] == '$') ? 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                                 char *usr_name, 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         pstring saved_pathname;
1409         pstring unix_pathname;
1410         char *ptr;
1411         int ret;
1412
1413         /* Convert any '\' paths to '/' */
1414         unix_format(dos_pathname);
1415         unix_clean_name(dos_pathname);
1416
1417         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1418         ptr = dos_pathname;
1419         if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1420                 ptr += 2;
1421
1422         /* Only abolute paths allowed. */
1423         if (*ptr != '/')
1424                 return NULL;
1425
1426         /* Can we cd to it ? */
1427
1428         /* First save our current directory. */
1429         if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
1430                 return False;
1431
1432         pstrcpy(unix_pathname, ptr);
1433         
1434         ret = chdir(unix_pathname);
1435
1436         /* We *MUST* be able to chdir back. Abort if we can't. */
1437         if (chdir(saved_pathname) == -1)
1438                 smb_panic("valid_share_pathname: Unable to restore current directory.\n");
1439
1440         return (ret != -1) ? ptr : NULL;
1441 }
1442
1443 /*******************************************************************
1444  Net share set info. Modify share details.
1445 ********************************************************************/
1446
1447 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)
1448 {
1449         struct current_user user;
1450         pstring command;
1451         fstring share_name;
1452         fstring comment;
1453         pstring pathname;
1454         int type;
1455         int snum;
1456         int ret;
1457         char *ptr;
1458         SEC_DESC *psd = NULL;
1459
1460         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1461
1462         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1463
1464         r_u->parm_error = 0;
1465
1466         if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1467                 return WERR_ACCESS_DENIED;
1468
1469         snum = find_service(share_name);
1470
1471         /* Does this share exist ? */
1472         if (snum < 0)
1473                 return WERR_INVALID_NAME;
1474
1475         /* No change to printer shares. */
1476         if (lp_print_ok(snum))
1477                 return WERR_ACCESS_DENIED;
1478
1479         get_current_user(&user,p);
1480
1481         if (user.uid != sec_initial_uid())
1482                 return WERR_ACCESS_DENIED;
1483
1484         switch (q_u->info_level) {
1485         case 1:
1486                 fstrcpy(pathname, lp_pathname(snum));
1487                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1488                 type = q_u->info.share.info2.info_2.type;
1489                 psd = NULL;
1490                 break;
1491         case 2:
1492                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1493                 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1494                 type = q_u->info.share.info2.info_2.type;
1495                 psd = NULL;
1496                 break;
1497 #if 0
1498                 /* not supported on set but here for completeness */
1499         case 501:
1500                 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1501                 type = q_u->info.share.info501.info_501.type;
1502                 psd = NULL;
1503                 break;
1504 #endif
1505         case 502:
1506                 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1507                 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1508                 type = q_u->info.share.info502.info_502.type;
1509                 psd = q_u->info.share.info502.info_502_str.sd;
1510                 map_generic_share_sd_bits(psd);
1511                 break;
1512         case 1004:
1513                 fstrcpy(pathname, lp_pathname(snum));
1514                 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1515                 type = STYPE_DISKTREE;
1516                 break;
1517         case 1005:
1518         case 1006:
1519         case 1007:
1520                 return WERR_ACCESS_DENIED;
1521                 break;
1522         case 1501:
1523                 fstrcpy(pathname, lp_pathname(snum));
1524                 fstrcpy(comment, lp_comment(snum));
1525                 psd = q_u->info.share.info1501.sdb->sec;
1526                 map_generic_share_sd_bits(psd);
1527                 type = STYPE_DISKTREE;
1528                 break;
1529         default:
1530                 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1531                 return WERR_UNKNOWN_LEVEL;
1532         }
1533
1534         /* We can only modify disk shares. */
1535         if (type != STYPE_DISKTREE)
1536                 return WERR_ACCESS_DENIED;
1537                 
1538         /* Check if the pathname is valid. */
1539         if (!(ptr = valid_share_pathname( pathname )))
1540                 return WERR_OBJECT_PATH_INVALID;
1541
1542         /* Ensure share name, pathname and comment don't contain '"' characters. */
1543         string_replace(share_name, '"', ' ');
1544         string_replace(ptr, '"', ' ');
1545         string_replace(comment, '"', ' ');
1546
1547         DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1548                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1549
1550         /* Only call modify function if something changed. */
1551
1552         if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
1553                 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1554                         return WERR_ACCESS_DENIED;
1555
1556                 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1557                                 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1558
1559                 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1560                 if ((ret = smbrun(command, NULL)) != 0) {
1561                         DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1562                         return WERR_ACCESS_DENIED;
1563                 }
1564
1565                 /* Tell everyone we updated smb.conf. */
1566                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1567
1568         } else {
1569                 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1570         }
1571
1572         /* Replace SD if changed. */
1573         if (psd) {
1574                 SEC_DESC *old_sd;
1575                 size_t sd_size;
1576
1577                 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1578
1579                 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1580                         if (!set_share_security(p->mem_ctx, share_name, psd))
1581                                 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1582                                         share_name ));
1583                 }
1584         }
1585
1586         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1587
1588         return WERR_OK;
1589 }
1590
1591 /*******************************************************************
1592  Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1593 ********************************************************************/
1594
1595 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1596 {
1597         struct current_user user;
1598         pstring command;
1599         fstring share_name;
1600         fstring comment;
1601         pstring pathname;
1602         int type;
1603         int snum;
1604         int ret;
1605         char *ptr;
1606         SEC_DESC *psd = NULL;
1607
1608         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1609
1610         r_u->parm_error = 0;
1611
1612         get_current_user(&user,p);
1613
1614         if (user.uid != sec_initial_uid()) {
1615                 DEBUG(10,("_srv_net_share_add: uid != sec_initial_uid(). Access denied.\n"));
1616                 return WERR_ACCESS_DENIED;
1617         }
1618
1619         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1620                 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1621                 return WERR_ACCESS_DENIED;
1622         }
1623
1624         switch (q_u->info_level) {
1625         case 0:
1626                 /* No path. Not enough info in a level 0 to do anything. */
1627                 return WERR_ACCESS_DENIED;
1628         case 1:
1629                 /* Not enough info in a level 1 to do anything. */
1630                 return WERR_ACCESS_DENIED;
1631         case 2:
1632                 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1633                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1634                 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1635                 type = q_u->info.share.info2.info_2.type;
1636                 break;
1637         case 501:
1638                 /* No path. Not enough info in a level 501 to do anything. */
1639                 return WERR_ACCESS_DENIED;
1640         case 502:
1641                 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1642                 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1643                 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1644                 type = q_u->info.share.info502.info_502.type;
1645                 psd = q_u->info.share.info502.info_502_str.sd;
1646                 map_generic_share_sd_bits(psd);
1647                 break;
1648
1649                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */ 
1650
1651         case 1004:
1652         case 1005:
1653         case 1006:
1654         case 1007:
1655                 return WERR_ACCESS_DENIED;
1656                 break;
1657         case 1501:
1658                 /* DFS only level. */
1659                 return WERR_ACCESS_DENIED;
1660         default:
1661                 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1662                 return WERR_UNKNOWN_LEVEL;
1663         }
1664
1665         if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1666                 return WERR_ACCESS_DENIED;
1667
1668         snum = find_service(share_name);
1669
1670         /* Share already exists. */
1671         if (snum >= 0)
1672                 return WERR_ALREADY_EXISTS;
1673
1674         /* We can only add disk shares. */
1675         if (type != STYPE_DISKTREE)
1676                 return WERR_ACCESS_DENIED;
1677                 
1678         /* Check if the pathname is valid. */
1679         if (!(ptr = valid_share_pathname( pathname )))
1680                 return WERR_OBJECT_PATH_INVALID;
1681
1682         /* Ensure share name, pathname and comment don't contain '"' characters. */
1683         string_replace(share_name, '"', ' ');
1684         string_replace(ptr, '"', ' ');
1685         string_replace(comment, '"', ' ');
1686
1687         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1688                         lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1689
1690         DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1691         if ((ret = smbrun(command, NULL)) != 0) {
1692                 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1693                 return WERR_ACCESS_DENIED;
1694         }
1695
1696         if (psd) {
1697                 if (!set_share_security(p->mem_ctx, share_name, psd))
1698                         DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
1699                                 share_name ));
1700         }
1701
1702         /* Tell everyone we updated smb.conf. */
1703         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1704
1705         /*
1706          * We don't call reload_services() here, the message will
1707          * cause this to be done before the next packet is read
1708          * from the client. JRA.
1709          */
1710
1711         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1712
1713         return WERR_OK;
1714 }
1715
1716 /*******************************************************************
1717  Net share delete. Call "delete share command" with the share name as
1718  a parameter.
1719 ********************************************************************/
1720
1721 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1722 {
1723         struct current_user user;
1724         pstring command;
1725         fstring share_name;
1726         int ret;
1727         int snum;
1728
1729         DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1730
1731         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1732
1733         if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1734                 return WERR_ACCESS_DENIED;
1735
1736         snum = find_service(share_name);
1737
1738         if (snum < 0)
1739                 return WERR_NO_SUCH_SHARE;
1740
1741         /* No change to printer shares. */
1742         if (lp_print_ok(snum))
1743                 return WERR_ACCESS_DENIED;
1744
1745         get_current_user(&user,p);
1746
1747         if (user.uid != sec_initial_uid())
1748                 return WERR_ACCESS_DENIED;
1749
1750         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1751                 return WERR_ACCESS_DENIED;
1752
1753         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1754                         lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1755
1756         DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1757         if ((ret = smbrun(command, NULL)) != 0) {
1758                 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1759                 return WERR_ACCESS_DENIED;
1760         }
1761
1762         /* Delete the SD in the database. */
1763         delete_share_security(snum);
1764
1765         /* Tell everyone we updated smb.conf. */
1766         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1767
1768         lp_killservice(snum);
1769
1770         return WERR_OK;
1771 }
1772
1773 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1774 {
1775         DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1776
1777         return _srv_net_share_del(p, q_u, r_u);
1778 }
1779
1780 /*******************************************************************
1781 time of day
1782 ********************************************************************/
1783
1784 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1785 {
1786         TIME_OF_DAY_INFO *tod;
1787         struct tm *t;
1788         time_t unixdate = time(NULL);
1789
1790         tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1791         if (!tod)
1792                 return WERR_NOMEM;
1793
1794         ZERO_STRUCTP(tod);
1795  
1796         r_u->tod = tod;
1797         r_u->ptr_srv_tod = 0x1;
1798         r_u->status = WERR_OK;
1799
1800         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1801
1802         t = gmtime(&unixdate);
1803
1804         /* set up the */
1805         init_time_of_day_info(tod,
1806                               unixdate,
1807                               0,
1808                               t->tm_hour,
1809                               t->tm_min,
1810                               t->tm_sec,
1811                               0,
1812                               TimeDiff(unixdate)/60,
1813                               10000,
1814                               t->tm_mday,
1815                               t->tm_mon + 1,
1816                               1900+t->tm_year,
1817                               t->tm_wday);
1818         
1819         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1820
1821         return r_u->status;
1822 }
1823
1824 /***********************************************************************************
1825  Win9x NT tools get security descriptor.
1826 ***********************************************************************************/
1827
1828 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1829                         SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1830 {
1831         SEC_DESC *psd = NULL;
1832         size_t sd_size;
1833         DATA_BLOB null_pw;
1834         pstring filename;
1835         pstring qualname;
1836         files_struct *fsp = NULL;
1837         SMB_STRUCT_STAT st;
1838         BOOL bad_path;
1839         int access_mode;
1840         int action;
1841         NTSTATUS nt_status;
1842         struct current_user user;
1843         connection_struct *conn = NULL;
1844         BOOL became_user = False; 
1845
1846         ZERO_STRUCT(st);
1847
1848         r_u->status = WERR_OK;
1849
1850         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1851
1852         /* Null password is ok - we are already an authenticated user... */
1853         null_pw = data_blob(NULL, 0);
1854
1855         get_current_user(&user, p);
1856
1857         become_root();
1858         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1859         unbecome_root();
1860
1861         if (conn == NULL) {
1862                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1863                 r_u->status = ntstatus_to_werror(nt_status);
1864                 goto error_exit;
1865         }
1866
1867         if (!become_user(conn, conn->vuid)) {
1868                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1869                 r_u->status = WERR_ACCESS_DENIED;
1870                 goto error_exit;
1871         }
1872     became_user = True;
1873
1874         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1875         unix_convert(filename, conn, NULL, &bad_path, &st);
1876         fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1877                                 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1878
1879         if (!fsp) {
1880                 /* Perhaps it is a directory */
1881                 if (errno == EISDIR)
1882                         fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1883                                         (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1884
1885                 if (!fsp) {
1886                         DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1887                         r_u->status = WERR_ACCESS_DENIED;
1888                         goto error_exit;
1889                 }
1890         }
1891
1892         sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd);
1893
1894         if (sd_size == 0) {
1895                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1896                 r_u->status = WERR_ACCESS_DENIED;
1897                 goto error_exit;
1898         }
1899
1900         r_u->ptr_response = 1;
1901         r_u->size_response = sd_size;
1902         r_u->ptr_secdesc = 1;
1903         r_u->size_secdesc = sd_size;
1904         r_u->sec_desc = psd;
1905
1906         psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1907
1908         close_file(fsp, True);
1909         unbecome_user();
1910         close_cnum(conn, user.vuid);
1911         return r_u->status;
1912
1913 error_exit:
1914
1915         if(fsp) {
1916                 close_file(fsp, True);
1917         }
1918
1919         if (became_user)
1920                 unbecome_user();
1921
1922         if (conn) 
1923                 close_cnum(conn, user.vuid);
1924
1925         return r_u->status;
1926 }
1927
1928 /***********************************************************************************
1929  Win9x NT tools set security descriptor.
1930 ***********************************************************************************/
1931
1932 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1933                                                                         SRV_R_NET_FILE_SET_SECDESC *r_u)
1934 {
1935         BOOL ret;
1936         pstring filename;
1937         pstring qualname;
1938         DATA_BLOB null_pw;
1939         files_struct *fsp = NULL;
1940         SMB_STRUCT_STAT st;
1941         BOOL bad_path;
1942         int access_mode;
1943         int action;
1944         NTSTATUS nt_status;
1945         struct current_user user;
1946         connection_struct *conn = NULL;
1947         BOOL became_user = False;
1948
1949         ZERO_STRUCT(st);
1950
1951         r_u->status = WERR_OK;
1952
1953         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1954
1955         /* Null password is ok - we are already an authenticated user... */
1956         null_pw = data_blob(NULL, 0);
1957
1958         get_current_user(&user, p);
1959
1960         become_root();
1961         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1962         unbecome_root();
1963
1964         if (conn == NULL) {
1965                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
1966                 r_u->status = ntstatus_to_werror(nt_status);
1967                 goto error_exit;
1968         }
1969
1970         if (!become_user(conn, conn->vuid)) {
1971                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1972                 r_u->status = WERR_ACCESS_DENIED;
1973                 goto error_exit;
1974         }
1975         became_user = True;
1976
1977         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1978         unix_convert(filename, conn, NULL, &bad_path, &st);
1979
1980         fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
1981                         (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1982
1983         if (!fsp) {
1984                 /* Perhaps it is a directory */
1985                 if (errno == EISDIR)
1986                         fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
1987                                                 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1988
1989                 if (!fsp) {
1990                         DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
1991                         r_u->status = WERR_ACCESS_DENIED;
1992                         goto error_exit;
1993                 }
1994         }
1995
1996         ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
1997
1998         if (ret == False) {
1999                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2000                 r_u->status = WERR_ACCESS_DENIED;
2001                 goto error_exit;
2002         }
2003
2004         close_file(fsp, True);
2005         unbecome_user();
2006         close_cnum(conn, user.vuid);
2007         return r_u->status;
2008
2009 error_exit:
2010
2011         if(fsp) {
2012                 close_file(fsp, True);
2013         }
2014
2015         if (became_user)
2016                 unbecome_user();
2017
2018         if (conn) 
2019                 close_cnum(conn, user.vuid);
2020
2021         return r_u->status;
2022 }
2023
2024 /***********************************************************************************
2025  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2026  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2027  These disks would the disks listed by this function.
2028  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2029  "Nigel Williams" <nigel@veritas.com>.
2030 ***********************************************************************************/
2031
2032 static const char *server_disks[] = {"C:"};
2033
2034 static uint32 get_server_disk_count(void)
2035 {
2036         return sizeof(server_disks)/sizeof(server_disks[0]);
2037 }
2038
2039 static uint32 init_server_disk_enum(uint32 *resume)
2040 {
2041         uint32 server_disk_count = get_server_disk_count();
2042
2043         /*resume can be an offset into the list for now*/
2044
2045         if(*resume & 0x80000000)
2046                 *resume = 0;
2047
2048         if(*resume > server_disk_count)
2049                 *resume = server_disk_count;
2050
2051         return server_disk_count - *resume;
2052 }
2053
2054 static const char *next_server_disk_enum(uint32 *resume)
2055 {
2056         const char *disk;
2057
2058         if(init_server_disk_enum(resume) == 0)
2059                 return NULL;
2060
2061         disk = server_disks[*resume];
2062
2063         (*resume)++;
2064
2065         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2066
2067         return disk;
2068 }
2069
2070 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2071 {
2072         uint32 i;
2073         const char *disk_name;
2074         TALLOC_CTX *ctx = p->mem_ctx;
2075         uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2076
2077         r_u->status=WERR_OK;
2078
2079         r_u->total_entries = init_server_disk_enum(&resume);
2080
2081         r_u->disk_enum_ctr.unknown = 0; 
2082
2083         {
2084                 DISK_INFO *dinfo;
2085
2086                 int dinfo_size = MAX_SERVER_DISK_ENTRIES * sizeof(*dinfo);
2087           
2088                 if(!(dinfo =  talloc(ctx, dinfo_size))) {
2089                         return WERR_NOMEM;
2090                 }
2091
2092                 r_u->disk_enum_ctr.disk_info = dinfo;
2093         }
2094
2095         r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2096
2097         /*allow one DISK_INFO for null terminator*/
2098
2099         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2100
2101                 r_u->disk_enum_ctr.entries_read++;
2102
2103                 /*copy disk name into a unicode string*/
2104
2105                 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);    
2106         }
2107
2108         /* add a terminating null string.  Is this there if there is more data to come? */
2109
2110         r_u->disk_enum_ctr.entries_read++;
2111
2112         init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2113
2114         init_enum_hnd(&r_u->enum_hnd, resume);
2115
2116         return r_u->status;
2117 }
2118
2119 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2120 {
2121         int snum;
2122         fstring share_name;
2123
2124         r_u->status=WERR_OK;
2125
2126         switch(q_u->type) {
2127
2128         case 0x9:
2129
2130                 /*check if share name is ok*/
2131                 /*also check if we already have a share with this name*/
2132
2133                 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
2134                 snum = find_service(share_name);
2135
2136                 /* Share already exists. */
2137                 if (snum >= 0)
2138                         r_u->status = WERR_ALREADY_EXISTS;
2139                 break;
2140
2141         default:
2142                 /*unsupported type*/
2143                 r_u->status = WERR_UNKNOWN_LEVEL;
2144                 break;
2145         }
2146
2147         return r_u->status;
2148 }