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