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