r6016: Give access only to root and Domain Users
[Samba/bb.git] / source / rpc_server / srv_srvsvc_nt.c
blob5dd2e6e47f3bc77ca1c2c9afebae8f645e106542
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 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_RPC_SRV
30 /*******************************************************************
31 Utility function to get the 'type' of a share from an snum.
32 ********************************************************************/
33 static uint32 get_share_type(int snum)
35 char *net_name = lp_servicename(snum);
36 int len_net_name = strlen(net_name);
38 /* work out the share type */
39 uint32 type = STYPE_DISKTREE;
41 if (lp_print_ok(snum))
42 type = STYPE_PRINTQ;
43 if (strequal(lp_fstype(snum), "IPC"))
44 type = STYPE_IPC;
45 if (net_name[len_net_name] == '$')
46 type |= STYPE_HIDDEN;
48 return type;
51 /*******************************************************************
52 Fill in a share info level 0 structure.
53 ********************************************************************/
55 static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum)
57 pstring net_name;
59 pstrcpy(net_name, lp_servicename(snum));
61 init_srv_share_info0(&sh0->info_0, net_name);
62 init_srv_share_info0_str(&sh0->info_0_str, net_name);
65 /*******************************************************************
66 Fill in a share info level 1 structure.
67 ********************************************************************/
69 static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
71 pstring remark;
73 char *net_name = lp_servicename(snum);
74 pstrcpy(remark, lp_comment(snum));
75 standard_sub_conn(p->conn, remark,sizeof(remark));
77 init_srv_share_info1(&sh1->info_1, net_name, get_share_type(snum), remark);
78 init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
81 /*******************************************************************
82 Fill in a share info level 2 structure.
83 ********************************************************************/
85 static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
87 pstring remark;
88 pstring path;
89 pstring passwd;
91 char *net_name = lp_servicename(snum);
92 pstrcpy(remark, lp_comment(snum));
93 standard_sub_conn(p->conn, remark,sizeof(remark));
94 pstrcpy(path, "C:");
95 pstrcat(path, lp_pathname(snum));
98 * Change / to \\ so that win2k will see it as a valid path. This was added to
99 * enable use of browsing in win2k add share dialog.
102 string_replace(path, '/', '\\');
104 pstrcpy(passwd, "");
106 init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd);
107 init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
110 /*******************************************************************
111 What to do when smb.conf is updated.
112 ********************************************************************/
114 static void smb_conf_updated(int msg_type, pid_t src, void *buf, size_t len)
116 DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
117 reload_services(False);
120 /*******************************************************************
121 Create the share security tdb.
122 ********************************************************************/
124 static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
125 #define SHARE_DATABASE_VERSION_V1 1
126 #define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
128 BOOL share_info_db_init(void)
130 static pid_t local_pid;
131 const char *vstring = "INFO/version";
132 int32 vers_id;
134 if (share_tdb && local_pid == sys_getpid())
135 return True;
136 share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
137 if (!share_tdb) {
138 DEBUG(0,("Failed to open share info database %s (%s)\n",
139 lock_path("share_info.tdb"), strerror(errno) ));
140 return False;
143 local_pid = sys_getpid();
145 /* handle a Samba upgrade */
146 tdb_lock_bystring(share_tdb, vstring, 0);
148 /* Cope with byte-reversed older versions of the db. */
149 vers_id = tdb_fetch_int32(share_tdb, vstring);
150 if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
151 /* Written on a bigendian machine with old fetch_int code. Save as le. */
152 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
153 vers_id = SHARE_DATABASE_VERSION_V2;
156 if (vers_id != SHARE_DATABASE_VERSION_V2) {
157 tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
158 tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
160 tdb_unlock_bystring(share_tdb, vstring);
162 message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
164 return True;
167 /*******************************************************************
168 Fake up a Everyone, full access as a default.
169 ********************************************************************/
171 static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
173 extern DOM_SID global_sid_World;
174 extern struct generic_mapping file_generic_mapping;
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 extern struct generic_mapping file_generic_mapping;
297 int i;
298 SEC_ACL *ps_dacl = NULL;
300 if (!psd)
301 return;
303 ps_dacl = psd->dacl;
304 if (!ps_dacl)
305 return;
307 for (i = 0; i < ps_dacl->num_aces; i++) {
308 SEC_ACE *psa = &ps_dacl->ace[i];
309 uint32 orig_mask = psa->info.mask;
311 se_map_generic(&psa->info.mask, &file_generic_mapping);
312 psa->info.mask |= orig_mask;
316 /*******************************************************************
317 Can this user access with share with the required permissions ?
318 ********************************************************************/
320 BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, uint32 desired_access)
322 uint32 granted;
323 NTSTATUS status;
324 TALLOC_CTX *mem_ctx = NULL;
325 SEC_DESC *psd = NULL;
326 size_t sd_size;
327 NT_USER_TOKEN *token = NULL;
328 BOOL ret = True;
330 mem_ctx = talloc_init("share_access_check");
331 if (mem_ctx == NULL)
332 return False;
334 psd = get_share_security(mem_ctx, snum, &sd_size);
336 if (!psd)
337 goto out;
339 if (conn->nt_user_token)
340 token = conn->nt_user_token;
341 else
342 token = vuser->nt_user_token;
344 ret = se_access_check(psd, token, desired_access, &granted, &status);
346 out:
348 talloc_destroy(mem_ctx);
350 return ret;
353 /*******************************************************************
354 Fill in a share info level 501 structure.
355 ********************************************************************/
357 static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
359 pstring remark;
361 const char *net_name = lp_servicename(snum);
362 pstrcpy(remark, lp_comment(snum));
363 standard_sub_conn(p->conn, remark, sizeof(remark));
365 init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
366 init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
369 /*******************************************************************
370 Fill in a share info level 502 structure.
371 ********************************************************************/
373 static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
375 pstring net_name;
376 pstring remark;
377 pstring path;
378 pstring passwd;
379 SEC_DESC *sd;
380 size_t sd_size;
381 TALLOC_CTX *ctx = p->mem_ctx;
384 ZERO_STRUCTP(sh502);
386 pstrcpy(net_name, lp_servicename(snum));
387 pstrcpy(remark, lp_comment(snum));
388 standard_sub_conn(p->conn, remark,sizeof(remark));
389 pstrcpy(path, "C:");
390 pstrcat(path, lp_pathname(snum));
393 * Change / to \\ so that win2k will see it as a valid path. This was added to
394 * enable use of browsing in win2k add share dialog.
397 string_replace(path, '/', '\\');
399 pstrcpy(passwd, "");
401 sd = get_share_security(ctx, snum, &sd_size);
403 init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size);
404 init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size);
407 /***************************************************************************
408 Fill in a share info level 1004 structure.
409 ***************************************************************************/
411 static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
413 pstring remark;
415 pstrcpy(remark, lp_comment(snum));
416 standard_sub_conn(p->conn, remark, sizeof(remark));
418 ZERO_STRUCTP(sh1004);
420 init_srv_share_info1004(&sh1004->info_1004, remark);
421 init_srv_share_info1004_str(&sh1004->info_1004_str, remark);
424 /***************************************************************************
425 Fill in a share info level 1005 structure.
426 ***************************************************************************/
428 static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum)
430 sh1005->share_info_flags = 0;
432 if(lp_host_msdfs() && lp_msdfs_root(snum))
433 sh1005->share_info_flags |=
434 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
435 sh1005->share_info_flags |=
436 lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
438 /***************************************************************************
439 Fill in a share info level 1006 structure.
440 ***************************************************************************/
442 static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum)
444 sh1006->max_uses = -1;
447 /***************************************************************************
448 Fill in a share info level 1007 structure.
449 ***************************************************************************/
451 static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum)
453 pstring alternate_directory_name = "";
454 uint32 flags = 0;
456 ZERO_STRUCTP(sh1007);
458 init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name);
459 init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name);
462 /*******************************************************************
463 Fill in a share info level 1501 structure.
464 ********************************************************************/
466 static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum)
468 SEC_DESC *sd;
469 size_t sd_size;
470 TALLOC_CTX *ctx = p->mem_ctx;
472 ZERO_STRUCTP(sh1501);
474 sd = get_share_security(ctx, snum, &sd_size);
476 sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
479 /*******************************************************************
480 True if it ends in '$'.
481 ********************************************************************/
483 static BOOL is_hidden_share(int snum)
485 const char *net_name = lp_servicename(snum);
487 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
490 /*******************************************************************
491 Fill in a share info structure.
492 ********************************************************************/
494 static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
495 uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
497 int num_entries = 0;
498 int num_services = lp_numservices();
499 int snum;
500 TALLOC_CTX *ctx = p->mem_ctx;
502 DEBUG(5,("init_srv_share_info_ctr\n"));
504 ZERO_STRUCTPN(ctr);
506 ctr->info_level = ctr->switch_value = info_level;
507 *resume_hnd = 0;
509 /* Count the number of entries. */
510 for (snum = 0; snum < num_services; snum++) {
511 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) )
512 num_entries++;
515 *total_entries = num_entries;
516 ctr->num_entries2 = ctr->num_entries = num_entries;
517 ctr->ptr_share_info = ctr->ptr_entries = 1;
519 if (!num_entries)
520 return True;
522 switch (info_level) {
523 case 0:
525 SRV_SHARE_INFO_0 *info0 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_0, num_entries);
526 int i = 0;
528 if (!info0) {
529 return False;
532 for (snum = *resume_hnd; snum < num_services; snum++) {
533 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
534 init_srv_share_info_0(p, &info0[i++], snum);
538 ctr->share.info0 = info0;
539 break;
543 case 1:
545 SRV_SHARE_INFO_1 *info1 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1, num_entries);
546 int i = 0;
548 if (!info1) {
549 return False;
552 for (snum = *resume_hnd; snum < num_services; snum++) {
553 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
554 init_srv_share_info_1(p, &info1[i++], snum);
558 ctr->share.info1 = info1;
559 break;
562 case 2:
564 SRV_SHARE_INFO_2 *info2 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_2, num_entries);
565 int i = 0;
567 if (!info2) {
568 return False;
571 for (snum = *resume_hnd; snum < num_services; snum++) {
572 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
573 init_srv_share_info_2(p, &info2[i++], snum);
577 ctr->share.info2 = info2;
578 break;
581 case 501:
583 SRV_SHARE_INFO_501 *info501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_501, num_entries);
584 int i = 0;
586 if (!info501) {
587 return False;
590 for (snum = *resume_hnd; snum < num_services; snum++) {
591 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
592 init_srv_share_info_501(p, &info501[i++], snum);
596 ctr->share.info501 = info501;
597 break;
600 case 502:
602 SRV_SHARE_INFO_502 *info502 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_502, num_entries);
603 int i = 0;
605 if (!info502) {
606 return False;
609 for (snum = *resume_hnd; snum < num_services; snum++) {
610 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
611 init_srv_share_info_502(p, &info502[i++], snum);
615 ctr->share.info502 = info502;
616 break;
619 /* here for completeness but not currently used with enum (1004 - 1501)*/
621 case 1004:
623 SRV_SHARE_INFO_1004 *info1004 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1004, num_entries);
624 int i = 0;
626 if (!info1004) {
627 return False;
630 for (snum = *resume_hnd; snum < num_services; snum++) {
631 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
632 init_srv_share_info_1004(p, &info1004[i++], snum);
636 ctr->share.info1004 = info1004;
637 break;
640 case 1005:
642 SRV_SHARE_INFO_1005 *info1005 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1005, num_entries);
643 int i = 0;
645 if (!info1005) {
646 return False;
649 for (snum = *resume_hnd; snum < num_services; snum++) {
650 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
651 init_srv_share_info_1005(p, &info1005[i++], snum);
655 ctr->share.info1005 = info1005;
656 break;
659 case 1006:
661 SRV_SHARE_INFO_1006 *info1006 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1006, num_entries);
662 int i = 0;
664 if (!info1006) {
665 return False;
668 for (snum = *resume_hnd; snum < num_services; snum++) {
669 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
670 init_srv_share_info_1006(p, &info1006[i++], snum);
674 ctr->share.info1006 = info1006;
675 break;
678 case 1007:
680 SRV_SHARE_INFO_1007 *info1007 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1007, num_entries);
681 int i = 0;
683 if (!info1007) {
684 return False;
687 for (snum = *resume_hnd; snum < num_services; snum++) {
688 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
689 init_srv_share_info_1007(p, &info1007[i++], snum);
693 ctr->share.info1007 = info1007;
694 break;
697 case 1501:
699 SRV_SHARE_INFO_1501 *info1501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1501, num_entries);
700 int i = 0;
702 if (!info1501) {
703 return False;
706 for (snum = *resume_hnd; snum < num_services; snum++) {
707 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
708 init_srv_share_info_1501(p, &info1501[i++], snum);
712 ctr->share.info1501 = info1501;
713 break;
715 default:
716 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
717 return False;
720 return True;
723 /*******************************************************************
724 Inits a SRV_R_NET_SHARE_ENUM structure.
725 ********************************************************************/
727 static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
728 uint32 info_level, uint32 resume_hnd, BOOL all)
730 DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
732 if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
733 &resume_hnd, &r_n->total_entries, all)) {
734 r_n->status = WERR_OK;
735 } else {
736 r_n->status = WERR_UNKNOWN_LEVEL;
739 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
742 /*******************************************************************
743 Inits a SRV_R_NET_SHARE_GET_INFO structure.
744 ********************************************************************/
746 static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
747 char *share_name, uint32 info_level)
749 WERROR status = WERR_OK;
750 int snum;
752 DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
754 r_n->info.switch_value = info_level;
756 snum = find_service(share_name);
758 if (snum >= 0) {
759 switch (info_level) {
760 case 0:
761 init_srv_share_info_0(p, &r_n->info.share.info0, snum);
762 break;
763 case 1:
764 init_srv_share_info_1(p, &r_n->info.share.info1, snum);
765 break;
766 case 2:
767 init_srv_share_info_2(p, &r_n->info.share.info2, snum);
768 break;
769 case 501:
770 init_srv_share_info_501(p, &r_n->info.share.info501, snum);
771 break;
772 case 502:
773 init_srv_share_info_502(p, &r_n->info.share.info502, snum);
774 break;
776 /* here for completeness */
777 case 1004:
778 init_srv_share_info_1004(p, &r_n->info.share.info1004, snum);
779 break;
780 case 1005:
781 init_srv_share_info_1005(p, &r_n->info.share.info1005, snum);
782 break;
784 /* here for completeness 1006 - 1501 */
785 case 1006:
786 init_srv_share_info_1006(p, &r_n->info.share.info1006, snum);
787 break;
788 case 1007:
789 init_srv_share_info_1007(p, &r_n->info.share.info1007, snum);
790 break;
791 case 1501:
792 init_srv_share_info_1501(p, &r_n->info.share.info1501, snum);
793 break;
794 default:
795 DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
796 status = WERR_UNKNOWN_LEVEL;
797 break;
799 } else {
800 status = WERR_INVALID_NAME;
803 r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0;
804 r_n->status = status;
807 /*******************************************************************
808 fill in a sess info level 1 structure.
809 ********************************************************************/
811 static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
813 init_srv_sess_info0(se0, name);
814 init_srv_sess_info0_str(str0, name);
817 /*******************************************************************
818 fill in a sess info level 0 structure.
819 ********************************************************************/
821 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
823 struct sessionid *session_list;
824 uint32 num_entries = 0;
825 (*stot) = list_sessions(&session_list);
827 if (ss0 == NULL) {
828 (*snum) = 0;
829 SAFE_FREE(session_list);
830 return;
833 DEBUG(5,("init_srv_sess_0_ss0\n"));
835 if (snum) {
836 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
837 init_srv_sess_0_info(&ss0->info_0[num_entries],
838 &ss0->info_0_str[num_entries], session_list[(*snum)].remote_machine);
840 /* move on to creating next session */
841 /* move on to creating next sess */
842 num_entries++;
845 ss0->num_entries_read = num_entries;
846 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
847 ss0->num_entries_read2 = num_entries;
849 if ((*snum) >= (*stot)) {
850 (*snum) = 0;
853 } else {
854 ss0->num_entries_read = 0;
855 ss0->ptr_sess_info = 0;
856 ss0->num_entries_read2 = 0;
858 SAFE_FREE(session_list);
861 /*******************************************************************
862 fill in a sess info level 1 structure.
863 ********************************************************************/
865 static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
866 char *name, char *user,
867 uint32 num_opens,
868 uint32 open_time, uint32 idle_time,
869 uint32 usr_flgs)
871 init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
872 init_srv_sess_info1_str(str1, name, user);
875 /*******************************************************************
876 fill in a sess info level 1 structure.
877 ********************************************************************/
879 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
881 struct sessionid *session_list;
882 uint32 num_entries = 0;
883 (*stot) = list_sessions(&session_list);
885 if (ss1 == NULL) {
886 (*snum) = 0;
887 SAFE_FREE(session_list);
888 return;
891 DEBUG(5,("init_srv_sess_1_ss1\n"));
893 if (snum) {
894 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
895 init_srv_sess_1_info(&ss1->info_1[num_entries],
896 &ss1->info_1_str[num_entries],
897 session_list[*snum].remote_machine,
898 session_list[*snum].username,
899 1, 10, 5, 0);
901 /* move on to creating next session */
902 /* move on to creating next sess */
903 num_entries++;
906 ss1->num_entries_read = num_entries;
907 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
908 ss1->num_entries_read2 = num_entries;
910 if ((*snum) >= (*stot)) {
911 (*snum) = 0;
914 } else {
915 ss1->num_entries_read = 0;
916 ss1->ptr_sess_info = 0;
917 ss1->num_entries_read2 = 0;
919 (*stot) = 0;
923 /*******************************************************************
924 makes a SRV_R_NET_SESS_ENUM structure.
925 ********************************************************************/
927 static WERROR init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
928 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
930 WERROR status = WERR_OK;
931 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
933 ctr->switch_value = switch_value;
935 switch (switch_value) {
936 case 0:
937 init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
938 ctr->ptr_sess_ctr = 1;
939 break;
940 case 1:
941 init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
942 ctr->ptr_sess_ctr = 1;
943 break;
944 default:
945 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
946 (*resume_hnd) = 0;
947 (*total_entries) = 0;
948 ctr->ptr_sess_ctr = 0;
949 status = WERR_UNKNOWN_LEVEL;
950 break;
953 return status;
956 /*******************************************************************
957 makes a SRV_R_NET_SESS_ENUM structure.
958 ********************************************************************/
960 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
961 uint32 resume_hnd, int sess_level, int switch_value)
963 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
965 r_n->sess_level = sess_level;
967 if (sess_level == -1)
968 r_n->status = WERR_UNKNOWN_LEVEL;
969 else
970 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
972 if (!W_ERROR_IS_OK(r_n->status))
973 resume_hnd = 0;
975 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
978 /*******************************************************************
979 fill in a conn info level 0 structure.
980 ********************************************************************/
982 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
984 uint32 num_entries = 0;
985 (*stot) = 1;
987 if (ss0 == NULL) {
988 (*snum) = 0;
989 return;
992 DEBUG(5,("init_srv_conn_0_ss0\n"));
994 if (snum) {
995 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
997 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
999 /* move on to creating next connection */
1000 /* move on to creating next conn */
1001 num_entries++;
1004 ss0->num_entries_read = num_entries;
1005 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
1006 ss0->num_entries_read2 = num_entries;
1008 if ((*snum) >= (*stot)) {
1009 (*snum) = 0;
1012 } else {
1013 ss0->num_entries_read = 0;
1014 ss0->ptr_conn_info = 0;
1015 ss0->num_entries_read2 = 0;
1017 (*stot) = 0;
1021 /*******************************************************************
1022 fill in a conn info level 1 structure.
1023 ********************************************************************/
1025 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
1026 uint32 id, uint32 type,
1027 uint32 num_opens, uint32 num_users, uint32 open_time,
1028 const char *usr_name, const char *net_name)
1030 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
1031 init_srv_conn_info1_str(str1, usr_name, net_name);
1034 /*******************************************************************
1035 fill in a conn info level 1 structure.
1036 ********************************************************************/
1038 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
1040 uint32 num_entries = 0;
1041 (*stot) = 1;
1043 if (ss1 == NULL) {
1044 (*snum) = 0;
1045 return;
1048 DEBUG(5,("init_srv_conn_1_ss1\n"));
1050 if (snum) {
1051 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
1052 init_srv_conn_1_info(&ss1->info_1[num_entries],
1053 &ss1->info_1_str[num_entries],
1054 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
1056 /* move on to creating next connection */
1057 /* move on to creating next conn */
1058 num_entries++;
1061 ss1->num_entries_read = num_entries;
1062 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
1063 ss1->num_entries_read2 = num_entries;
1066 if ((*snum) >= (*stot)) {
1067 (*snum) = 0;
1070 } else {
1071 ss1->num_entries_read = 0;
1072 ss1->ptr_conn_info = 0;
1073 ss1->num_entries_read2 = 0;
1075 (*stot) = 0;
1079 /*******************************************************************
1080 makes a SRV_R_NET_CONN_ENUM structure.
1081 ********************************************************************/
1083 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1084 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1086 WERROR status = WERR_OK;
1087 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1089 ctr->switch_value = switch_value;
1091 switch (switch_value) {
1092 case 0:
1093 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1094 ctr->ptr_conn_ctr = 1;
1095 break;
1096 case 1:
1097 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1098 ctr->ptr_conn_ctr = 1;
1099 break;
1100 default:
1101 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1102 (*resume_hnd = 0);
1103 (*total_entries) = 0;
1104 ctr->ptr_conn_ctr = 0;
1105 status = WERR_UNKNOWN_LEVEL;
1106 break;
1109 return status;
1112 /*******************************************************************
1113 makes a SRV_R_NET_CONN_ENUM structure.
1114 ********************************************************************/
1116 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1117 uint32 resume_hnd, int conn_level, int switch_value)
1119 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1121 r_n->conn_level = conn_level;
1122 if (conn_level == -1)
1123 r_n->status = WERR_UNKNOWN_LEVEL;
1124 else
1125 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1127 if (!W_ERROR_IS_OK(r_n->status))
1128 resume_hnd = 0;
1130 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1133 /*******************************************************************
1134 makes a SRV_R_NET_FILE_ENUM structure.
1135 ********************************************************************/
1137 static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
1138 int switch_value, uint32 *resume_hnd,
1139 uint32 *total_entries)
1141 WERROR status = WERR_OK;
1142 TALLOC_CTX *ctx = p->mem_ctx;
1143 DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
1144 *total_entries = 1; /* dummy entries only, for */
1146 ctr->switch_value = switch_value;
1147 ctr->num_entries = *total_entries - *resume_hnd;
1148 ctr->num_entries2 = ctr->num_entries;
1150 switch (switch_value) {
1151 case 3: {
1152 int i;
1153 if (*total_entries > 0) {
1154 ctr->ptr_entries = 1;
1155 ctr->file.info3 = TALLOC_ARRAY(ctx, SRV_FILE_INFO_3, ctr->num_entries);
1157 for (i=0 ;i<ctr->num_entries;i++) {
1158 init_srv_file_info3(&ctr->file.info3[i].info_3, i+*resume_hnd, 0x35, 0, "\\PIPE\\samr", "dummy user");
1159 init_srv_file_info3_str(&ctr->file.info3[i].info_3_str, "\\PIPE\\samr", "dummy user");
1162 ctr->ptr_file_info = 1;
1163 *resume_hnd = 0;
1164 break;
1166 default:
1167 DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
1168 (*resume_hnd = 0);
1169 (*total_entries) = 0;
1170 ctr->ptr_entries = 0;
1171 status = WERR_UNKNOWN_LEVEL;
1172 break;
1175 return status;
1178 /*******************************************************************
1179 makes a SRV_R_NET_FILE_ENUM structure.
1180 ********************************************************************/
1182 static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n,
1183 uint32 resume_hnd, int file_level, int switch_value)
1185 DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
1187 r_n->file_level = file_level;
1188 if (file_level == 0)
1189 r_n->status = WERR_UNKNOWN_LEVEL;
1190 else
1191 r_n->status = init_srv_file_info_ctr(p, &r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
1193 if (!W_ERROR_IS_OK(r_n->status))
1194 resume_hnd = 0;
1196 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1199 /*******************************************************************
1200 net server get info
1201 ********************************************************************/
1203 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)
1205 WERROR status = WERR_OK;
1206 SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR);
1208 if (!ctr)
1209 return WERR_NOMEM;
1211 ZERO_STRUCTP(ctr);
1213 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1215 if (!pipe_access_check(p)) {
1216 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1217 return WERR_ACCESS_DENIED;
1220 switch (q_u->switch_value) {
1222 /* Technically level 102 should only be available to
1223 Administrators but there isn't anything super-secret
1224 here, as most of it is made up. */
1226 case 102:
1227 init_srv_info_102(&ctr->srv.sv102,
1228 500, global_myname(),
1229 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1230 lp_major_announce_version(), lp_minor_announce_version(),
1231 lp_default_server_announce(),
1232 0xffffffff, /* users */
1233 0xf, /* disc */
1234 0, /* hidden */
1235 240, /* announce */
1236 3000, /* announce delta */
1237 100000, /* licenses */
1238 "c:\\"); /* user path */
1239 break;
1240 case 101:
1241 init_srv_info_101(&ctr->srv.sv101,
1242 500, global_myname(),
1243 lp_major_announce_version(), lp_minor_announce_version(),
1244 lp_default_server_announce(),
1245 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1246 break;
1247 case 100:
1248 init_srv_info_100(&ctr->srv.sv100, 500, global_myname());
1249 break;
1250 default:
1251 status = WERR_UNKNOWN_LEVEL;
1252 break;
1255 /* set up the net server get info structure */
1256 init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status);
1258 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1260 return r_u->status;
1263 /*******************************************************************
1264 net server set info
1265 ********************************************************************/
1267 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)
1269 WERROR status = WERR_OK;
1271 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1273 /* Set up the net server set info structure. */
1275 init_srv_r_net_srv_set_info(r_u, 0x0, status);
1277 DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
1279 return r_u->status;
1282 /*******************************************************************
1283 net file enum
1284 ********************************************************************/
1286 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1288 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1290 /* set up the */
1291 init_srv_r_net_file_enum(p, r_u,
1292 get_enum_hnd(&q_u->enum_hnd),
1293 q_u->file_level,
1294 q_u->ctr.switch_value);
1296 DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
1298 return r_u->status;
1301 /*******************************************************************
1302 net conn enum
1303 ********************************************************************/
1305 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1307 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1309 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_CONN_INFO_CTR);
1310 if (!r_u->ctr)
1311 return WERR_NOMEM;
1313 ZERO_STRUCTP(r_u->ctr);
1315 /* set up the */
1316 init_srv_r_net_conn_enum(r_u,
1317 get_enum_hnd(&q_u->enum_hnd),
1318 q_u->conn_level,
1319 q_u->ctr->switch_value);
1321 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1323 return r_u->status;
1326 /*******************************************************************
1327 net sess enum
1328 ********************************************************************/
1330 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1332 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1334 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_SESS_INFO_CTR);
1335 if (!r_u->ctr)
1336 return WERR_NOMEM;
1338 ZERO_STRUCTP(r_u->ctr);
1340 /* set up the */
1341 init_srv_r_net_sess_enum(r_u,
1342 get_enum_hnd(&q_u->enum_hnd),
1343 q_u->sess_level,
1344 q_u->ctr->switch_value);
1346 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1348 return r_u->status;
1351 /*******************************************************************
1352 net sess del
1353 ********************************************************************/
1355 WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u)
1357 struct sessionid *session_list;
1358 struct current_user user;
1359 int num_sessions, snum, ret;
1360 fstring username;
1361 fstring machine;
1362 /* SE_PRIV se_diskop = SE_DISK_OPERATOR; / * Is disk op appropriate here ? JRA. * /
1363 BOOL is_disk_op = False; / * No. SSS. :) */
1365 rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name);
1366 rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name);
1368 /* strip leading backslashes if any */
1369 while (machine[0] == '\\') {
1370 memmove(machine, &machine[1], strlen(machine));
1373 num_sessions = list_sessions(&session_list);
1375 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1377 /* is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop ); */
1379 r_u->status = WERR_ACCESS_DENIED;
1381 get_current_user(&user, p);
1382 /* fail out now if you are not root */
1383 /* or at least domain admins */
1384 if ((user.uid != sec_initial_uid()) &&
1385 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1387 goto done;
1390 for (snum = 0; snum < num_sessions; snum++) {
1392 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1393 strequal(session_list[snum].remote_machine, machine)) {
1395 if (user.uid != sec_initial_uid()) {
1396 become_root();
1398 if ((ret = message_send_pid(session_list[snum].pid, MSG_SHUTDOWN, NULL, 0, False))) {
1399 r_u->status = WERR_OK;
1400 } else {
1401 r_u->status = WERR_ACCESS_DENIED;
1403 if (user.uid != sec_initial_uid()) {
1404 unbecome_root();
1409 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1412 done:
1413 SAFE_FREE(session_list);
1415 return r_u->status;
1418 /*******************************************************************
1419 Net share enum all.
1420 ********************************************************************/
1422 WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1424 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1426 if (!pipe_access_check(p)) {
1427 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1428 return WERR_ACCESS_DENIED;
1431 /* Create the list of shares for the response. */
1432 init_srv_r_net_share_enum(p, r_u,
1433 q_u->ctr.info_level,
1434 get_enum_hnd(&q_u->enum_hnd), True);
1436 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1438 return r_u->status;
1441 /*******************************************************************
1442 Net share enum.
1443 ********************************************************************/
1445 WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
1447 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1449 if (!pipe_access_check(p)) {
1450 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1451 return WERR_ACCESS_DENIED;
1454 /* Create the list of shares for the response. */
1455 init_srv_r_net_share_enum(p, r_u,
1456 q_u->ctr.info_level,
1457 get_enum_hnd(&q_u->enum_hnd), False);
1459 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1461 return r_u->status;
1464 /*******************************************************************
1465 Net share get info.
1466 ********************************************************************/
1468 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)
1470 fstring share_name;
1472 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1474 /* Create the list of shares for the response. */
1475 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1476 init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
1478 DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
1480 return r_u->status;
1483 /*******************************************************************
1484 Check a given DOS pathname is valid for a share.
1485 ********************************************************************/
1487 static char *valid_share_pathname(char *dos_pathname)
1489 char *ptr;
1491 /* Convert any '\' paths to '/' */
1492 unix_format(dos_pathname);
1493 unix_clean_name(dos_pathname);
1495 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1496 ptr = dos_pathname;
1497 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1498 ptr += 2;
1500 /* Only abolute paths allowed. */
1501 if (*ptr != '/')
1502 return NULL;
1504 return ptr;
1507 /*******************************************************************
1508 Net share set info. Modify share details.
1509 ********************************************************************/
1511 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)
1513 struct current_user user;
1514 pstring command;
1515 fstring share_name;
1516 fstring comment;
1517 pstring pathname;
1518 int type;
1519 int snum;
1520 int ret;
1521 char *path;
1522 SEC_DESC *psd = NULL;
1523 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1524 BOOL is_disk_op = False;
1526 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1528 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1530 r_u->parm_error = 0;
1532 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1533 return WERR_ACCESS_DENIED;
1535 snum = find_service(share_name);
1537 /* Does this share exist ? */
1538 if (snum < 0)
1539 return WERR_INVALID_NAME;
1541 /* No change to printer shares. */
1542 if (lp_print_ok(snum))
1543 return WERR_ACCESS_DENIED;
1545 get_current_user(&user,p);
1547 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1549 /* fail out now if you are not root and not a disk op */
1551 if ( user.uid != sec_initial_uid() && !is_disk_op )
1552 return WERR_ACCESS_DENIED;
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;
1600 break;
1601 case 1006:
1602 case 1007:
1603 return WERR_ACCESS_DENIED;
1604 break;
1605 case 1501:
1606 pstrcpy(pathname, lp_pathname(snum));
1607 fstrcpy(comment, lp_comment(snum));
1608 psd = q_u->info.share.info1501.sdb->sec;
1609 map_generic_share_sd_bits(psd);
1610 type = STYPE_DISKTREE;
1611 break;
1612 default:
1613 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level));
1614 return WERR_UNKNOWN_LEVEL;
1617 /* We can only modify disk shares. */
1618 if (type != STYPE_DISKTREE)
1619 return WERR_ACCESS_DENIED;
1621 /* Check if the pathname is valid. */
1622 if (!(path = valid_share_pathname( pathname )))
1623 return WERR_OBJECT_PATH_INVALID;
1625 /* Ensure share name, pathname and comment don't contain '"' characters. */
1626 string_replace(share_name, '"', ' ');
1627 string_replace(path, '"', ' ');
1628 string_replace(comment, '"', ' ');
1630 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1631 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1633 /* Only call modify function if something changed. */
1635 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) )
1637 if (!lp_change_share_cmd() || !*lp_change_share_cmd())
1638 return WERR_ACCESS_DENIED;
1640 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1641 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1643 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1645 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1647 if ( is_disk_op )
1648 become_root();
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);
1655 if ( is_disk_op )
1656 unbecome_root();
1658 /********* END SeDiskOperatorPrivilege BLOCK *********/
1660 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
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 ));
1668 /* Replace SD if changed. */
1669 if (psd) {
1670 SEC_DESC *old_sd;
1671 size_t sd_size;
1673 old_sd = get_share_security(p->mem_ctx, snum, &sd_size);
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 ));
1682 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1684 return WERR_OK;
1687 /*******************************************************************
1688 Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
1689 ********************************************************************/
1691 WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
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;
1706 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1708 r_u->parm_error = 0;
1710 get_current_user(&user,p);
1712 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1714 if (user.uid != sec_initial_uid() && !is_disk_op )
1715 return WERR_ACCESS_DENIED;
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;
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;
1747 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1749 case 1004:
1750 case 1005:
1751 case 1006:
1752 case 1007:
1753 return WERR_ACCESS_DENIED;
1754 break;
1755 case 1501:
1756 /* DFS only level. */
1757 return WERR_ACCESS_DENIED;
1758 default:
1759 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
1760 return WERR_UNKNOWN_LEVEL;
1763 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1764 return WERR_ACCESS_DENIED;
1766 snum = find_service(share_name);
1768 /* Share already exists. */
1769 if (snum >= 0)
1770 return WERR_ALREADY_EXISTS;
1772 /* We can only add disk shares. */
1773 if (type != STYPE_DISKTREE)
1774 return WERR_ACCESS_DENIED;
1776 /* Check if the pathname is valid. */
1777 if (!(path = valid_share_pathname( pathname )))
1778 return WERR_OBJECT_PATH_INVALID;
1780 /* Ensure share name, pathname and comment don't contain '"' characters. */
1781 string_replace(share_name, '"', ' ');
1782 string_replace(path, '"', ' ');
1783 string_replace(comment, '"', ' ');
1785 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
1786 lp_add_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
1788 DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1790 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1792 if ( is_disk_op )
1793 become_root();
1795 if ( (ret = smbrun(command, NULL)) == 0 ) {
1796 /* Tell everyone we updated smb.conf. */
1797 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1800 if ( is_disk_op )
1801 unbecome_root();
1803 /********* END SeDiskOperatorPrivilege BLOCK *********/
1805 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1807 if ( ret != 0 )
1808 return WERR_ACCESS_DENIED;
1810 if (psd) {
1811 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1812 DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1817 * We don't call reload_services() here, the message will
1818 * cause this to be done before the next packet is read
1819 * from the client. JRA.
1822 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1824 return WERR_OK;
1827 /*******************************************************************
1828 Net share delete. Call "delete share command" with the share name as
1829 a parameter.
1830 ********************************************************************/
1832 WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1834 struct current_user user;
1835 pstring command;
1836 fstring share_name;
1837 int ret;
1838 int snum;
1839 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1840 BOOL is_disk_op;
1842 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1844 unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
1846 if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
1847 return WERR_ACCESS_DENIED;
1849 snum = find_service(share_name);
1851 if (snum < 0)
1852 return WERR_NO_SUCH_SHARE;
1854 /* No change to printer shares. */
1855 if (lp_print_ok(snum))
1856 return WERR_ACCESS_DENIED;
1858 get_current_user(&user,p);
1860 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1862 if (user.uid != sec_initial_uid() && !is_disk_op )
1863 return WERR_ACCESS_DENIED;
1865 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
1866 return WERR_ACCESS_DENIED;
1868 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1869 lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1871 DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1873 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1875 if ( is_disk_op )
1876 become_root();
1878 if ( (ret = smbrun(command, NULL)) == 0 ) {
1879 /* Tell everyone we updated smb.conf. */
1880 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1883 if ( is_disk_op )
1884 unbecome_root();
1886 /********* END SeDiskOperatorPrivilege BLOCK *********/
1888 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1890 if ( ret != 0 )
1891 return WERR_ACCESS_DENIED;
1893 /* Delete the SD in the database. */
1894 delete_share_security(snum);
1896 lp_killservice(snum);
1898 return WERR_OK;
1901 WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
1903 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1905 return _srv_net_share_del(p, q_u, r_u);
1908 /*******************************************************************
1909 time of day
1910 ********************************************************************/
1912 WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
1914 TIME_OF_DAY_INFO *tod;
1915 struct tm *t;
1916 time_t unixdate = time(NULL);
1918 tod = TALLOC_P(p->mem_ctx, TIME_OF_DAY_INFO);
1919 if (!tod)
1920 return WERR_NOMEM;
1922 ZERO_STRUCTP(tod);
1924 r_u->tod = tod;
1925 r_u->ptr_srv_tod = 0x1;
1926 r_u->status = WERR_OK;
1928 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1930 t = gmtime(&unixdate);
1932 /* set up the */
1933 init_time_of_day_info(tod,
1934 unixdate,
1936 t->tm_hour,
1937 t->tm_min,
1938 t->tm_sec,
1940 TimeDiff(unixdate)/60,
1941 10000,
1942 t->tm_mday,
1943 t->tm_mon + 1,
1944 1900+t->tm_year,
1945 t->tm_wday);
1947 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1949 return r_u->status;
1952 /***********************************************************************************
1953 Win9x NT tools get security descriptor.
1954 ***********************************************************************************/
1956 WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
1957 SRV_R_NET_FILE_QUERY_SECDESC *r_u)
1959 SEC_DESC *psd = NULL;
1960 size_t sd_size;
1961 DATA_BLOB null_pw;
1962 pstring filename;
1963 pstring qualname;
1964 files_struct *fsp = NULL;
1965 SMB_STRUCT_STAT st;
1966 BOOL bad_path;
1967 int access_mode;
1968 int action;
1969 NTSTATUS nt_status;
1970 struct current_user user;
1971 connection_struct *conn = NULL;
1972 BOOL became_user = False;
1974 ZERO_STRUCT(st);
1976 r_u->status = WERR_OK;
1978 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
1980 /* Null password is ok - we are already an authenticated user... */
1981 null_pw = data_blob(NULL, 0);
1983 get_current_user(&user, p);
1985 become_root();
1986 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
1987 unbecome_root();
1989 if (conn == NULL) {
1990 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
1991 r_u->status = ntstatus_to_werror(nt_status);
1992 goto error_exit;
1995 if (!become_user(conn, conn->vuid)) {
1996 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1997 r_u->status = WERR_ACCESS_DENIED;
1998 goto error_exit;
2000 became_user = True;
2002 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2003 unix_convert(filename, conn, NULL, &bad_path, &st);
2004 if (bad_path) {
2005 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
2006 r_u->status = WERR_ACCESS_DENIED;
2007 goto error_exit;
2010 if (!check_name(filename,conn)) {
2011 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
2012 r_u->status = WERR_ACCESS_DENIED;
2013 goto error_exit;
2016 fsp = open_file_shared(conn, filename, &st, SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
2017 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
2018 &access_mode, &action);
2020 if (!fsp) {
2021 /* Perhaps it is a directory */
2022 if (errno == EISDIR)
2023 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
2024 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
2026 if (!fsp) {
2027 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
2028 r_u->status = WERR_ACCESS_DENIED;
2029 goto error_exit;
2033 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2035 if (sd_size == 0) {
2036 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
2037 r_u->status = WERR_ACCESS_DENIED;
2038 goto error_exit;
2041 r_u->ptr_response = 1;
2042 r_u->size_response = sd_size;
2043 r_u->ptr_secdesc = 1;
2044 r_u->size_secdesc = sd_size;
2045 r_u->sec_desc = psd;
2047 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2049 close_file(fsp, True);
2050 unbecome_user();
2051 close_cnum(conn, user.vuid);
2052 return r_u->status;
2054 error_exit:
2056 if(fsp) {
2057 close_file(fsp, True);
2060 if (became_user)
2061 unbecome_user();
2063 if (conn)
2064 close_cnum(conn, user.vuid);
2066 return r_u->status;
2069 /***********************************************************************************
2070 Win9x NT tools set security descriptor.
2071 ***********************************************************************************/
2073 WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
2074 SRV_R_NET_FILE_SET_SECDESC *r_u)
2076 BOOL ret;
2077 pstring filename;
2078 pstring qualname;
2079 DATA_BLOB null_pw;
2080 files_struct *fsp = NULL;
2081 SMB_STRUCT_STAT st;
2082 BOOL bad_path;
2083 int access_mode;
2084 int action;
2085 NTSTATUS nt_status;
2086 struct current_user user;
2087 connection_struct *conn = NULL;
2088 BOOL became_user = False;
2090 ZERO_STRUCT(st);
2092 r_u->status = WERR_OK;
2094 unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
2096 /* Null password is ok - we are already an authenticated user... */
2097 null_pw = data_blob(NULL, 0);
2099 get_current_user(&user, p);
2101 become_root();
2102 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2103 unbecome_root();
2105 if (conn == NULL) {
2106 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
2107 r_u->status = ntstatus_to_werror(nt_status);
2108 goto error_exit;
2111 if (!become_user(conn, conn->vuid)) {
2112 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2113 r_u->status = WERR_ACCESS_DENIED;
2114 goto error_exit;
2116 became_user = True;
2118 unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
2119 unix_convert(filename, conn, NULL, &bad_path, &st);
2120 if (bad_path) {
2121 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
2122 r_u->status = WERR_ACCESS_DENIED;
2123 goto error_exit;
2126 if (!check_name(filename,conn)) {
2127 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
2128 r_u->status = WERR_ACCESS_DENIED;
2129 goto error_exit;
2133 fsp = open_file_shared(conn, filename, &st, SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDWR),
2134 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
2135 &access_mode, &action);
2137 if (!fsp) {
2138 /* Perhaps it is a directory */
2139 if (errno == EISDIR)
2140 fsp = open_directory(conn, filename, &st,FILE_READ_ATTRIBUTES,0,
2141 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), &action);
2143 if (!fsp) {
2144 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
2145 r_u->status = WERR_ACCESS_DENIED;
2146 goto error_exit;
2150 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc);
2152 if (ret == False) {
2153 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
2154 r_u->status = WERR_ACCESS_DENIED;
2155 goto error_exit;
2158 close_file(fsp, True);
2159 unbecome_user();
2160 close_cnum(conn, user.vuid);
2161 return r_u->status;
2163 error_exit:
2165 if(fsp) {
2166 close_file(fsp, True);
2169 if (became_user)
2170 unbecome_user();
2172 if (conn)
2173 close_cnum(conn, user.vuid);
2175 return r_u->status;
2178 /***********************************************************************************
2179 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2180 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2181 These disks would the disks listed by this function.
2182 Users could then create shares relative to these disks. Watch out for moving these disks around.
2183 "Nigel Williams" <nigel@veritas.com>.
2184 ***********************************************************************************/
2186 static const char *server_disks[] = {"C:"};
2188 static uint32 get_server_disk_count(void)
2190 return sizeof(server_disks)/sizeof(server_disks[0]);
2193 static uint32 init_server_disk_enum(uint32 *resume)
2195 uint32 server_disk_count = get_server_disk_count();
2197 /*resume can be an offset into the list for now*/
2199 if(*resume & 0x80000000)
2200 *resume = 0;
2202 if(*resume > server_disk_count)
2203 *resume = server_disk_count;
2205 return server_disk_count - *resume;
2208 static const char *next_server_disk_enum(uint32 *resume)
2210 const char *disk;
2212 if(init_server_disk_enum(resume) == 0)
2213 return NULL;
2215 disk = server_disks[*resume];
2217 (*resume)++;
2219 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2221 return disk;
2224 WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
2226 uint32 i;
2227 const char *disk_name;
2228 TALLOC_CTX *ctx = p->mem_ctx;
2229 uint32 resume=get_enum_hnd(&q_u->enum_hnd);
2231 r_u->status=WERR_OK;
2233 r_u->total_entries = init_server_disk_enum(&resume);
2235 r_u->disk_enum_ctr.unknown = 0;
2237 if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
2238 return WERR_NOMEM;
2241 r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
2243 /*allow one DISK_INFO for null terminator*/
2245 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2247 r_u->disk_enum_ctr.entries_read++;
2249 /*copy disk name into a unicode string*/
2251 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name);
2254 /* add a terminating null string. Is this there if there is more data to come? */
2256 r_u->disk_enum_ctr.entries_read++;
2258 init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
2260 init_enum_hnd(&r_u->enum_hnd, resume);
2262 return r_u->status;
2265 WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
2267 int snum;
2268 fstring share_name;
2270 r_u->status=WERR_OK;
2272 switch(q_u->type) {
2274 case 0x9:
2276 /*check if share name is ok*/
2277 /*also check if we already have a share with this name*/
2279 unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
2280 snum = find_service(share_name);
2282 /* Share already exists. */
2283 if (snum >= 0)
2284 r_u->status = WERR_ALREADY_EXISTS;
2285 break;
2287 default:
2288 /*unsupported type*/
2289 r_u->status = WERR_UNKNOWN_LEVEL;
2290 break;
2293 return r_u->status;