r9780: Clean up a bunch of compiler warnings.
[sfrench/samba-autobuild/.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;
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 (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         case 1006:
1601         case 1007:
1602                 return WERR_ACCESS_DENIED;
1603         case 1501:
1604                 pstrcpy(pathname, lp_pathname(snum));
1605                 fstrcpy(comment, lp_comment(snum));
1606                 psd = q_u->info.share.info1501.sdb->sec;
1607                 map_generic_share_sd_bits(psd);
1608                 type = STYPE_DISKTREE;
1609                 break;
1610         default:
1611                 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1612                 return WERR_UNKNOWN_LEVEL;
1613         }
1614
1615         /* We can only modify disk shares. */
1616         if (type != STYPE_DISKTREE)
1617                 return WERR_ACCESS_DENIED;
1618                 
1619         /* Check if the pathname is valid. */
1620         if (!(path = valid_share_pathname( pathname )))
1621                 return WERR_OBJECT_PATH_INVALID;
1622
1623         /* Ensure share name, pathname and comment don't contain '"' characters. */
1624         string_replace(share_name, '"', ' ');
1625         string_replace(path, '"', ' ');
1626         string_replace(comment, '"', ' ');
1627
1628         DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1629                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1630
1631         /* Only call modify function if something changed. */
1632         
1633         if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) 
1634         {
1635                 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1636                         DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1637                         return WERR_ACCESS_DENIED;
1638                 }
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         case 1501:
1755                 /* DFS only level. */
1756                 return WERR_ACCESS_DENIED;
1757         default:
1758                 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1759                 return WERR_UNKNOWN_LEVEL;
1760         }
1761
1762         if ( strequal(share_name,"IPC$") 
1763                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1764                 || strequal(share_name,"global") )
1765         {
1766                 return WERR_ACCESS_DENIED;
1767         }
1768
1769         snum = find_service(share_name);
1770
1771         /* Share already exists. */
1772         if (snum >= 0)
1773                 return WERR_ALREADY_EXISTS;
1774
1775         /* We can only add disk shares. */
1776         if (type != STYPE_DISKTREE)
1777                 return WERR_ACCESS_DENIED;
1778                 
1779         /* Check if the pathname is valid. */
1780         if (!(path = valid_share_pathname( pathname )))
1781                 return WERR_OBJECT_PATH_INVALID;
1782
1783         /* Ensure share name, pathname and comment don't contain '"' characters. */
1784         string_replace(share_name, '"', ' ');
1785         string_replace(path, '"', ' ');
1786         string_replace(comment, '"', ' ');
1787
1788         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1789                         lp_add_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1790                         
1791         DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1792         
1793         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1794         
1795         if ( is_disk_op )
1796                 become_root();
1797
1798         if ( (ret = smbrun(command, NULL)) == 0 ) {
1799                 /* Tell everyone we updated smb.conf. */
1800                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1801         }
1802
1803         if ( is_disk_op )
1804                 unbecome_root();
1805                 
1806         /********* END SeDiskOperatorPrivilege BLOCK *********/
1807
1808         DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1809
1810         if ( ret != 0 )
1811                 return WERR_ACCESS_DENIED;
1812
1813         if (psd) {
1814                 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1815                         DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1816                 }
1817         }
1818
1819         /*
1820          * We don't call reload_services() here, the message will
1821          * cause this to be done before the next packet is read
1822          * from the client. JRA.
1823          */
1824
1825         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1826
1827         return WERR_OK;
1828 }
1829
1830 /*******************************************************************
1831  Net share delete. Call "delete share command" with the share name as
1832  a parameter.
1833 ********************************************************************/
1834
1835 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1836 {
1837         struct current_user user;
1838         pstring command;
1839         fstring share_name;
1840         int ret;
1841         int snum;
1842         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1843         BOOL is_disk_op;
1844
1845         DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1846
1847         unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1848
1849         if ( strequal(share_name,"IPC$") 
1850                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1851                 || strequal(share_name,"global") )
1852         {
1853                 return WERR_ACCESS_DENIED;
1854         }
1855
1856         snum = find_service(share_name);
1857
1858         if (snum < 0)
1859                 return WERR_NO_SUCH_SHARE;
1860
1861         /* No change to printer shares. */
1862         if (lp_print_ok(snum))
1863                 return WERR_ACCESS_DENIED;
1864
1865         get_current_user(&user,p);
1866
1867         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1868
1869         if (user.uid != sec_initial_uid()  && !is_disk_op ) 
1870                 return WERR_ACCESS_DENIED;
1871
1872         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1873                 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1874                 return WERR_ACCESS_DENIED;
1875         }
1876                 
1877         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1878                         lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1879
1880         DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1881
1882         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1883         
1884         if ( is_disk_op )
1885                 become_root();
1886
1887         if ( (ret = smbrun(command, NULL)) == 0 ) {
1888                 /* Tell everyone we updated smb.conf. */
1889                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1890         }
1891
1892         if ( is_disk_op )
1893                 unbecome_root();
1894                 
1895         /********* END SeDiskOperatorPrivilege BLOCK *********/
1896
1897         DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1898
1899         if ( ret != 0 )
1900                 return WERR_ACCESS_DENIED;
1901
1902         /* Delete the SD in the database. */
1903         delete_share_security(snum);
1904
1905         lp_killservice(snum);
1906
1907         return WERR_OK;
1908 }
1909
1910 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1911 {
1912         DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1913
1914         return _srv_net_share_del(p, q_u, r_u);
1915 }
1916
1917 /*******************************************************************
1918 time of day
1919 ********************************************************************/
1920
1921 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1922 {
1923         TIME_OF_DAY_INFO *tod;
1924         struct tm *t;
1925         time_t unixdate = time(NULL);
1926
1927         tod = TALLOC_P(p->mem_ctx, TIME_OF_DAY_INFO);
1928         if (!tod)
1929                 return WERR_NOMEM;
1930
1931         ZERO_STRUCTP(tod);
1932  
1933         r_u->tod = tod;
1934         r_u->ptr_srv_tod = 0x1;
1935         r_u->status = WERR_OK;
1936
1937         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1938
1939         t = gmtime(&unixdate);
1940
1941         /* set up the */
1942         init_time_of_day_info(tod,
1943                               unixdate,
1944                               0,
1945                               t->tm_hour,
1946                               t->tm_min,
1947                               t->tm_sec,
1948                               0,
1949                               TimeDiff(unixdate)/60,
1950                               10000,
1951                               t->tm_mday,
1952                               t->tm_mon + 1,
1953                               1900+t->tm_year,
1954                               t->tm_wday);
1955         
1956         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1957
1958         return r_u->status;
1959 }
1960
1961 /***********************************************************************************
1962  Win9x NT tools get security descriptor.
1963 ***********************************************************************************/
1964
1965 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1966                         SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1967 {
1968         SEC_DESC *psd = NULL;
1969         size_t sd_size;
1970         DATA_BLOB null_pw;
1971         pstring filename;
1972         pstring qualname;
1973         files_struct *fsp = NULL;
1974         SMB_STRUCT_STAT st;
1975         BOOL bad_path;
1976         NTSTATUS nt_status;
1977         struct current_user user;
1978         connection_struct *conn = NULL;
1979         BOOL became_user = False; 
1980
1981         ZERO_STRUCT(st);
1982
1983         r_u->status = WERR_OK;
1984
1985         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1986
1987         /* Null password is ok - we are already an authenticated user... */
1988         null_pw = data_blob(NULL, 0);
1989
1990         get_current_user(&user, p);
1991
1992         become_root();
1993         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1994         unbecome_root();
1995
1996         if (conn == NULL) {
1997                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1998                 r_u->status = ntstatus_to_werror(nt_status);
1999                 goto error_exit;
2000         }
2001
2002         if (!become_user(conn, conn->vuid)) {
2003                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2004                 r_u->status = WERR_ACCESS_DENIED;
2005                 goto error_exit;
2006         }
2007         became_user = True;
2008
2009         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2010         unix_convert(filename, conn, NULL, &bad_path, &st);
2011         if (bad_path) {
2012                 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
2013                 r_u->status = WERR_ACCESS_DENIED;
2014                 goto error_exit;
2015         }
2016
2017         if (!check_name(filename,conn)) {
2018                 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
2019                 r_u->status = WERR_ACCESS_DENIED;
2020                 goto error_exit;
2021         }
2022
2023         fsp = open_file_stat(conn, filename, &st);
2024         if (!fsp) {
2025                 /* Perhaps it is a directory */
2026                 if (errno == EISDIR)
2027                         fsp = open_directory(conn, filename, &st,
2028                                         READ_CONTROL_ACCESS,
2029                                         FILE_SHARE_READ|FILE_SHARE_WRITE,
2030                                         FILE_OPEN,
2031                                         0,
2032                                         NULL);
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         NTSTATUS nt_status;
2092         struct current_user user;
2093         connection_struct *conn = NULL;
2094         BOOL became_user = False;
2095
2096         ZERO_STRUCT(st);
2097
2098         r_u->status = WERR_OK;
2099
2100         unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2101
2102         /* Null password is ok - we are already an authenticated user... */
2103         null_pw = data_blob(NULL, 0);
2104
2105         get_current_user(&user, p);
2106
2107         become_root();
2108         conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2109         unbecome_root();
2110
2111         if (conn == NULL) {
2112                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2113                 r_u->status = ntstatus_to_werror(nt_status);
2114                 goto error_exit;
2115         }
2116
2117         if (!become_user(conn, conn->vuid)) {
2118                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2119                 r_u->status = WERR_ACCESS_DENIED;
2120                 goto error_exit;
2121         }
2122         became_user = True;
2123
2124         unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2125         unix_convert(filename, conn, NULL, &bad_path, &st);
2126         if (bad_path) {
2127                 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2128                 r_u->status = WERR_ACCESS_DENIED;
2129                 goto error_exit;
2130         }
2131
2132         if (!check_name(filename,conn)) {
2133                 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2134                 r_u->status = WERR_ACCESS_DENIED;
2135                 goto error_exit;
2136         }
2137
2138
2139         fsp = open_file_stat(conn, filename, &st);
2140
2141         if (!fsp) {
2142                 /* Perhaps it is a directory */
2143                 if (errno == EISDIR)
2144                         fsp = open_directory(conn, filename, &st,
2145                                                 FILE_READ_ATTRIBUTES,
2146                                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
2147                                                 FILE_OPEN,
2148                                                 0,
2149                                                 NULL);
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
2181         if (conn) {
2182                 close_cnum(conn, user.vuid);
2183         }
2184
2185         return r_u->status;
2186 }
2187
2188 /***********************************************************************************
2189  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2190  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2191  These disks would the disks listed by this function.
2192  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2193  "Nigel Williams" <nigel@veritas.com>.
2194 ***********************************************************************************/
2195
2196 static const char *server_disks[] = {"C:"};
2197
2198 static uint32 get_server_disk_count(void)
2199 {
2200         return sizeof(server_disks)/sizeof(server_disks[0]);
2201 }
2202
2203 static uint32 init_server_disk_enum(uint32 *resume)
2204 {
2205         uint32 server_disk_count = get_server_disk_count();
2206
2207         /*resume can be an offset into the list for now*/
2208
2209         if(*resume & 0x80000000)
2210                 *resume = 0;
2211
2212         if(*resume > server_disk_count)
2213                 *resume = server_disk_count;
2214
2215         return server_disk_count - *resume;
2216 }
2217
2218 static const char *next_server_disk_enum(uint32 *resume)
2219 {
2220         const char *disk;
2221
2222         if(init_server_disk_enum(resume) == 0)
2223                 return NULL;
2224
2225         disk = server_disks[*resume];
2226
2227         (*resume)++;
2228
2229         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2230
2231         return disk;
2232 }
2233
2234 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2235 {
2236         uint32 i;
2237         const char *disk_name;
2238         TALLOC_CTX *ctx = p->mem_ctx;
2239         uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2240
2241         r_u->status=WERR_OK;
2242
2243         r_u->total_entries = init_server_disk_enum(&resume);
2244
2245         r_u->disk_enum_ctr.unknown = 0; 
2246
2247         if(!(r_u->disk_enum_ctr.disk_info =  TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2248                 return WERR_NOMEM;
2249         }
2250
2251         r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2252
2253         /*allow one DISK_INFO for null terminator*/
2254
2255         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2256
2257                 r_u->disk_enum_ctr.entries_read++;
2258
2259                 /*copy disk name into a unicode string*/
2260
2261                 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);    
2262         }
2263
2264         /* add a terminating null string.  Is this there if there is more data to come? */
2265
2266         r_u->disk_enum_ctr.entries_read++;
2267
2268         init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2269
2270         init_enum_hnd(&r_u->enum_hnd, resume);
2271
2272         return r_u->status;
2273 }
2274
2275 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2276 {
2277         int snum;
2278         fstring share_name;
2279
2280         r_u->status=WERR_OK;
2281
2282         switch(q_u->type) {
2283
2284         case 0x9:
2285
2286                 /*check if share name is ok*/
2287                 /*also check if we already have a share with this name*/
2288
2289                 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
2290                 snum = find_service(share_name);
2291
2292                 /* Share already exists. */
2293                 if (snum >= 0)
2294                         r_u->status = WERR_ALREADY_EXISTS;
2295                 break;
2296
2297         default:
2298                 /*unsupported type*/
2299                 r_u->status = WERR_UNKNOWN_LEVEL;
2300                 break;
2301         }
2302
2303         return r_u->status;
2304 }