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