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