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