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