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