r6303: Setting up for 3.0.15pre1
[Samba.git] / source / rpc_server / srv_srvsvc_nt.c
blobb5768a09af038f914bde2a68881daf09bea8ff02
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.
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.
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.
23 /* This is the implementation of the srvsvc pipe. */
25 #include "includes.h"
27 extern struct generic_mapping file_generic_mapping;
29 #undef DBGC_CLASS
30 #define DBGC_CLASS DBGC_RPC_SRV
32 /*******************************************************************
33 Utility function to get the 'type' of a share from an snum.
34 ********************************************************************/
35 static uint32 get_share_type(int snum)
37 char *net_name = lp_servicename(snum);
38 int len_net_name = strlen(net_name);
40 /* work out the share type */
41 uint32 type = STYPE_DISKTREE;
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;
50 return type;
53 /*******************************************************************
54 Fill in a share info level 0 structure.
55 ********************************************************************/
57 static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum)
59 pstring net_name;
61 pstrcpy(net_name, lp_servicename(snum));
63 init_srv_share_info0(&sh0->info_0, net_name);
64 init_srv_share_info0_str(&sh0->info_0_str, net_name);
67 /*******************************************************************
68 Fill in a share info level 1 structure.
69 ********************************************************************/
71 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
73 pstring remark;
75 char *net_name = lp_servicename(snum);
76 pstrcpy(remark, lp_comment(snum));
77 standard_sub_conn(p->conn, remark,sizeof(remark));
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);
83 /*******************************************************************
84 Fill in a share info level 2 structure.
85 ********************************************************************/
87 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
89 pstring remark;
90 pstring path;
91 pstring passwd;
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));
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.
104 string_replace(path, '/', '\\');
106 pstrcpy(passwd, "");
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);
112 /*******************************************************************
113 What to do when smb.conf is updated.
114 ********************************************************************/
116 static void smb_conf_updated(int msg_type, pid_t src, void *buf, size_t len)
118 DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
119 reload_services(False);
122 /*******************************************************************
123 Create the share security tdb.
124 ********************************************************************/
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. */
130 BOOL share_info_db_init(void)
132 static pid_t local_pid;
133 const char *vstring = "INFO/version";
134 int32 vers_id;
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;
145 local_pid = sys_getpid();
147 /* handle a Samba upgrade */
148 tdb_lock_bystring(share_tdb, vstring, 0);
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;
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);
162 tdb_unlock_bystring(share_tdb, vstring);
164 message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
166 return True;
169 /*******************************************************************
170 Fake up a Everyone, full access as a default.
171 ********************************************************************/
173 static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
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;
181 se_map_generic(&def_access, &file_generic_mapping);
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);
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);
190 if (!psd) {
191 DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
192 return NULL;
195 return psd;
198 /*******************************************************************
199 Pull a security descriptor from the share tdb.
200 ********************************************************************/
202 static SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
204 prs_struct ps;
205 fstring key;
206 SEC_DESC *psd = NULL;
208 *psize = 0;
210 /* Fetch security descriptor from tdb */
212 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
214 if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
215 !sec_io_desc("get_share_security", &psd, &ps, 1)) {
217 DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
219 return get_share_security_default(ctx, snum, psize);
222 if (psd)
223 *psize = sec_desc_size(psd);
225 prs_mem_free(&ps);
226 return psd;
229 /*******************************************************************
230 Store a security descriptor in the share db.
231 ********************************************************************/
233 static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd)
235 prs_struct ps;
236 TALLOC_CTX *mem_ctx = NULL;
237 fstring key;
238 BOOL ret = False;
240 mem_ctx = talloc_init("set_share_security");
241 if (mem_ctx == NULL)
242 return False;
244 prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
246 if (!sec_io_desc("share_security", &psd, &ps, 1))
247 goto out;
249 slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name);
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 ));
258 /* Free malloc'ed memory */
260 out:
262 prs_mem_free(&ps);
263 if (mem_ctx)
264 talloc_destroy(mem_ctx);
265 return ret;
268 /*******************************************************************
269 Delete a security descriptor.
270 ********************************************************************/
272 static BOOL delete_share_security(int snum)
274 TDB_DATA kbuf;
275 fstring key;
277 slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
278 kbuf.dptr = key;
279 kbuf.dsize = strlen(key)+1;
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;
287 return True;
290 /*******************************************************************
291 Map any generic bits to file specific bits.
292 ********************************************************************/
294 void map_generic_share_sd_bits(SEC_DESC *psd)
296 int i;
297 SEC_ACL *ps_dacl = NULL;
299 if (!psd)
300 return;
302 ps_dacl = psd->dacl;
303 if (!ps_dacl)
304 return;
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;
310 se_map_generic(&psa->info.mask, &file_generic_mapping);
311 psa->info.mask |= orig_mask;
315 /*******************************************************************
316 Can this user access with share with the required permissions ?
317 ********************************************************************/
319 BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, uint32 desired_access)
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;
329 mem_ctx = talloc_init("share_access_check");
330 if (mem_ctx == NULL)
331 return False;
333 psd = get_share_security(mem_ctx, snum, &sd_size);
335 if (!psd)
336 goto out;
338 if (conn->nt_user_token)
339 token = conn->nt_user_token;
340 else
341 token = vuser->nt_user_token;
343 ret = se_access_check(psd, token, desired_access, &granted, &status);
345 out:
347 talloc_destroy(mem_ctx);
349 return ret;
352 /*******************************************************************
353 Fill in a share info level 501 structure.
354 ********************************************************************/
356 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
358 pstring remark;
360 const char *net_name = lp_servicename(snum);
361 pstrcpy(remark, lp_comment(snum));
362 standard_sub_conn(p->conn, remark, sizeof(remark));
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);
368 /*******************************************************************
369 Fill in a share info level 502 structure.
370 ********************************************************************/
372 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
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;
383 ZERO_STRUCTP(sh502);
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));
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.
396 string_replace(path, '/', '\\');
398 pstrcpy(passwd, "");
400 sd = get_share_security(ctx, snum, &sd_size);
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);
406 /***************************************************************************
407 Fill in a share info level 1004 structure.
408 ***************************************************************************/
410 static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
412 pstring remark;
414 pstrcpy(remark, lp_comment(snum));
415 standard_sub_conn(p->conn, remark, sizeof(remark));
417 ZERO_STRUCTP(sh1004);
419 init_srv_share_info1004(&sh1004->info_1004, remark);
420 init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
423 /***************************************************************************
424 Fill in a share info level 1005 structure.
425 ***************************************************************************/
427 static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum)
429 sh1005->share_info_flags = 0;
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;
437 /***************************************************************************
438 Fill in a share info level 1006 structure.
439 ***************************************************************************/
441 static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
443 sh1006->max_uses = -1;
446 /***************************************************************************
447 Fill in a share info level 1007 structure.
448 ***************************************************************************/
450 static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
452 pstring alternate_directory_name = "";
453 uint32 flags = 0;
455 ZERO_STRUCTP(sh1007);
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);
461 /*******************************************************************
462 Fill in a share info level 1501 structure.
463 ********************************************************************/
465 static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
467 SEC_DESC *sd;
468 size_t sd_size;
469 TALLOC_CTX *ctx = p->mem_ctx;
471 ZERO_STRUCTP(sh1501);
473 sd = get_share_security(ctx, snum, &sd_size);
475 sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
478 /*******************************************************************
479 True if it ends in '$'.
480 ********************************************************************/
482 static BOOL is_hidden_share(int snum)
484 const char *net_name = lp_servicename(snum);
486 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
489 /*******************************************************************
490 Fill in a share info structure.
491 ********************************************************************/
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)
496 int num_entries = 0;
497 int num_services = lp_numservices();
498 int snum;
499 TALLOC_CTX *ctx = p->mem_ctx;
501 DEBUG(5,("init_srv_share_info_ctr\n"));
503 ZERO_STRUCTPN(ctr);
505 ctr->info_level = ctr->switch_value = info_level;
506 *resume_hnd = 0;
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++;
514 *total_entries = num_entries;
515 ctr->num_entries2 = ctr->num_entries = num_entries;
516 ctr->ptr_share_info = ctr->ptr_entries = 1;
518 if (!num_entries)
519 return True;
521 switch (info_level) {
522 case 0:
524 SRV_SHARE_INFO_0 *info0 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_0, num_entries);
525 int i = 0;
527 if (!info0) {
528 return False;
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);
537 ctr->share.info0 = info0;
538 break;
542 case 1:
544 SRV_SHARE_INFO_1 *info1 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1, num_entries);
545 int i = 0;
547 if (!info1) {
548 return False;
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);
557 ctr->share.info1 = info1;
558 break;
561 case 2:
563 SRV_SHARE_INFO_2 *info2 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_2, num_entries);
564 int i = 0;
566 if (!info2) {
567 return False;
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);
576 ctr->share.info2 = info2;
577 break;
580 case 501:
582 SRV_SHARE_INFO_501 *info501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_501, num_entries);
583 int i = 0;
585 if (!info501) {
586 return False;
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);
595 ctr->share.info501 = info501;
596 break;
599 case 502:
601 SRV_SHARE_INFO_502 *info502 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_502, num_entries);
602 int i = 0;
604 if (!info502) {
605 return False;
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);
614 ctr->share.info502 = info502;
615 break;
618 /* here for completeness but not currently used with enum (1004 - 1501)*/
620 case 1004:
622 SRV_SHARE_INFO_1004 *info1004 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1004, num_entries);
623 int i = 0;
625 if (!info1004) {
626 return False;
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);
635 ctr->share.info1004 = info1004;
636 break;
639 case 1005:
641 SRV_SHARE_INFO_1005 *info1005 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1005, num_entries);
642 int i = 0;
644 if (!info1005) {
645 return False;
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);
654 ctr->share.info1005 = info1005;
655 break;
658 case 1006:
660 SRV_SHARE_INFO_1006 *info1006 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1006, num_entries);
661 int i = 0;
663 if (!info1006) {
664 return False;
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);
673 ctr->share.info1006 = info1006;
674 break;
677 case 1007:
679 SRV_SHARE_INFO_1007 *info1007 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1007, num_entries);
680 int i = 0;
682 if (!info1007) {
683 return False;
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);
692 ctr->share.info1007 = info1007;
693 break;
696 case 1501:
698 SRV_SHARE_INFO_1501 *info1501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1501, num_entries);
699 int i = 0;
701 if (!info1501) {
702 return False;
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);
711 ctr->share.info1501 = info1501;
712 break;
714 default:
715 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
716 return False;
719 return True;
722 /*******************************************************************
723 Inits a SRV_R_NET_SHARE_ENUM structure.
724 ********************************************************************/
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)
729 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
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;
738 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
741 /*******************************************************************
742 Inits a SRV_R_NET_SHARE_GET_INFO structure.
743 ********************************************************************/
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)
748 WERROR status = WERR_OK;
749 int snum;
751 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
753 r_n->info.switch_value = info_level;
755 snum = find_service(share_name);
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;
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;
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;
798 } else {
799 status = WERR_INVALID_NAME;
802 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
803 r_n->status = status;
806 /*******************************************************************
807 fill in a sess info level 1 structure.
808 ********************************************************************/
810 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
812 init_srv_sess_info0(se0, name);
813 init_srv_sess_info0_str(str0, name);
816 /*******************************************************************
817 fill in a sess info level 0 structure.
818 ********************************************************************/
820 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
822 struct sessionid *session_list;
823 uint32 num_entries = 0;
824 (*stot) = list_sessions(&session_list);
826 if (ss0 == NULL) {
827 (*snum) = 0;
828 SAFE_FREE(session_list);
829 return;
832 DEBUG(5,("init_srv_sess_0_ss0\n"));
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);
839 /* move on to creating next session */
840 /* move on to creating next sess */
841 num_entries++;
844 ss0->num_entries_read = num_entries;
845 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
846 ss0->num_entries_read2 = num_entries;
848 if ((*snum) >= (*stot)) {
849 (*snum) = 0;
852 } else {
853 ss0->num_entries_read = 0;
854 ss0->ptr_sess_info = 0;
855 ss0->num_entries_read2 = 0;
857 SAFE_FREE(session_list);
860 /*******************************************************************
861 fill in a sess info level 1 structure.
862 ********************************************************************/
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)
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);
874 /*******************************************************************
875 fill in a sess info level 1 structure.
876 ********************************************************************/
878 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
880 struct sessionid *session_list;
881 uint32 num_entries = 0;
882 (*stot) = list_sessions(&session_list);
884 if (ss1 == NULL) {
885 (*snum) = 0;
886 SAFE_FREE(session_list);
887 return;
890 DEBUG(5,("init_srv_sess_1_ss1\n"));
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);
900 /* move on to creating next session */
901 /* move on to creating next sess */
902 num_entries++;
905 ss1->num_entries_read = num_entries;
906 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
907 ss1->num_entries_read2 = num_entries;
909 if ((*snum) >= (*stot)) {
910 (*snum) = 0;
913 } else {
914 ss1->num_entries_read = 0;
915 ss1->ptr_sess_info = 0;
916 ss1->num_entries_read2 = 0;
918 (*stot) = 0;
922 /*******************************************************************
923 makes a SRV_R_NET_SESS_ENUM structure.
924 ********************************************************************/
926 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
927 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
929 WERROR status = WERR_OK;
930 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
932 ctr->switch_value = switch_value;
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;
952 return status;
955 /*******************************************************************
956 makes a SRV_R_NET_SESS_ENUM structure.
957 ********************************************************************/
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)
962 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
964 r_n->sess_level = sess_level;
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);
971 if (!W_ERROR_IS_OK(r_n->status))
972 resume_hnd = 0;
974 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
977 /*******************************************************************
978 fill in a conn info level 0 structure.
979 ********************************************************************/
981 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
983 uint32 num_entries = 0;
984 (*stot) = 1;
986 if (ss0 == NULL) {
987 (*snum) = 0;
988 return;
991 DEBUG(5,("init_srv_conn_0_ss0\n"));
993 if (snum) {
994 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
996 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
998 /* move on to creating next connection */
999 /* move on to creating next conn */
1000 num_entries++;
1003 ss0->num_entries_read = num_entries;
1004 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
1005 ss0->num_entries_read2 = num_entries;
1007 if ((*snum) >= (*stot)) {
1008 (*snum) = 0;
1011 } else {
1012 ss0->num_entries_read = 0;
1013 ss0->ptr_conn_info = 0;
1014 ss0->num_entries_read2 = 0;
1016 (*stot) = 0;
1020 /*******************************************************************
1021 fill in a conn info level 1 structure.
1022 ********************************************************************/
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)
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);
1033 /*******************************************************************
1034 fill in a conn info level 1 structure.
1035 ********************************************************************/
1037 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1039 uint32 num_entries = 0;
1040 (*stot) = 1;
1042 if (ss1 == NULL) {
1043 (*snum) = 0;
1044 return;
1047 DEBUG(5,("init_srv_conn_1_ss1\n"));
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$");
1055 /* move on to creating next connection */
1056 /* move on to creating next conn */
1057 num_entries++;
1060 ss1->num_entries_read = num_entries;
1061 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
1062 ss1->num_entries_read2 = num_entries;
1065 if ((*snum) >= (*stot)) {
1066 (*snum) = 0;
1069 } else {
1070 ss1->num_entries_read = 0;
1071 ss1->ptr_conn_info = 0;
1072 ss1->num_entries_read2 = 0;
1074 (*stot) = 0;
1078 /*******************************************************************
1079 makes a SRV_R_NET_CONN_ENUM structure.
1080 ********************************************************************/
1082 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1083 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1085 WERROR status = WERR_OK;
1086 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1088 ctr->switch_value = switch_value;
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;
1108 return status;
1111 /*******************************************************************
1112 makes a SRV_R_NET_CONN_ENUM structure.
1113 ********************************************************************/
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)
1118 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
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);
1126 if (!W_ERROR_IS_OK(r_n->status))
1127 resume_hnd = 0;
1129 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1132 /*******************************************************************
1133 makes a SRV_R_NET_FILE_ENUM structure.
1134 ********************************************************************/
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)
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 */
1145 ctr->switch_value = switch_value;
1146 ctr->num_entries = *total_entries - *resume_hnd;
1147 ctr->num_entries2 = ctr->num_entries;
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);
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");
1161 ctr->ptr_file_info = 1;
1162 *resume_hnd = 0;
1163 break;
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;
1174 return status;
1177 /*******************************************************************
1178 makes a SRV_R_NET_FILE_ENUM structure.
1179 ********************************************************************/
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)
1184 DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
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));
1192 if (!W_ERROR_IS_OK(r_n->status))
1193 resume_hnd = 0;
1195 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1198 /*******************************************************************
1199 net server get info
1200 ********************************************************************/
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)
1204 WERROR status = WERR_OK;
1205 SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR);
1207 if (!ctr)
1208 return WERR_NOMEM;
1210 ZERO_STRUCTP(ctr);
1212 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1214 if (!pipe_access_check(p)) {
1215 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1216 return WERR_ACCESS_DENIED;
1219 switch (q_u->switch_value) {
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. */
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;
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);
1257 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1259 return r_u->status;
1262 /*******************************************************************
1263 net server set info
1264 ********************************************************************/
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)
1268 WERROR status = WERR_OK;
1270 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1272 /* Set up the net server set info structure. */
1274 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1276 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1278 return r_u->status;
1281 /*******************************************************************
1282 net file enum
1283 ********************************************************************/
1285 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1287 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
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);
1295 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1297 return r_u->status;
1300 /*******************************************************************
1301 net conn enum
1302 ********************************************************************/
1304 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1306 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1308 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_CONN_INFO_CTR);
1309 if (!r_u->ctr)
1310 return WERR_NOMEM;
1312 ZERO_STRUCTP(r_u->ctr);
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);
1320 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1322 return r_u->status;
1325 /*******************************************************************
1326 net sess enum
1327 ********************************************************************/
1329 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1331 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1333 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_SESS_INFO_CTR);
1334 if (!r_u->ctr)
1335 return WERR_NOMEM;
1337 ZERO_STRUCTP(r_u->ctr);
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);
1345 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1347 return r_u->status;
1350 /*******************************************************************
1351 net sess del
1352 ********************************************************************/
1354 WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u)
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;
1363 rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name);
1364 rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name);
1366 /* strip leading backslashes if any */
1367 while (machine[0] == '\\') {
1368 memmove(machine, &machine[1], strlen(machine));
1371 num_sessions = list_sessions(&session_list);
1373 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1375 r_u->status = WERR_ACCESS_DENIED;
1377 get_current_user(&user, p);
1379 /* fail out now if you are not root or not a domain admin */
1381 if ((user.uid != sec_initial_uid()) &&
1382 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1384 goto done;
1387 for (snum = 0; snum < num_sessions; snum++) {
1389 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1390 strequal(session_list[snum].remote_machine, machine)) {
1392 if (user.uid != sec_initial_uid()) {
1393 not_root = True;
1394 become_root();
1397 if ((ret = message_send_pid(session_list[snum].pid, MSG_SHUTDOWN, NULL, 0, False)))
1398 r_u->status = WERR_OK;
1400 if (not_root)
1401 unbecome_root();
1405 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1408 done:
1409 SAFE_FREE(session_list);
1411 return r_u->status;
1414 /*******************************************************************
1415 Net share enum all.
1416 ********************************************************************/
1418 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1420 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1422 if (!pipe_access_check(p)) {
1423 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1424 return WERR_ACCESS_DENIED;
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);
1432 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1434 return r_u->status;
1437 /*******************************************************************
1438 Net share enum.
1439 ********************************************************************/
1441 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1443 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1445 if (!pipe_access_check(p)) {
1446 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1447 return WERR_ACCESS_DENIED;
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);
1455 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1457 return r_u->status;
1460 /*******************************************************************
1461 Net share get info.
1462 ********************************************************************/
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)
1466 fstring share_name;
1468 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
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);
1474 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1476 return r_u->status;
1479 /*******************************************************************
1480 Check a given DOS pathname is valid for a share.
1481 ********************************************************************/
1483 static char *valid_share_pathname(char *dos_pathname)
1485 char *ptr;
1487 /* Convert any '\' paths to '/' */
1488 unix_format(dos_pathname);
1489 unix_clean_name(dos_pathname);
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;
1496 /* Only abolute paths allowed. */
1497 if (*ptr != '/')
1498 return NULL;
1500 return ptr;
1503 /*******************************************************************
1504 Net share set info. Modify share details.
1505 ********************************************************************/
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)
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;
1522 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1524 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1526 r_u->parm_error = 0;
1528 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1529 return WERR_ACCESS_DENIED;
1531 snum = find_service(share_name);
1533 /* Does this share exist ? */
1534 if (snum < 0)
1535 return WERR_INVALID_NAME;
1537 /* No change to printer shares. */
1538 if (lp_print_ok(snum))
1539 return WERR_ACCESS_DENIED;
1541 get_current_user(&user,p);
1543 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1545 /* fail out now if you are not root and not a disk op */
1547 if ( user.uid != sec_initial_uid() && !is_disk_op )
1548 return WERR_ACCESS_DENIED;
1550 switch (q_u->info_level) {
1551 case 1:
1552 pstrcpy(pathname, lp_pathname(snum));
1553 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1554 type = q_u->info.share.info2.info_2.type;
1555 psd = NULL;
1556 break;
1557 case 2:
1558 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment));
1559 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname));
1560 type = q_u->info.share.info2.info_2.type;
1561 psd = NULL;
1562 break;
1563 #if 0
1564 /* not supported on set but here for completeness */
1565 case 501:
1566 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1567 type = q_u->info.share.info501.info_501.type;
1568 psd = NULL;
1569 break;
1570 #endif
1571 case 502:
1572 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment));
1573 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname));
1574 type = q_u->info.share.info502.info_502.type;
1575 psd = q_u->info.share.info502.info_502_str.sd;
1576 map_generic_share_sd_bits(psd);
1577 break;
1578 case 1004:
1579 pstrcpy(pathname, lp_pathname(snum));
1580 unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment));
1581 type = STYPE_DISKTREE;
1582 break;
1583 case 1005:
1584 /* XP re-sets the csc policy even if it wasn't changed by the
1585 user, so we must compare it to see if it's what is set in
1586 smb.conf, so that we can contine other ops like setting
1587 ACLs on a share */
1588 if (((q_u->info.share.info1005.share_info_flags &
1589 SHARE_1005_CSC_POLICY_MASK) >>
1590 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1591 return WERR_OK;
1592 else {
1593 DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1594 return WERR_ACCESS_DENIED;
1596 break;
1597 case 1006:
1598 case 1007:
1599 return WERR_ACCESS_DENIED;
1600 break;
1601 case 1501:
1602 pstrcpy(pathname, lp_pathname(snum));
1603 fstrcpy(comment, lp_comment(snum));
1604 psd = q_u->info.share.info1501.sdb->sec;
1605 map_generic_share_sd_bits(psd);
1606 type = STYPE_DISKTREE;
1607 break;
1608 default:
1609 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1610 return WERR_UNKNOWN_LEVEL;
1613 /* We can only modify disk shares. */
1614 if (type != STYPE_DISKTREE)
1615 return WERR_ACCESS_DENIED;
1617 /* Check if the pathname is valid. */
1618 if (!(path = valid_share_pathname( pathname )))
1619 return WERR_OBJECT_PATH_INVALID;
1621 /* Ensure share name, pathname and comment don't contain '"' characters. */
1622 string_replace(share_name, '"', ' ');
1623 string_replace(path, '"', ' ');
1624 string_replace(comment, '"', ' ');
1626 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1627 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1629 /* Only call modify function if something changed. */
1631 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) )
1633 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1634 return WERR_ACCESS_DENIED;
1636 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1637 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1639 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1641 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1643 if ( is_disk_op )
1644 become_root();
1646 if ( (ret = smbrun(command, NULL)) == 0 ) {
1647 /* Tell everyone we updated smb.conf. */
1648 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1651 if ( is_disk_op )
1652 unbecome_root();
1654 /********* END SeDiskOperatorPrivilege BLOCK *********/
1656 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
1658 if ( ret != 0 )
1659 return WERR_ACCESS_DENIED;
1660 } else {
1661 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1664 /* Replace SD if changed. */
1665 if (psd) {
1666 SEC_DESC *old_sd;
1667 size_t sd_size;
1669 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
1671 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1672 if (!set_share_security(p->mem_ctx, share_name, psd))
1673 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1674 share_name ));
1678 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1680 return WERR_OK;
1683 /*******************************************************************
1684 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1685 ********************************************************************/
1687 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
1689 struct current_user user;
1690 pstring command;
1691 fstring share_name;
1692 fstring comment;
1693 pstring pathname;
1694 int type;
1695 int snum;
1696 int ret;
1697 char *path;
1698 SEC_DESC *psd = NULL;
1699 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1700 BOOL is_disk_op;
1702 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1704 r_u->parm_error = 0;
1706 get_current_user(&user,p);
1708 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1710 if (user.uid != sec_initial_uid() && !is_disk_op )
1711 return WERR_ACCESS_DENIED;
1713 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1714 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1715 return WERR_ACCESS_DENIED;
1718 switch (q_u->info_level) {
1719 case 0:
1720 /* No path. Not enough info in a level 0 to do anything. */
1721 return WERR_ACCESS_DENIED;
1722 case 1:
1723 /* Not enough info in a level 1 to do anything. */
1724 return WERR_ACCESS_DENIED;
1725 case 2:
1726 unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
1727 unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
1728 unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
1729 type = q_u->info.share.info2.info_2.type;
1730 break;
1731 case 501:
1732 /* No path. Not enough info in a level 501 to do anything. */
1733 return WERR_ACCESS_DENIED;
1734 case 502:
1735 unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name));
1736 unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name));
1737 unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name));
1738 type = q_u->info.share.info502.info_502.type;
1739 psd = q_u->info.share.info502.info_502_str.sd;
1740 map_generic_share_sd_bits(psd);
1741 break;
1743 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1745 case 1004:
1746 case 1005:
1747 case 1006:
1748 case 1007:
1749 return WERR_ACCESS_DENIED;
1750 break;
1751 case 1501:
1752 /* DFS only level. */
1753 return WERR_ACCESS_DENIED;
1754 default:
1755 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1756 return WERR_UNKNOWN_LEVEL;
1759 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1760 return WERR_ACCESS_DENIED;
1762 snum = find_service(share_name);
1764 /* Share already exists. */
1765 if (snum >= 0)
1766 return WERR_ALREADY_EXISTS;
1768 /* We can only add disk shares. */
1769 if (type != STYPE_DISKTREE)
1770 return WERR_ACCESS_DENIED;
1772 /* Check if the pathname is valid. */
1773 if (!(path = valid_share_pathname( pathname )))
1774 return WERR_OBJECT_PATH_INVALID;
1776 /* Ensure share name, pathname and comment don't contain '"' characters. */
1777 string_replace(share_name, '"', ' ');
1778 string_replace(path, '"', ' ');
1779 string_replace(comment, '"', ' ');
1781 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1782 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1784 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1786 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1788 if ( is_disk_op )
1789 become_root();
1791 if ( (ret = smbrun(command, NULL)) == 0 ) {
1792 /* Tell everyone we updated smb.conf. */
1793 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1796 if ( is_disk_op )
1797 unbecome_root();
1799 /********* END SeDiskOperatorPrivilege BLOCK *********/
1801 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1803 if ( ret != 0 )
1804 return WERR_ACCESS_DENIED;
1806 if (psd) {
1807 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1808 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1813 * We don't call reload_services() here, the message will
1814 * cause this to be done before the next packet is read
1815 * from the client. JRA.
1818 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1820 return WERR_OK;
1823 /*******************************************************************
1824 Net share delete. Call "delete share command" with the share name as
1825 a parameter.
1826 ********************************************************************/
1828 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1830 struct current_user user;
1831 pstring command;
1832 fstring share_name;
1833 int ret;
1834 int snum;
1835 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1836 BOOL is_disk_op;
1838 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1840 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1842 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1843 return WERR_ACCESS_DENIED;
1845 snum = find_service(share_name);
1847 if (snum < 0)
1848 return WERR_NO_SUCH_SHARE;
1850 /* No change to printer shares. */
1851 if (lp_print_ok(snum))
1852 return WERR_ACCESS_DENIED;
1854 get_current_user(&user,p);
1856 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1858 if (user.uid != sec_initial_uid() && !is_disk_op )
1859 return WERR_ACCESS_DENIED;
1861 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1862 return WERR_ACCESS_DENIED;
1864 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1865 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1867 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1869 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1871 if ( is_disk_op )
1872 become_root();
1874 if ( (ret = smbrun(command, NULL)) == 0 ) {
1875 /* Tell everyone we updated smb.conf. */
1876 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1879 if ( is_disk_op )
1880 unbecome_root();
1882 /********* END SeDiskOperatorPrivilege BLOCK *********/
1884 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1886 if ( ret != 0 )
1887 return WERR_ACCESS_DENIED;
1889 /* Delete the SD in the database. */
1890 delete_share_security(snum);
1892 lp_killservice(snum);
1894 return WERR_OK;
1897 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1899 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1901 return _srv_net_share_del(p, q_u, r_u);
1904 /*******************************************************************
1905 time of day
1906 ********************************************************************/
1908 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1910 TIME_OF_DAY_INFO *tod;
1911 struct tm *t;
1912 time_t unixdate = time(NULL);
1914 tod = TALLOC_P(p->mem_ctx, TIME_OF_DAY_INFO);
1915 if (!tod)
1916 return WERR_NOMEM;
1918 ZERO_STRUCTP(tod);
1920 r_u->tod = tod;
1921 r_u->ptr_srv_tod = 0x1;
1922 r_u->status = WERR_OK;
1924 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1926 t = gmtime(&unixdate);
1928 /* set up the */
1929 init_time_of_day_info(tod,
1930 unixdate,
1932 t->tm_hour,
1933 t->tm_min,
1934 t->tm_sec,
1936 TimeDiff(unixdate)/60,
1937 10000,
1938 t->tm_mday,
1939 t->tm_mon + 1,
1940 1900+t->tm_year,
1941 t->tm_wday);
1943 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1945 return r_u->status;
1948 /***********************************************************************************
1949 Win9x NT tools get security descriptor.
1950 ***********************************************************************************/
1952 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1953 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1955 SEC_DESC *psd = NULL;
1956 size_t sd_size;
1957 DATA_BLOB null_pw;
1958 pstring filename;
1959 pstring qualname;
1960 files_struct *fsp = NULL;
1961 SMB_STRUCT_STAT st;
1962 BOOL bad_path;
1963 int access_mode;
1964 int action;
1965 NTSTATUS nt_status;
1966 struct current_user user;
1967 connection_struct *conn = NULL;
1968 BOOL became_user = False;
1970 ZERO_STRUCT(st);
1972 r_u->status = WERR_OK;
1974 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1976 /* Null password is ok - we are already an authenticated user... */
1977 null_pw = data_blob(NULL, 0);
1979 get_current_user(&user, p);
1981 become_root();
1982 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1983 unbecome_root();
1985 if (conn == NULL) {
1986 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1987 r_u->status = ntstatus_to_werror(nt_status);
1988 goto error_exit;
1991 if (!become_user(conn, conn->vuid)) {
1992 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1993 r_u->status = WERR_ACCESS_DENIED;
1994 goto error_exit;
1996 became_user = True;
1998 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
1999 unix_convert(filename, conn, NULL, &bad_path, &st);
2000 if (bad_path) {
2001 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
2002 r_u->status = WERR_ACCESS_DENIED;
2003 goto error_exit;
2006 if (!check_name(filename,conn)) {
2007 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
2008 r_u->status = WERR_ACCESS_DENIED;
2009 goto error_exit;
2012 fsp = open_file_shared(conn, filename, &st, SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
2013 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
2014 &access_mode, &action);
2016 if (!fsp) {
2017 /* Perhaps it is a directory */
2018 if (errno == EISDIR)
2019 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
2020 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
2022 if (!fsp) {
2023 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
2024 r_u->status = WERR_ACCESS_DENIED;
2025 goto error_exit;
2029 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2031 if (sd_size == 0) {
2032 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
2033 r_u->status = WERR_ACCESS_DENIED;
2034 goto error_exit;
2037 r_u->ptr_response = 1;
2038 r_u->size_response = sd_size;
2039 r_u->ptr_secdesc = 1;
2040 r_u->size_secdesc = sd_size;
2041 r_u->sec_desc = psd;
2043 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2045 close_file(fsp, True);
2046 unbecome_user();
2047 close_cnum(conn, user.vuid);
2048 return r_u->status;
2050 error_exit:
2052 if(fsp) {
2053 close_file(fsp, True);
2056 if (became_user)
2057 unbecome_user();
2059 if (conn)
2060 close_cnum(conn, user.vuid);
2062 return r_u->status;
2065 /***********************************************************************************
2066 Win9x NT tools set security descriptor.
2067 ***********************************************************************************/
2069 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
2070 SRV_R_NET_FILE_SET_SECDESC *r_u)
2072 BOOL ret;
2073 pstring filename;
2074 pstring qualname;
2075 DATA_BLOB null_pw;
2076 files_struct *fsp = NULL;
2077 SMB_STRUCT_STAT st;
2078 BOOL bad_path;
2079 int access_mode;
2080 int action;
2081 NTSTATUS nt_status;
2082 struct current_user user;
2083 connection_struct *conn = NULL;
2084 BOOL became_user = False;
2086 ZERO_STRUCT(st);
2088 r_u->status = WERR_OK;
2090 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2092 /* Null password is ok - we are already an authenticated user... */
2093 null_pw = data_blob(NULL, 0);
2095 get_current_user(&user, p);
2097 become_root();
2098 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2099 unbecome_root();
2101 if (conn == NULL) {
2102 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2103 r_u->status = ntstatus_to_werror(nt_status);
2104 goto error_exit;
2107 if (!become_user(conn, conn->vuid)) {
2108 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2109 r_u->status = WERR_ACCESS_DENIED;
2110 goto error_exit;
2112 became_user = True;
2114 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2115 unix_convert(filename, conn, NULL, &bad_path, &st);
2116 if (bad_path) {
2117 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2118 r_u->status = WERR_ACCESS_DENIED;
2119 goto error_exit;
2122 if (!check_name(filename,conn)) {
2123 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2124 r_u->status = WERR_ACCESS_DENIED;
2125 goto error_exit;
2129 fsp = open_file_shared(conn, filename, &st, SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDWR),
2130 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
2131 &access_mode, &action);
2133 if (!fsp) {
2134 /* Perhaps it is a directory */
2135 if (errno == EISDIR)
2136 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
2137 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
2139 if (!fsp) {
2140 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2141 r_u->status = WERR_ACCESS_DENIED;
2142 goto error_exit;
2146 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2148 if (ret == False) {
2149 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2150 r_u->status = WERR_ACCESS_DENIED;
2151 goto error_exit;
2154 close_file(fsp, True);
2155 unbecome_user();
2156 close_cnum(conn, user.vuid);
2157 return r_u->status;
2159 error_exit:
2161 if(fsp) {
2162 close_file(fsp, True);
2165 if (became_user)
2166 unbecome_user();
2168 if (conn)
2169 close_cnum(conn, user.vuid);
2171 return r_u->status;
2174 /***********************************************************************************
2175 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2176 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2177 These disks would the disks listed by this function.
2178 Users could then create shares relative to these disks. Watch out for moving these disks around.
2179 "Nigel Williams" <nigel@veritas.com>.
2180 ***********************************************************************************/
2182 static const char *server_disks[] = {"C:"};
2184 static uint32 get_server_disk_count(void)
2186 return sizeof(server_disks)/sizeof(server_disks[0]);
2189 static uint32 init_server_disk_enum(uint32 *resume)
2191 uint32 server_disk_count = get_server_disk_count();
2193 /*resume can be an offset into the list for now*/
2195 if(*resume & 0x80000000)
2196 *resume = 0;
2198 if(*resume > server_disk_count)
2199 *resume = server_disk_count;
2201 return server_disk_count - *resume;
2204 static const char *next_server_disk_enum(uint32 *resume)
2206 const char *disk;
2208 if(init_server_disk_enum(resume) == 0)
2209 return NULL;
2211 disk = server_disks[*resume];
2213 (*resume)++;
2215 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2217 return disk;
2220 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2222 uint32 i;
2223 const char *disk_name;
2224 TALLOC_CTX *ctx = p->mem_ctx;
2225 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2227 r_u->status=WERR_OK;
2229 r_u->total_entries = init_server_disk_enum(&resume);
2231 r_u->disk_enum_ctr.unknown = 0;
2233 if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2234 return WERR_NOMEM;
2237 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2239 /*allow one DISK_INFO for null terminator*/
2241 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2243 r_u->disk_enum_ctr.entries_read++;
2245 /*copy disk name into a unicode string*/
2247 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2250 /* add a terminating null string. Is this there if there is more data to come? */
2252 r_u->disk_enum_ctr.entries_read++;
2254 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2256 init_enum_hnd(&r_u->enum_hnd, resume);
2258 return r_u->status;
2261 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2263 int snum;
2264 fstring share_name;
2266 r_u->status=WERR_OK;
2268 switch(q_u->type) {
2270 case 0x9:
2272 /*check if share name is ok*/
2273 /*also check if we already have a share with this name*/
2275 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
2276 snum = find_service(share_name);
2278 /* Share already exists. */
2279 if (snum >= 0)
2280 r_u->status = WERR_ALREADY_EXISTS;
2281 break;
2283 default:
2284 /*unsupported type*/
2285 r_u->status = WERR_UNKNOWN_LEVEL;
2286 break;
2289 return r_u->status;