r6942: * merging the registry changes back to the 3.0 tree
[ira/wip.git] / source3 / 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 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 absolute 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$") 
1529                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1530                 || strequal(share_name,"global") )
1531         {
1532                 return WERR_ACCESS_DENIED;
1533         }
1534
1535         snum = find_service(share_name);
1536
1537         /* Does this share exist ? */
1538         if (snum < 0)
1539                 return WERR_INVALID_NAME;
1540
1541         /* No change to printer shares. */
1542         if (lp_print_ok(snum))
1543                 return WERR_ACCESS_DENIED;
1544
1545         get_current_user(&user,p);
1546
1547         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1548         
1549         /* fail out now if you are not root and not a disk op */
1550         
1551         if ( user.uid != sec_initial_uid() && !is_disk_op )
1552                 return WERR_ACCESS_DENIED;
1553
1554         switch (q_u->info_level) {
1555         case 1:
1556                 pstrcpy(pathname, lp_pathname(snum));
1557                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1558                 type = q_u->info.share.info2.info_2.type;
1559                 psd = NULL;
1560                 break;
1561         case 2:
1562                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1563                 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1564                 type = q_u->info.share.info2.info_2.type;
1565                 psd = NULL;
1566                 break;
1567 #if 0
1568                 /* not supported on set but here for completeness */
1569         case 501:
1570                 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1571                 type = q_u->info.share.info501.info_501.type;
1572                 psd = NULL;
1573                 break;
1574 #endif
1575         case 502:
1576                 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1577                 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1578                 type = q_u->info.share.info502.info_502.type;
1579                 psd = q_u->info.share.info502.info_502_str.sd;
1580                 map_generic_share_sd_bits(psd);
1581                 break;
1582         case 1004:
1583                 pstrcpy(pathname, lp_pathname(snum));
1584                 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1585                 type = STYPE_DISKTREE;
1586                 break;
1587         case 1005:
1588                 /* XP re-sets the csc policy even if it wasn't changed by the
1589                    user, so we must compare it to see if it's what is set in
1590                    smb.conf, so that we can contine other ops like setting
1591                    ACLs on a share */
1592                 if (((q_u->info.share.info1005.share_info_flags &
1593                       SHARE_1005_CSC_POLICY_MASK) >>
1594                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1595                         return WERR_OK;
1596                 else {
1597                         DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1598                         return WERR_ACCESS_DENIED;
1599                 }
1600                 break;
1601         case 1006:
1602         case 1007:
1603                 return WERR_ACCESS_DENIED;
1604                 break;
1605         case 1501:
1606                 pstrcpy(pathname, lp_pathname(snum));
1607                 fstrcpy(comment, lp_comment(snum));
1608                 psd = q_u->info.share.info1501.sdb->sec;
1609                 map_generic_share_sd_bits(psd);
1610                 type = STYPE_DISKTREE;
1611                 break;
1612         default:
1613                 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1614                 return WERR_UNKNOWN_LEVEL;
1615         }
1616
1617         /* We can only modify disk shares. */
1618         if (type != STYPE_DISKTREE)
1619                 return WERR_ACCESS_DENIED;
1620                 
1621         /* Check if the pathname is valid. */
1622         if (!(path = valid_share_pathname( pathname )))
1623                 return WERR_OBJECT_PATH_INVALID;
1624
1625         /* Ensure share name, pathname and comment don't contain '"' characters. */
1626         string_replace(share_name, '"', ' ');
1627         string_replace(path, '"', ' ');
1628         string_replace(comment, '"', ' ');
1629
1630         DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1631                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1632
1633         /* Only call modify function if something changed. */
1634         
1635         if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) 
1636         {
1637                 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) 
1638                         return WERR_ACCESS_DENIED;
1639
1640                 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1641                                 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1642
1643                 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1644                                 
1645                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1646         
1647                 if ( is_disk_op )
1648                         become_root();
1649                         
1650                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1651                         /* Tell everyone we updated smb.conf. */
1652                         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1653                 }
1654                 
1655                 if ( is_disk_op )
1656                         unbecome_root();
1657                         
1658                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1659
1660                 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));              
1661         
1662                 if ( ret != 0 )
1663                         return WERR_ACCESS_DENIED;
1664         } else {
1665                 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1666         }
1667
1668         /* Replace SD if changed. */
1669         if (psd) {
1670                 SEC_DESC *old_sd;
1671                 size_t sd_size;
1672
1673                 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1674
1675                 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1676                         if (!set_share_security(p->mem_ctx, share_name, psd))
1677                                 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1678                                         share_name ));
1679                 }
1680         }
1681                         
1682         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1683
1684         return WERR_OK;
1685 }
1686
1687 /*******************************************************************
1688  Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1689 ********************************************************************/
1690
1691 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1692 {
1693         struct current_user user;
1694         pstring command;
1695         fstring share_name;
1696         fstring comment;
1697         pstring pathname;
1698         int type;
1699         int snum;
1700         int ret;
1701         char *path;
1702         SEC_DESC *psd = NULL;
1703         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1704         BOOL is_disk_op;
1705
1706         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1707
1708         r_u->parm_error = 0;
1709
1710         get_current_user(&user,p);
1711
1712         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1713
1714         if (user.uid != sec_initial_uid()  && !is_disk_op ) 
1715                 return WERR_ACCESS_DENIED;
1716
1717         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1718                 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1719                 return WERR_ACCESS_DENIED;
1720         }
1721         
1722         switch (q_u->info_level) {
1723         case 0:
1724                 /* No path. Not enough info in a level 0 to do anything. */
1725                 return WERR_ACCESS_DENIED;
1726         case 1:
1727                 /* Not enough info in a level 1 to do anything. */
1728                 return WERR_ACCESS_DENIED;
1729         case 2:
1730                 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1731                 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1732                 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1733                 type = q_u->info.share.info2.info_2.type;
1734                 break;
1735         case 501:
1736                 /* No path. Not enough info in a level 501 to do anything. */
1737                 return WERR_ACCESS_DENIED;
1738         case 502:
1739                 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1740                 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1741                 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1742                 type = q_u->info.share.info502.info_502.type;
1743                 psd = q_u->info.share.info502.info_502_str.sd;
1744                 map_generic_share_sd_bits(psd);
1745                 break;
1746
1747                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */ 
1748
1749         case 1004:
1750         case 1005:
1751         case 1006:
1752         case 1007:
1753                 return WERR_ACCESS_DENIED;
1754                 break;
1755         case 1501:
1756                 /* DFS only level. */
1757                 return WERR_ACCESS_DENIED;
1758         default:
1759                 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1760                 return WERR_UNKNOWN_LEVEL;
1761         }
1762
1763         if ( strequal(share_name,"IPC$") 
1764                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1765                 || strequal(share_name,"global") )
1766         {
1767                 return WERR_ACCESS_DENIED;
1768         }
1769
1770         snum = find_service(share_name);
1771
1772         /* Share already exists. */
1773         if (snum >= 0)
1774                 return WERR_ALREADY_EXISTS;
1775
1776         /* We can only add disk shares. */
1777         if (type != STYPE_DISKTREE)
1778                 return WERR_ACCESS_DENIED;
1779                 
1780         /* Check if the pathname is valid. */
1781         if (!(path = valid_share_pathname( pathname )))
1782                 return WERR_OBJECT_PATH_INVALID;
1783
1784         /* Ensure share name, pathname and comment don't contain '"' characters. */
1785         string_replace(share_name, '"', ' ');
1786         string_replace(path, '"', ' ');
1787         string_replace(comment, '"', ' ');
1788
1789         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1790                         lp_add_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1791                         
1792         DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1793         
1794         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1795         
1796         if ( is_disk_op )
1797                 become_root();
1798
1799         if ( (ret = smbrun(command, NULL)) == 0 ) {
1800                 /* Tell everyone we updated smb.conf. */
1801                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1802         }
1803
1804         if ( is_disk_op )
1805                 unbecome_root();
1806                 
1807         /********* END SeDiskOperatorPrivilege BLOCK *********/
1808
1809         DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1810
1811         if ( ret != 0 )
1812                 return WERR_ACCESS_DENIED;
1813
1814         if (psd) {
1815                 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1816                         DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1817                 }
1818         }
1819
1820         /*
1821          * We don't call reload_services() here, the message will
1822          * cause this to be done before the next packet is read
1823          * from the client. JRA.
1824          */
1825
1826         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1827
1828         return WERR_OK;
1829 }
1830
1831 /*******************************************************************
1832  Net share delete. Call "delete share command" with the share name as
1833  a parameter.
1834 ********************************************************************/
1835
1836 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1837 {
1838         struct current_user user;
1839         pstring command;
1840         fstring share_name;
1841         int ret;
1842         int snum;
1843         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1844         BOOL is_disk_op;
1845
1846         DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1847
1848         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1849
1850         if ( strequal(share_name,"IPC$") 
1851                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1852                 || strequal(share_name,"global") )
1853         {
1854                 return WERR_ACCESS_DENIED;
1855         }
1856
1857         snum = find_service(share_name);
1858
1859         if (snum < 0)
1860                 return WERR_NO_SUCH_SHARE;
1861
1862         /* No change to printer shares. */
1863         if (lp_print_ok(snum))
1864                 return WERR_ACCESS_DENIED;
1865
1866         get_current_user(&user,p);
1867
1868         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1869
1870         if (user.uid != sec_initial_uid()  && !is_disk_op ) 
1871                 return WERR_ACCESS_DENIED;
1872
1873         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1874                 return WERR_ACCESS_DENIED;
1875                 
1876         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1877                         lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1878
1879         DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1880
1881         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1882         
1883         if ( is_disk_op )
1884                 become_root();
1885
1886         if ( (ret = smbrun(command, NULL)) == 0 ) {
1887                 /* Tell everyone we updated smb.conf. */
1888                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1889         }
1890
1891         if ( is_disk_op )
1892                 unbecome_root();
1893                 
1894         /********* END SeDiskOperatorPrivilege BLOCK *********/
1895
1896         DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1897
1898         if ( ret != 0 )
1899                 return WERR_ACCESS_DENIED;
1900
1901         /* Delete the SD in the database. */
1902         delete_share_security(snum);
1903
1904         lp_killservice(snum);
1905
1906         return WERR_OK;
1907 }
1908
1909 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1910 {
1911         DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1912
1913         return _srv_net_share_del(p, q_u, r_u);
1914 }
1915
1916 /*******************************************************************
1917 time of day
1918 ********************************************************************/
1919
1920 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1921 {
1922         TIME_OF_DAY_INFO *tod;
1923         struct tm *t;
1924         time_t unixdate = time(NULL);
1925
1926         tod = TALLOC_P(p->mem_ctx, TIME_OF_DAY_INFO);
1927         if (!tod)
1928                 return WERR_NOMEM;
1929
1930         ZERO_STRUCTP(tod);
1931  
1932         r_u->tod = tod;
1933         r_u->ptr_srv_tod = 0x1;
1934         r_u->status = WERR_OK;
1935
1936         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1937
1938         t = gmtime(&unixdate);
1939
1940         /* set up the */
1941         init_time_of_day_info(tod,
1942                               unixdate,
1943                               0,
1944                               t->tm_hour,
1945                               t->tm_min,
1946                               t->tm_sec,
1947                               0,
1948                               TimeDiff(unixdate)/60,
1949                               10000,
1950                               t->tm_mday,
1951                               t->tm_mon + 1,
1952                               1900+t->tm_year,
1953                               t->tm_wday);
1954         
1955         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1956
1957         return r_u->status;
1958 }
1959
1960 /***********************************************************************************
1961  Win9x NT tools get security descriptor.
1962 ***********************************************************************************/
1963
1964 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1965                         SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1966 {
1967         SEC_DESC *psd = NULL;
1968         size_t sd_size;
1969         DATA_BLOB null_pw;
1970         pstring filename;
1971         pstring qualname;
1972         files_struct *fsp = NULL;
1973         SMB_STRUCT_STAT st;
1974         BOOL bad_path;
1975         int access_mode;
1976         int action;
1977         NTSTATUS nt_status;
1978         struct current_user user;
1979         connection_struct *conn = NULL;
1980         BOOL became_user = False; 
1981
1982         ZERO_STRUCT(st);
1983
1984         r_u->status = WERR_OK;
1985
1986         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1987
1988         /* Null password is ok - we are already an authenticated user... */
1989         null_pw = data_blob(NULL, 0);
1990
1991         get_current_user(&user, p);
1992
1993         become_root();
1994         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1995         unbecome_root();
1996
1997         if (conn == NULL) {
1998                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1999                 r_u->status = ntstatus_to_werror(nt_status);
2000                 goto error_exit;
2001         }
2002
2003         if (!become_user(conn, conn->vuid)) {
2004                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2005                 r_u->status = WERR_ACCESS_DENIED;
2006                 goto error_exit;
2007         }
2008         became_user = True;
2009
2010         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2011         unix_convert(filename, conn, NULL, &bad_path, &st);
2012         if (bad_path) {
2013                 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
2014                 r_u->status = WERR_ACCESS_DENIED;
2015                 goto error_exit;
2016         }
2017
2018         if (!check_name(filename,conn)) {
2019                 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
2020                 r_u->status = WERR_ACCESS_DENIED;
2021                 goto error_exit;
2022         }
2023
2024         fsp = open_file_shared(conn, filename, &st, SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
2025                                 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
2026                                 &access_mode, &action);
2027
2028         if (!fsp) {
2029                 /* Perhaps it is a directory */
2030                 if (errno == EISDIR)
2031                         fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
2032                                         (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
2033
2034                 if (!fsp) {
2035                         DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
2036                         r_u->status = WERR_ACCESS_DENIED;
2037                         goto error_exit;
2038                 }
2039         }
2040
2041         sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2042
2043         if (sd_size == 0) {
2044                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
2045                 r_u->status = WERR_ACCESS_DENIED;
2046                 goto error_exit;
2047         }
2048
2049         r_u->ptr_response = 1;
2050         r_u->size_response = sd_size;
2051         r_u->ptr_secdesc = 1;
2052         r_u->size_secdesc = sd_size;
2053         r_u->sec_desc = psd;
2054
2055         psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2056
2057         close_file(fsp, True);
2058         unbecome_user();
2059         close_cnum(conn, user.vuid);
2060         return r_u->status;
2061
2062 error_exit:
2063
2064         if(fsp) {
2065                 close_file(fsp, True);
2066         }
2067
2068         if (became_user)
2069                 unbecome_user();
2070
2071         if (conn) 
2072                 close_cnum(conn, user.vuid);
2073
2074         return r_u->status;
2075 }
2076
2077 /***********************************************************************************
2078  Win9x NT tools set security descriptor.
2079 ***********************************************************************************/
2080
2081 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
2082                                                                         SRV_R_NET_FILE_SET_SECDESC *r_u)
2083 {
2084         BOOL ret;
2085         pstring filename;
2086         pstring qualname;
2087         DATA_BLOB null_pw;
2088         files_struct *fsp = NULL;
2089         SMB_STRUCT_STAT st;
2090         BOOL bad_path;
2091         int access_mode;
2092         int action;
2093         NTSTATUS nt_status;
2094         struct current_user user;
2095         connection_struct *conn = NULL;
2096         BOOL became_user = False;
2097
2098         ZERO_STRUCT(st);
2099
2100         r_u->status = WERR_OK;
2101
2102         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2103
2104         /* Null password is ok - we are already an authenticated user... */
2105         null_pw = data_blob(NULL, 0);
2106
2107         get_current_user(&user, p);
2108
2109         become_root();
2110         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2111         unbecome_root();
2112
2113         if (conn == NULL) {
2114                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2115                 r_u->status = ntstatus_to_werror(nt_status);
2116                 goto error_exit;
2117         }
2118
2119         if (!become_user(conn, conn->vuid)) {
2120                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2121                 r_u->status = WERR_ACCESS_DENIED;
2122                 goto error_exit;
2123         }
2124         became_user = True;
2125
2126         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2127         unix_convert(filename, conn, NULL, &bad_path, &st);
2128         if (bad_path) {
2129                 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2130                 r_u->status = WERR_ACCESS_DENIED;
2131                 goto error_exit;
2132         }
2133
2134         if (!check_name(filename,conn)) {
2135                 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2136                 r_u->status = WERR_ACCESS_DENIED;
2137                 goto error_exit;
2138         }
2139
2140
2141         fsp = open_file_shared(conn, filename, &st, SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDWR),
2142                         (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
2143                         &access_mode, &action);
2144
2145         if (!fsp) {
2146                 /* Perhaps it is a directory */
2147                 if (errno == EISDIR)
2148                         fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
2149                                                 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
2150
2151                 if (!fsp) {
2152                         DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2153                         r_u->status = WERR_ACCESS_DENIED;
2154                         goto error_exit;
2155                 }
2156         }
2157
2158         ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2159
2160         if (ret == False) {
2161                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2162                 r_u->status = WERR_ACCESS_DENIED;
2163                 goto error_exit;
2164         }
2165
2166         close_file(fsp, True);
2167         unbecome_user();
2168         close_cnum(conn, user.vuid);
2169         return r_u->status;
2170
2171 error_exit:
2172
2173         if(fsp) {
2174                 close_file(fsp, True);
2175         }
2176
2177         if (became_user)
2178                 unbecome_user();
2179
2180         if (conn) 
2181                 close_cnum(conn, user.vuid);
2182
2183         return r_u->status;
2184 }
2185
2186 /***********************************************************************************
2187  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2188  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2189  These disks would the disks listed by this function.
2190  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2191  "Nigel Williams" <nigel@veritas.com>.
2192 ***********************************************************************************/
2193
2194 static const char *server_disks[] = {"C:"};
2195
2196 static uint32 get_server_disk_count(void)
2197 {
2198         return sizeof(server_disks)/sizeof(server_disks[0]);
2199 }
2200
2201 static uint32 init_server_disk_enum(uint32 *resume)
2202 {
2203         uint32 server_disk_count = get_server_disk_count();
2204
2205         /*resume can be an offset into the list for now*/
2206
2207         if(*resume & 0x80000000)
2208                 *resume = 0;
2209
2210         if(*resume > server_disk_count)
2211                 *resume = server_disk_count;
2212
2213         return server_disk_count - *resume;
2214 }
2215
2216 static const char *next_server_disk_enum(uint32 *resume)
2217 {
2218         const char *disk;
2219
2220         if(init_server_disk_enum(resume) == 0)
2221                 return NULL;
2222
2223         disk = server_disks[*resume];
2224
2225         (*resume)++;
2226
2227         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2228
2229         return disk;
2230 }
2231
2232 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2233 {
2234         uint32 i;
2235         const char *disk_name;
2236         TALLOC_CTX *ctx = p->mem_ctx;
2237         uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2238
2239         r_u->status=WERR_OK;
2240
2241         r_u->total_entries = init_server_disk_enum(&resume);
2242
2243         r_u->disk_enum_ctr.unknown = 0; 
2244
2245         if(!(r_u->disk_enum_ctr.disk_info =  TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2246                 return WERR_NOMEM;
2247         }
2248
2249         r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2250
2251         /*allow one DISK_INFO for null terminator*/
2252
2253         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2254
2255                 r_u->disk_enum_ctr.entries_read++;
2256
2257                 /*copy disk name into a unicode string*/
2258
2259                 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);    
2260         }
2261
2262         /* add a terminating null string.  Is this there if there is more data to come? */
2263
2264         r_u->disk_enum_ctr.entries_read++;
2265
2266         init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2267
2268         init_enum_hnd(&r_u->enum_hnd, resume);
2269
2270         return r_u->status;
2271 }
2272
2273 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2274 {
2275         int snum;
2276         fstring share_name;
2277
2278         r_u->status=WERR_OK;
2279
2280         switch(q_u->type) {
2281
2282         case 0x9:
2283
2284                 /*check if share name is ok*/
2285                 /*also check if we already have a share with this name*/
2286
2287                 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
2288                 snum = find_service(share_name);
2289
2290                 /* Share already exists. */
2291                 if (snum >= 0)
2292                         r_u->status = WERR_ALREADY_EXISTS;
2293                 break;
2294
2295         default:
2296                 /*unsupported type*/
2297                 r_u->status = WERR_UNKNOWN_LEVEL;
2298                 break;
2299         }
2300
2301         return r_u->status;
2302 }