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