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