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