Add an output parameter to message_send_all that says how many
[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,
1333                                  0, False, NULL);
1334
1335         } else {
1336                 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1337         }
1338
1339         /* Replace SD if changed. */
1340         if (psd) {
1341                 SEC_DESC *old_sd;
1342                 size_t sd_size;
1343
1344                 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1345
1346                 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1347                         if (!set_share_security(p->mem_ctx, share_name, psd))
1348                                 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1349                                         share_name ));
1350                 }
1351         }
1352
1353         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1354
1355         return NT_STATUS_OK;
1356 }
1357
1358 /*******************************************************************
1359  Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1360 ********************************************************************/
1361
1362 NTSTATUS _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1363 {
1364         struct current_user user;
1365         pstring command;
1366         fstring share_name;
1367         fstring comment;
1368         pstring pathname;
1369         int type;
1370         int snum;
1371         int ret;
1372         char *ptr;
1373         SEC_DESC *psd = NULL;
1374
1375         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1376
1377         r_u->switch_value = 0;
1378
1379         get_current_user(&user,p);
1380
1381         if (user.uid != 0) {
1382                 DEBUG(10,("_srv_net_share_add: uid != 0. Access denied.\n"));
1383                 return NT_STATUS_ACCESS_DENIED;
1384         }
1385
1386         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1387                 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1388                 return NT_STATUS_ACCESS_DENIED;
1389         }
1390
1391         switch (q_u->info_level) {
1392         case 1:
1393                 /* Not enough info in a level 1 to do anything. */
1394                 return NT_STATUS_ACCESS_DENIED;
1395         case 2:
1396                 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1397                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1398                 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1399                 type = q_u->info.share.info2.info_2.type;
1400                 break;
1401         case 502:
1402                 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1403                 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1404                 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1405                 type = q_u->info.share.info502.info_502.type;
1406                 psd = q_u->info.share.info502.info_502_str.sd;
1407                 map_generic_share_sd_bits(psd);
1408                 break;
1409         case 1005:
1410                 /* DFS only level. */
1411                 return NT_STATUS_ACCESS_DENIED;
1412         default:
1413                 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1414                 return NT_STATUS_INVALID_INFO_CLASS;
1415         }
1416
1417         if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1418                 return NT_STATUS_ACCESS_DENIED;
1419
1420         snum = find_service(share_name);
1421
1422         /* Share already exists. */
1423         if (snum >= 0)
1424                 return NT_STATUS_OBJECT_NAME_COLLISION;
1425
1426         /* We can only add disk shares. */
1427         if (type != STYPE_DISKTREE)
1428                 return NT_STATUS_ACCESS_DENIED;
1429                 
1430         /* Check if the pathname is valid. */
1431         if (!(ptr = valid_share_pathname( pathname )))
1432                 return NT_STATUS_OBJECT_PATH_INVALID;
1433
1434         /* Ensure share name, pathname and comment don't contain '"' characters. */
1435         string_replace(share_name, '"', ' ');
1436         string_replace(ptr, '"', ' ');
1437         string_replace(comment, '"', ' ');
1438
1439         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1440                         lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
1441
1442         DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1443         if ((ret = smbrun(command, NULL)) != 0) {
1444                 DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1445                 return NT_STATUS_ACCESS_DENIED;
1446         }
1447
1448         if (psd) {
1449                 if (!set_share_security(p->mem_ctx, share_name, psd))
1450                         DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
1451                                 share_name ));
1452         }
1453
1454         /* Tell everyone we updated smb.conf. */
1455         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False,
1456                          NULL);
1457
1458         /*
1459          * We don't call reload_services() here, the message will
1460          * cause this to be done before the next packet is read
1461          * from the client. JRA.
1462          */
1463
1464         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1465
1466         return NT_STATUS_OK;
1467 }
1468
1469 /*******************************************************************
1470  Net share delete. Call "delete share command" with the share name as
1471  a parameter.
1472 ********************************************************************/
1473
1474 NTSTATUS _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1475 {
1476         struct current_user user;
1477         pstring command;
1478         fstring share_name;
1479         int ret;
1480         int snum;
1481
1482         DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1483
1484         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1485
1486         if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1487                 return NT_STATUS_ACCESS_DENIED;
1488
1489         snum = find_service(share_name);
1490
1491         if (snum < 0)
1492                 return NT_STATUS_BAD_NETWORK_NAME;
1493
1494         /* No change to printer shares. */
1495         if (lp_print_ok(snum))
1496                 return NT_STATUS_ACCESS_DENIED;
1497
1498         get_current_user(&user,p);
1499
1500         if (user.uid != 0)
1501                 return NT_STATUS_ACCESS_DENIED;
1502
1503         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1504                 return NT_STATUS_ACCESS_DENIED;
1505
1506         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1507                         lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1508
1509         DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1510         if ((ret = smbrun(command, NULL)) != 0) {
1511                 DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1512                 return NT_STATUS_ACCESS_DENIED;
1513         }
1514
1515         /* Delete the SD in the database. */
1516         delete_share_security(snum);
1517
1518         /* Tell everyone we updated smb.conf. */
1519         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False,
1520                          NULL);
1521
1522         lp_killservice(snum);
1523
1524         return NT_STATUS_OK;
1525 }
1526
1527 /*******************************************************************
1528 time of day
1529 ********************************************************************/
1530
1531 NTSTATUS _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1532 {
1533         TIME_OF_DAY_INFO *tod;
1534         struct tm *t;
1535         time_t unixdate = time(NULL);
1536
1537         tod = (TIME_OF_DAY_INFO *)talloc(p->mem_ctx, sizeof(TIME_OF_DAY_INFO));
1538         if (!tod)
1539                 return NT_STATUS_NO_MEMORY;
1540
1541         ZERO_STRUCTP(tod);
1542  
1543         r_u->tod = tod;
1544         r_u->ptr_srv_tod = 0x1;
1545         r_u->status = NT_STATUS_OK;
1546
1547         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1548
1549         t = gmtime(&unixdate);
1550
1551         /* set up the */
1552         init_time_of_day_info(tod,
1553                               unixdate,
1554                               0,
1555                               t->tm_hour,
1556                               t->tm_min,
1557                               t->tm_sec,
1558                               0,
1559                               TimeDiff(unixdate)/60,
1560                               10000,
1561                               t->tm_mday,
1562                               t->tm_mon + 1,
1563                               1900+t->tm_year,
1564                               t->tm_wday);
1565         
1566         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1567
1568         return r_u->status;
1569 }
1570
1571 /***********************************************************************************
1572  Win9x NT tools get security descriptor.
1573 ***********************************************************************************/
1574
1575 NTSTATUS _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1576                         SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1577 {
1578         SEC_DESC *psd = NULL;
1579         size_t sd_size;
1580         DATA_BLOB null_pw;
1581         pstring filename;
1582         pstring qualname;
1583         files_struct *fsp = NULL;
1584         SMB_STRUCT_STAT st;
1585         BOOL bad_path;
1586         int access_mode;
1587         int action;
1588         NTSTATUS nt_status;
1589         struct current_user user;
1590         connection_struct *conn = NULL;
1591         BOOL became_user = False;
1592
1593         ZERO_STRUCT(st);
1594
1595         r_u->status = NT_STATUS_OK;
1596
1597         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1598
1599         /* Null password is ok - we are already an authenticated user... */
1600         null_pw = data_blob(NULL, 0);
1601
1602         get_current_user(&user, p);     
1603         
1604         become_root();
1605         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1606         unbecome_root();
1607
1608         if (conn == NULL) {
1609                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1610                 r_u->status = nt_status;
1611                 goto error_exit;
1612         }
1613
1614         if (!become_user(conn, conn->vuid)) {
1615                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1616                 r_u->status = NT_STATUS_ACCESS_DENIED;
1617                 goto error_exit;
1618         }
1619         became_user = True;
1620
1621         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1622         unix_convert(filename, conn, NULL, &bad_path, &st);
1623
1624         fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
1625                                (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1626
1627         if (!fsp) {
1628                 /* Perhaps it is a directory */
1629                 if (errno == EISDIR)
1630                         fsp = open_directory(conn, filename, &st,0,
1631                                              (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1632
1633                 if (!fsp) {
1634                         DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
1635                         r_u->status = NT_STATUS_ACCESS_DENIED;
1636                         goto error_exit;
1637                 }
1638         }
1639
1640         sd_size = conn->vfs_ops.get_nt_acl(fsp, fsp->fsp_name, &psd);
1641
1642         if (sd_size == 0) {
1643                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
1644                 r_u->status = NT_STATUS_ACCESS_DENIED;
1645                 goto error_exit;
1646         }
1647
1648         r_u->ptr_response = 1;
1649         r_u->size_response = sd_size;
1650         r_u->ptr_secdesc = 1;
1651         r_u->size_secdesc = sd_size;
1652         r_u->sec_desc = psd;
1653
1654         psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1655
1656         close_file(fsp, True);
1657         unbecome_user();
1658         close_cnum(conn, user.vuid);
1659         return r_u->status;
1660
1661   error_exit:
1662
1663         if(fsp) {
1664                 close_file(fsp, True);
1665         }
1666
1667         if (became_user)
1668                 unbecome_user();
1669
1670         if (conn) 
1671                 close_cnum(conn, user.vuid);
1672
1673         return r_u->status;
1674 }
1675
1676 /***********************************************************************************
1677  Win9x NT tools set security descriptor.
1678 ***********************************************************************************/
1679
1680 NTSTATUS _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
1681                                                                         SRV_R_NET_FILE_SET_SECDESC *r_u)
1682 {
1683         BOOL ret;
1684         DATA_BLOB null_pw;
1685         pstring filename;
1686         pstring qualname;
1687         files_struct *fsp = NULL;
1688         SMB_STRUCT_STAT st;
1689         BOOL bad_path;
1690         int access_mode;
1691         int action;
1692         NTSTATUS nt_status;
1693         struct current_user user;
1694         connection_struct *conn = NULL;
1695         BOOL became_user = False;
1696
1697         ZERO_STRUCT(st);
1698
1699         r_u->status = NT_STATUS_OK;
1700
1701         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1702
1703         /* Null password is ok - we are already an authenticated user... */
1704         null_pw = data_blob(NULL, 0);
1705
1706         get_current_user(&user, p);     
1707         
1708         become_root();
1709         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1710         unbecome_root();
1711
1712         if (conn == NULL) {
1713                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
1714                 r_u->status = nt_status;
1715                 goto error_exit;
1716         }
1717
1718         if (!become_user(conn, conn->vuid)) {
1719                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1720                 r_u->status = NT_STATUS_ACCESS_DENIED;
1721                 goto error_exit;
1722         }
1723         became_user = True;
1724
1725         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1726         unix_convert(filename, conn, NULL, &bad_path, &st);
1727
1728         fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDWR),
1729                                (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &action);
1730
1731         if (!fsp) {
1732                 /* Perhaps it is a directory */
1733                 if (errno == EISDIR)
1734                         fsp = open_directory(conn, filename, &st,0,
1735                                              (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
1736
1737                 if (!fsp) {
1738                         DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
1739                         r_u->status = NT_STATUS_ACCESS_DENIED;
1740                         goto error_exit;
1741                 }
1742         }
1743
1744         ret = conn->vfs_ops.set_nt_acl(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
1745
1746         if (ret == False) {
1747                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
1748                 r_u->status = NT_STATUS_ACCESS_DENIED;
1749                 goto error_exit;
1750         }
1751
1752         close_file(fsp, True);
1753         unbecome_user();
1754         close_cnum(conn, user.vuid);
1755         return r_u->status;
1756
1757   error_exit:
1758
1759         if(fsp) {
1760                 close_file(fsp, True);
1761         }
1762
1763         if (became_user)
1764                 unbecome_user();
1765
1766         if (conn) 
1767                 close_cnum(conn, user.vuid);
1768
1769         return r_u->status;
1770 }
1771
1772 /***********************************************************************************
1773  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
1774  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
1775  These disks would the disks listed by this function.
1776  Users could then create shares relative to these disks.  Watch out for moving these disks around.
1777  "Nigel Williams" <nigel@veritas.com>.
1778 ***********************************************************************************/
1779
1780 const char *server_disks[] = {"C:"};
1781
1782 static uint32 get_server_disk_count(void)
1783 {
1784         return sizeof(server_disks)/sizeof(server_disks[0]);
1785 }
1786
1787 static uint32 init_server_disk_enum(uint32 *resume)
1788 {
1789         uint32 server_disk_count = get_server_disk_count();
1790
1791         /*resume can be an offset into the list for now*/
1792
1793         if(*resume & 0x80000000)
1794                 *resume = 0;
1795
1796         if(*resume > server_disk_count)
1797                 *resume = server_disk_count;
1798
1799         return server_disk_count - *resume;
1800 }
1801
1802 static const char *next_server_disk_enum(uint32 *resume)
1803 {
1804         const char *disk;
1805
1806         if(init_server_disk_enum(resume) == 0)
1807                 return NULL;
1808
1809         disk = server_disks[*resume];
1810
1811         (*resume)++;
1812
1813         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
1814
1815         return disk;
1816 }
1817
1818 NTSTATUS _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
1819 {
1820         uint32 i;
1821         const char *disk_name;
1822         uint32 resume=get_enum_hnd(&q_u->enum_hnd);
1823
1824         r_u->status=NT_STATUS_OK;
1825
1826         r_u->total_entries = init_server_disk_enum(&resume);
1827
1828         r_u->disk_enum_ctr.unknown = 0; 
1829
1830         r_u->disk_enum_ctr.disk_info_ptr = (uint32) r_u->disk_enum_ctr.disk_info;
1831
1832         /*allow one DISK_INFO for null terminator*/
1833
1834         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
1835
1836                 r_u->disk_enum_ctr.entries_read++;
1837
1838                 /*copy disk name into a unicode string*/
1839
1840                 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);    
1841         }
1842
1843         /*add a terminating null string.  Is this there if there is more data to come?*/
1844
1845         r_u->disk_enum_ctr.entries_read++;
1846
1847         init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
1848
1849         init_enum_hnd(&r_u->enum_hnd, resume);
1850
1851         return r_u->status;
1852 }
1853
1854 NTSTATUS _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
1855 {
1856         int snum;
1857         fstring share_name;
1858
1859         r_u->status=NT_STATUS_OK;
1860
1861         switch(q_u->type) {
1862
1863         case 0x9:
1864
1865                 /*check if share name is ok*/
1866                 /*also check if we already have a share with this name*/
1867
1868                 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
1869                 snum = find_service(share_name);
1870
1871                 /* Share already exists. */
1872                 if (snum >= 0)
1873                         r_u->status = NT_STATUS_OBJECT_NAME_INVALID;
1874                 break;
1875
1876         default:
1877                 /*unsupported type*/
1878                 r_u->status = NT_STATUS_INVALID_LEVEL;
1879                 break;
1880         }
1881
1882         return r_u->status;
1883 }