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