smbd: Remove superfluous ()
[Samba.git] / source4 / ntvfs / posix / pvfs_acl.c
blob269b5ecd098a450851872f84ea85a2b13a1667d4
1 /*
2 Unix SMB/CIFS implementation.
4 POSIX NTVFS backend - ACL support
6 Copyright (C) Andrew Tridgell 2004
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 3 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, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "system/passwd.h"
24 #include "auth/auth.h"
25 #include "vfs_posix.h"
26 #include "librpc/gen_ndr/xattr.h"
27 #include "libcli/security/security.h"
28 #include "param/param.h"
29 #include "../lib/util/unix_privs.h"
30 #include "lib/util/samba_modules.h"
32 /* the list of currently registered ACL backends */
33 static struct pvfs_acl_backend {
34 const struct pvfs_acl_ops *ops;
35 } *backends = NULL;
36 static int num_backends;
39 register a pvfs acl backend.
41 The 'name' can be later used by other backends to find the operations
42 structure for this backend.
44 NTSTATUS pvfs_acl_register(const struct pvfs_acl_ops *ops)
46 struct pvfs_acl_ops *new_ops;
48 if (pvfs_acl_backend_byname(ops->name) != NULL) {
49 DEBUG(0,("pvfs acl backend '%s' already registered\n", ops->name));
50 return NT_STATUS_OBJECT_NAME_COLLISION;
53 backends = talloc_realloc(talloc_autofree_context(), backends, struct pvfs_acl_backend, num_backends+1);
54 NT_STATUS_HAVE_NO_MEMORY(backends);
56 new_ops = (struct pvfs_acl_ops *)talloc_memdup(backends, ops, sizeof(*ops));
57 new_ops->name = talloc_strdup(new_ops, ops->name);
59 backends[num_backends].ops = new_ops;
61 num_backends++;
63 DEBUG(3,("NTVFS backend '%s' registered\n", ops->name));
65 return NT_STATUS_OK;
70 return the operations structure for a named backend
72 const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name)
74 int i;
76 for (i=0;i<num_backends;i++) {
77 if (strcmp(backends[i].ops->name, name) == 0) {
78 return backends[i].ops;
82 return NULL;
85 NTSTATUS pvfs_acl_init(void)
87 static bool initialized = false;
88 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
89 STATIC_pvfs_acl_MODULES_PROTO;
90 init_module_fn static_init[] = { STATIC_pvfs_acl_MODULES };
91 init_module_fn *shared_init;
93 if (initialized) return NT_STATUS_OK;
94 initialized = true;
96 shared_init = load_samba_modules(NULL, "pvfs_acl");
98 run_init_functions(static_init);
99 run_init_functions(shared_init);
101 talloc_free(shared_init);
103 return NT_STATUS_OK;
108 map a single access_mask from generic to specific bits for files/dirs
110 static uint32_t pvfs_translate_mask(uint32_t access_mask)
112 if (access_mask & SEC_MASK_GENERIC) {
113 if (access_mask & SEC_GENERIC_READ) access_mask |= SEC_RIGHTS_FILE_READ;
114 if (access_mask & SEC_GENERIC_WRITE) access_mask |= SEC_RIGHTS_FILE_WRITE;
115 if (access_mask & SEC_GENERIC_EXECUTE) access_mask |= SEC_RIGHTS_FILE_EXECUTE;
116 if (access_mask & SEC_GENERIC_ALL) access_mask |= SEC_RIGHTS_FILE_ALL;
117 access_mask &= ~SEC_MASK_GENERIC;
119 return access_mask;
124 map any generic access bits in the given acl
125 this relies on the fact that the mappings for files and directories
126 are the same
128 static void pvfs_translate_generic_bits(struct security_acl *acl)
130 unsigned i;
132 if (!acl) return;
134 for (i=0;i<acl->num_aces;i++) {
135 struct security_ace *ace = &acl->aces[i];
136 ace->access_mask = pvfs_translate_mask(ace->access_mask);
142 setup a default ACL for a file
144 static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
145 struct ntvfs_request *req,
146 struct pvfs_filename *name, int fd,
147 struct security_descriptor **psd)
149 struct security_descriptor *sd;
150 NTSTATUS status;
151 struct security_ace ace;
152 mode_t mode;
153 struct id_map *ids;
155 *psd = security_descriptor_initialise(req);
156 if (*psd == NULL) {
157 return NT_STATUS_NO_MEMORY;
159 sd = *psd;
161 ids = talloc_zero_array(sd, struct id_map, 2);
162 NT_STATUS_HAVE_NO_MEMORY(ids);
164 ids[0].xid.id = name->st.st_uid;
165 ids[0].xid.type = ID_TYPE_UID;
166 ids[0].sid = NULL;
168 ids[1].xid.id = name->st.st_gid;
169 ids[1].xid.type = ID_TYPE_GID;
170 ids[1].sid = NULL;
172 status = wbc_xids_to_sids(pvfs->ntvfs->ctx->event_ctx, ids, 2);
173 NT_STATUS_NOT_OK_RETURN(status);
175 sd->owner_sid = talloc_steal(sd, ids[0].sid);
176 sd->group_sid = talloc_steal(sd, ids[1].sid);
178 talloc_free(ids);
179 sd->type |= SEC_DESC_DACL_PRESENT;
181 mode = name->st.st_mode;
184 we provide up to 4 ACEs
185 - Owner
186 - Group
187 - Everyone
188 - Administrator
192 /* setup owner ACE */
193 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
194 ace.flags = 0;
195 ace.trustee = *sd->owner_sid;
196 ace.access_mask = 0;
198 if (mode & S_IRUSR) {
199 if (mode & S_IWUSR) {
200 ace.access_mask |= SEC_RIGHTS_FILE_ALL;
201 } else {
202 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
205 if (mode & S_IWUSR) {
206 ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
208 if (ace.access_mask) {
209 security_descriptor_dacl_add(sd, &ace);
213 /* setup group ACE */
214 ace.trustee = *sd->group_sid;
215 ace.access_mask = 0;
216 if (mode & S_IRGRP) {
217 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
219 if (mode & S_IWGRP) {
220 /* note that delete is not granted - this matches posix behaviour */
221 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
223 if (ace.access_mask) {
224 security_descriptor_dacl_add(sd, &ace);
227 /* setup other ACE */
228 ace.trustee = *dom_sid_parse_talloc(req, SID_WORLD);
229 ace.access_mask = 0;
230 if (mode & S_IROTH) {
231 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
233 if (mode & S_IWOTH) {
234 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
236 if (ace.access_mask) {
237 security_descriptor_dacl_add(sd, &ace);
240 /* setup system ACE */
241 ace.trustee = *dom_sid_parse_talloc(req, SID_NT_SYSTEM);
242 ace.access_mask = SEC_RIGHTS_FILE_ALL;
243 security_descriptor_dacl_add(sd, &ace);
245 return NT_STATUS_OK;
250 omit any security_descriptor elements not specified in the given
251 secinfo flags
253 static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags)
255 if (!(secinfo_flags & SECINFO_OWNER)) {
256 sd->owner_sid = NULL;
258 if (!(secinfo_flags & SECINFO_GROUP)) {
259 sd->group_sid = NULL;
261 if (!(secinfo_flags & SECINFO_DACL)) {
262 sd->dacl = NULL;
264 if (!(secinfo_flags & SECINFO_SACL)) {
265 sd->sacl = NULL;
269 static bool pvfs_privileged_access(uid_t uid)
271 uid_t euid;
273 if (uid_wrapper_enabled()) {
274 setenv("UID_WRAPPER_MYUID", "1", 1);
277 euid = geteuid();
279 if (uid_wrapper_enabled()) {
280 unsetenv("UID_WRAPPER_MYUID");
283 return (uid == euid);
287 answer a setfileinfo for an ACL
289 NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
290 struct ntvfs_request *req,
291 struct pvfs_filename *name, int fd,
292 uint32_t access_mask,
293 union smb_setfileinfo *info)
295 uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
296 struct security_descriptor *new_sd, *sd, orig_sd;
297 NTSTATUS status = NT_STATUS_NOT_FOUND;
298 uid_t old_uid = -1;
299 gid_t old_gid = -1;
300 uid_t new_uid = -1;
301 gid_t new_gid = -1;
302 struct id_map *ids;
304 if (pvfs->acl_ops != NULL) {
305 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
307 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
308 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
310 if (!NT_STATUS_IS_OK(status)) {
311 return status;
314 ids = talloc(req, struct id_map);
315 NT_STATUS_HAVE_NO_MEMORY(ids);
316 ZERO_STRUCT(ids->xid);
317 ids->sid = NULL;
318 ids->status = ID_UNKNOWN;
320 new_sd = info->set_secdesc.in.sd;
321 orig_sd = *sd;
323 old_uid = name->st.st_uid;
324 old_gid = name->st.st_gid;
326 /* only set the elements that have been specified */
327 if (secinfo_flags & SECINFO_OWNER) {
328 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
329 return NT_STATUS_ACCESS_DENIED;
331 if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
332 ids->sid = new_sd->owner_sid;
333 status = wbc_sids_to_xids(pvfs->ntvfs->ctx->event_ctx,
334 ids, 1);
335 NT_STATUS_NOT_OK_RETURN(status);
337 if (ids->xid.type == ID_TYPE_BOTH ||
338 ids->xid.type == ID_TYPE_UID) {
339 new_uid = ids->xid.id;
342 sd->owner_sid = new_sd->owner_sid;
345 if (secinfo_flags & SECINFO_GROUP) {
346 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
347 return NT_STATUS_ACCESS_DENIED;
349 if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
350 ids->sid = new_sd->group_sid;
351 status = wbc_sids_to_xids(pvfs->ntvfs->ctx->event_ctx,
352 ids, 1);
353 NT_STATUS_NOT_OK_RETURN(status);
355 if (ids->xid.type == ID_TYPE_BOTH ||
356 ids->xid.type == ID_TYPE_GID) {
357 new_gid = ids->xid.id;
361 sd->group_sid = new_sd->group_sid;
364 if (secinfo_flags & SECINFO_DACL) {
365 if (!(access_mask & SEC_STD_WRITE_DAC)) {
366 return NT_STATUS_ACCESS_DENIED;
368 sd->dacl = new_sd->dacl;
369 pvfs_translate_generic_bits(sd->dacl);
370 sd->type |= SEC_DESC_DACL_PRESENT;
373 if (secinfo_flags & SECINFO_SACL) {
374 if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
375 return NT_STATUS_ACCESS_DENIED;
377 sd->sacl = new_sd->sacl;
378 pvfs_translate_generic_bits(sd->sacl);
379 sd->type |= SEC_DESC_SACL_PRESENT;
382 if (secinfo_flags & SECINFO_PROTECTED_DACL) {
383 if (new_sd->type & SEC_DESC_DACL_PROTECTED) {
384 sd->type |= SEC_DESC_DACL_PROTECTED;
385 } else {
386 sd->type &= ~SEC_DESC_DACL_PROTECTED;
390 if (secinfo_flags & SECINFO_PROTECTED_SACL) {
391 if (new_sd->type & SEC_DESC_SACL_PROTECTED) {
392 sd->type |= SEC_DESC_SACL_PROTECTED;
393 } else {
394 sd->type &= ~SEC_DESC_SACL_PROTECTED;
398 if (new_uid == old_uid) {
399 new_uid = -1;
402 if (new_gid == old_gid) {
403 new_gid = -1;
406 /* if there's something to change try it */
407 if (new_uid != -1 || new_gid != -1) {
408 int ret;
409 if (fd == -1) {
410 ret = chown(name->full_name, new_uid, new_gid);
411 } else {
412 ret = fchown(fd, new_uid, new_gid);
414 if (errno == EPERM) {
415 if (pvfs_privileged_access(name->st.st_uid)) {
416 ret = 0;
417 } else {
418 /* try again as root if we have SEC_PRIV_RESTORE or
419 SEC_PRIV_TAKE_OWNERSHIP */
420 if (security_token_has_privilege(req->session_info->security_token,
421 SEC_PRIV_RESTORE) ||
422 security_token_has_privilege(req->session_info->security_token,
423 SEC_PRIV_TAKE_OWNERSHIP)) {
424 void *privs;
425 privs = root_privileges();
426 if (fd == -1) {
427 ret = chown(name->full_name, new_uid, new_gid);
428 } else {
429 ret = fchown(fd, new_uid, new_gid);
431 talloc_free(privs);
435 if (ret == -1) {
436 return pvfs_map_errno(pvfs, errno);
440 /* we avoid saving if the sd is the same. This means when clients
441 copy files and end up copying the default sd that we don't
442 needlessly use xattrs */
443 if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
444 status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
447 return status;
452 answer a fileinfo query for the ACL
454 NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs,
455 struct ntvfs_request *req,
456 struct pvfs_filename *name, int fd,
457 union smb_fileinfo *info)
459 NTSTATUS status = NT_STATUS_NOT_FOUND;
460 struct security_descriptor *sd;
462 if (pvfs->acl_ops) {
463 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
465 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
466 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
468 if (!NT_STATUS_IS_OK(status)) {
469 return status;
472 normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
474 info->query_secdesc.out.sd = sd;
476 return NT_STATUS_OK;
481 check the read only bit against any of the write access bits
483 static bool pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask)
485 if ((pvfs->flags & PVFS_FLAG_READONLY) &&
486 (access_mask & (SEC_FILE_WRITE_DATA |
487 SEC_FILE_APPEND_DATA |
488 SEC_FILE_WRITE_EA |
489 SEC_FILE_WRITE_ATTRIBUTE |
490 SEC_STD_DELETE |
491 SEC_STD_WRITE_DAC |
492 SEC_STD_WRITE_OWNER |
493 SEC_DIR_DELETE_CHILD))) {
494 return true;
496 return false;
500 see if we are a member of the appropriate unix group
502 static bool pvfs_group_member(struct pvfs_state *pvfs, gid_t gid)
504 int i, ngroups;
505 gid_t *groups;
506 if (getegid() == gid) {
507 return true;
509 ngroups = getgroups(0, NULL);
510 if (ngroups <= 0) {
511 return false;
513 groups = talloc_array(pvfs, gid_t, ngroups);
514 if (groups == NULL) {
515 return false;
517 if (getgroups(ngroups, groups) != ngroups) {
518 talloc_free(groups);
519 return false;
521 for (i=0; i<ngroups; i++) {
522 if (groups[i] == gid) break;
524 talloc_free(groups);
525 return i < ngroups;
529 default access check function based on unix permissions
530 doing this saves on building a full security descriptor
531 for the common case of access check on files with no
532 specific NT ACL
534 If name is NULL then treat as a new file creation
536 static NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
537 struct ntvfs_request *req,
538 struct pvfs_filename *name,
539 uint32_t *access_mask)
541 uint32_t max_bits = 0;
542 struct security_token *token = req->session_info->security_token;
544 if (pvfs_read_only(pvfs, *access_mask)) {
545 return NT_STATUS_ACCESS_DENIED;
548 if (name == NULL) {
549 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
550 } else if (pvfs_privileged_access(name->st.st_uid)) {
551 /* use the IxUSR bits */
552 if ((name->st.st_mode & S_IWUSR)) {
553 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
554 } else if ((name->st.st_mode & (S_IRUSR | S_IXUSR))) {
555 max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
557 } else if (pvfs_group_member(pvfs, name->st.st_gid)) {
558 /* use the IxGRP bits */
559 if ((name->st.st_mode & S_IWGRP)) {
560 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
561 } else if ((name->st.st_mode & (S_IRGRP | S_IXGRP))) {
562 max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
564 } else {
565 /* use the IxOTH bits */
566 if ((name->st.st_mode & S_IWOTH)) {
567 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
568 } else if ((name->st.st_mode & (S_IROTH | S_IXOTH))) {
569 max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
573 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
574 *access_mask |= max_bits;
575 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
578 if ((*access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
579 security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
580 max_bits |= SEC_FLAG_SYSTEM_SECURITY;
583 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_RESTORE) &&
584 security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
585 max_bits |= ~(SEC_RIGHTS_PRIV_RESTORE);
587 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_BACKUP) &&
588 security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
589 max_bits |= ~(SEC_RIGHTS_PRIV_BACKUP);
592 if (*access_mask & ~max_bits) {
593 DEBUG(5,(__location__ " denied access to '%s' - wanted 0x%08x but got 0x%08x (missing 0x%08x)\n",
594 name?name->full_name:"(new file)", *access_mask, max_bits, *access_mask & ~max_bits));
595 return NT_STATUS_ACCESS_DENIED;
598 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
599 /* on SMB, this bit is always granted, even if not
600 asked for */
601 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
604 return NT_STATUS_OK;
609 check the security descriptor on a file, if any
611 *access_mask is modified with the access actually granted
613 NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
614 struct ntvfs_request *req,
615 struct pvfs_filename *name,
616 uint32_t *access_mask)
618 struct security_token *token = req->session_info->security_token;
619 struct xattr_NTACL *acl;
620 NTSTATUS status;
621 struct security_descriptor *sd;
622 bool allow_delete = false;
624 /* on SMB2 a blank access mask is always denied */
625 if (pvfs->ntvfs->ctx->protocol >= PROTOCOL_SMB2_02 &&
626 *access_mask == 0) {
627 return NT_STATUS_ACCESS_DENIED;
630 if (pvfs_read_only(pvfs, *access_mask)) {
631 return NT_STATUS_ACCESS_DENIED;
634 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
635 *access_mask & SEC_STD_DELETE) {
636 status = pvfs_access_check_parent(pvfs, req,
637 name, SEC_DIR_DELETE_CHILD);
638 if (NT_STATUS_IS_OK(status)) {
639 allow_delete = true;
640 *access_mask &= ~SEC_STD_DELETE;
644 acl = talloc(req, struct xattr_NTACL);
645 if (acl == NULL) {
646 return NT_STATUS_NO_MEMORY;
649 /* expand the generic access bits to file specific bits */
650 *access_mask = pvfs_translate_mask(*access_mask);
651 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
652 *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
655 status = pvfs_acl_load(pvfs, name, -1, acl);
656 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
657 talloc_free(acl);
658 status = pvfs_access_check_unix(pvfs, req, name, access_mask);
659 goto done;
661 if (!NT_STATUS_IS_OK(status)) {
662 return status;
665 switch (acl->version) {
666 case 1:
667 sd = acl->info.sd;
668 break;
669 default:
670 return NT_STATUS_INVALID_ACL;
673 /* check the acl against the required access mask */
674 status = se_access_check(sd, token, *access_mask, access_mask);
675 talloc_free(acl);
677 /* if we used a NT acl, then allow access override if the
678 share allows for posix permission override
680 if (NT_STATUS_IS_OK(status)) {
681 name->allow_override = (pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) != 0;
684 done:
685 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
686 /* on SMB, this bit is always granted, even if not
687 asked for */
688 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
691 if (allow_delete) {
692 *access_mask |= SEC_STD_DELETE;
695 return status;
700 a simplified interface to access check, designed for calls that
701 do not take or return an access check mask
703 NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs,
704 struct ntvfs_request *req,
705 struct pvfs_filename *name,
706 uint32_t access_needed)
708 if (access_needed == 0) {
709 return NT_STATUS_OK;
711 return pvfs_access_check(pvfs, req, name, &access_needed);
715 access check for creating a new file/directory
717 NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs,
718 struct ntvfs_request *req,
719 struct pvfs_filename *name,
720 uint32_t *access_mask,
721 bool container,
722 struct security_descriptor **sd)
724 struct pvfs_filename *parent;
725 NTSTATUS status;
726 uint32_t parent_mask;
727 bool allow_delete = false;
729 if (pvfs_read_only(pvfs, *access_mask)) {
730 return NT_STATUS_ACCESS_DENIED;
733 status = pvfs_resolve_parent(pvfs, req, name, &parent);
734 NT_STATUS_NOT_OK_RETURN(status);
736 if (container) {
737 parent_mask = SEC_DIR_ADD_SUBDIR;
738 } else {
739 parent_mask = SEC_DIR_ADD_FILE;
741 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
742 *access_mask & SEC_STD_DELETE) {
743 parent_mask |= SEC_DIR_DELETE_CHILD;
746 status = pvfs_access_check(pvfs, req, parent, &parent_mask);
747 if (NT_STATUS_IS_OK(status)) {
748 if (parent_mask & SEC_DIR_DELETE_CHILD) {
749 allow_delete = true;
751 } else if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
753 * on ACCESS_DENIED we get the rejected bits
754 * remove the non critical SEC_DIR_DELETE_CHILD
755 * and check if something else was rejected.
757 parent_mask &= ~SEC_DIR_DELETE_CHILD;
758 if (parent_mask != 0) {
759 return NT_STATUS_ACCESS_DENIED;
761 status = NT_STATUS_OK;
762 } else {
763 return status;
766 if (*sd == NULL) {
767 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, sd);
770 talloc_free(parent);
771 if (!NT_STATUS_IS_OK(status)) {
772 return status;
775 /* expand the generic access bits to file specific bits */
776 *access_mask = pvfs_translate_mask(*access_mask);
778 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
779 *access_mask |= SEC_RIGHTS_FILE_ALL;
780 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
783 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
784 /* on SMB, this bit is always granted, even if not
785 asked for */
786 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
789 if (allow_delete) {
790 *access_mask |= SEC_STD_DELETE;
793 return NT_STATUS_OK;
797 access check for creating a new file/directory - no access mask supplied
799 NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs,
800 struct ntvfs_request *req,
801 struct pvfs_filename *name,
802 uint32_t access_mask)
804 struct pvfs_filename *parent;
805 NTSTATUS status;
807 status = pvfs_resolve_parent(pvfs, req, name, &parent);
808 if (!NT_STATUS_IS_OK(status)) {
809 return status;
812 status = pvfs_access_check_simple(pvfs, req, parent, access_mask);
813 if (NT_STATUS_IS_OK(status) && parent->allow_override) {
814 name->allow_override = true;
816 return status;
821 determine if an ACE is inheritable
823 static bool pvfs_inheritable_ace(struct pvfs_state *pvfs,
824 const struct security_ace *ace,
825 bool container)
827 if (!container) {
828 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
831 if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
832 return true;
835 if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
836 !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
837 return true;
840 return false;
844 this is the core of ACL inheritance. It copies any inheritable
845 aces from the parent SD to the child SD. Note that the algorithm
846 depends on whether the child is a container or not
848 static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs,
849 struct security_descriptor *parent_sd,
850 struct security_descriptor *sd,
851 bool container)
853 int i;
855 for (i=0;i<parent_sd->dacl->num_aces;i++) {
856 struct security_ace ace = parent_sd->dacl->aces[i];
857 NTSTATUS status;
858 const struct dom_sid *creator = NULL, *new_id = NULL;
859 uint32_t orig_flags;
861 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
862 continue;
865 orig_flags = ace.flags;
867 /* see the RAW-ACLS inheritance test for details on these rules */
868 if (!container) {
869 ace.flags = 0;
870 } else {
871 ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
873 if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
874 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
876 if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
877 ace.flags = 0;
881 /* the CREATOR sids are special when inherited */
882 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
883 creator = pvfs->sid_cache.creator_owner;
884 new_id = sd->owner_sid;
885 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
886 creator = pvfs->sid_cache.creator_group;
887 new_id = sd->group_sid;
888 } else {
889 new_id = &ace.trustee;
892 if (creator && container &&
893 (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
894 uint32_t flags = ace.flags;
896 ace.trustee = *new_id;
897 ace.flags = 0;
898 status = security_descriptor_dacl_add(sd, &ace);
899 if (!NT_STATUS_IS_OK(status)) {
900 return status;
903 ace.trustee = *creator;
904 ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
905 status = security_descriptor_dacl_add(sd, &ace);
906 } else if (container &&
907 !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
908 status = security_descriptor_dacl_add(sd, &ace);
909 } else {
910 ace.trustee = *new_id;
911 status = security_descriptor_dacl_add(sd, &ace);
914 if (!NT_STATUS_IS_OK(status)) {
915 return status;
919 return NT_STATUS_OK;
925 calculate the ACL on a new file/directory based on the inherited ACL
926 from the parent. If there is no inherited ACL then return a NULL
927 ACL, which means the default ACL should be used
929 NTSTATUS pvfs_acl_inherited_sd(struct pvfs_state *pvfs,
930 TALLOC_CTX *mem_ctx,
931 struct ntvfs_request *req,
932 struct pvfs_filename *parent,
933 bool container,
934 struct security_descriptor **ret_sd)
936 struct xattr_NTACL *acl;
937 NTSTATUS status;
938 struct security_descriptor *parent_sd, *sd;
939 struct id_map *ids;
940 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
942 *ret_sd = NULL;
944 acl = talloc(req, struct xattr_NTACL);
945 if (acl == NULL) {
946 TALLOC_FREE(tmp_ctx);
947 return NT_STATUS_NO_MEMORY;
950 status = pvfs_acl_load(pvfs, parent, -1, acl);
951 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
952 talloc_free(tmp_ctx);
953 return NT_STATUS_OK;
955 if (!NT_STATUS_IS_OK(status)) {
956 TALLOC_FREE(tmp_ctx);
957 return status;
960 switch (acl->version) {
961 case 1:
962 parent_sd = acl->info.sd;
963 break;
964 default:
965 talloc_free(tmp_ctx);
966 return NT_STATUS_INVALID_ACL;
969 if (parent_sd == NULL ||
970 parent_sd->dacl == NULL ||
971 parent_sd->dacl->num_aces == 0) {
972 /* go with the default ACL */
973 talloc_free(tmp_ctx);
974 return NT_STATUS_OK;
977 /* create the new sd */
978 sd = security_descriptor_initialise(req);
979 if (sd == NULL) {
980 TALLOC_FREE(tmp_ctx);
981 return NT_STATUS_NO_MEMORY;
984 ids = talloc_array(sd, struct id_map, 2);
985 if (ids == NULL) {
986 TALLOC_FREE(tmp_ctx);
987 return NT_STATUS_NO_MEMORY;
990 ids[0].xid.id = geteuid();
991 ids[0].xid.type = ID_TYPE_UID;
992 ids[0].sid = NULL;
993 ids[0].status = ID_UNKNOWN;
995 ids[1].xid.id = getegid();
996 ids[1].xid.type = ID_TYPE_GID;
997 ids[1].sid = NULL;
998 ids[1].status = ID_UNKNOWN;
1000 status = wbc_xids_to_sids(pvfs->ntvfs->ctx->event_ctx, ids, 2);
1001 if (!NT_STATUS_IS_OK(status)) {
1002 TALLOC_FREE(tmp_ctx);
1003 return status;
1006 sd->owner_sid = talloc_steal(sd, ids[0].sid);
1007 sd->group_sid = talloc_steal(sd, ids[1].sid);
1009 sd->type |= SEC_DESC_DACL_PRESENT;
1011 /* fill in the aces from the parent */
1012 status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
1013 if (!NT_STATUS_IS_OK(status)) {
1014 TALLOC_FREE(tmp_ctx);
1015 return status;
1018 /* if there is nothing to inherit then we fallback to the
1019 default acl */
1020 if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
1021 talloc_free(tmp_ctx);
1022 return NT_STATUS_OK;
1025 *ret_sd = talloc_steal(mem_ctx, sd);
1027 talloc_free(tmp_ctx);
1028 return NT_STATUS_OK;
1033 setup an ACL on a new file/directory based on the inherited ACL from
1034 the parent. If there is no inherited ACL then we don't set anything,
1035 as the default ACL applies anyway
1037 NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
1038 struct ntvfs_request *req,
1039 struct pvfs_filename *name,
1040 int fd)
1042 struct xattr_NTACL acl;
1043 NTSTATUS status;
1044 struct security_descriptor *sd;
1045 struct pvfs_filename *parent;
1046 bool container;
1048 /* form the parents path */
1049 status = pvfs_resolve_parent(pvfs, req, name, &parent);
1050 NT_STATUS_NOT_OK_RETURN(status);
1052 container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false;
1054 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, &sd);
1055 if (!NT_STATUS_IS_OK(status)) {
1056 talloc_free(parent);
1057 return status;
1060 if (sd == NULL) {
1061 return NT_STATUS_OK;
1064 acl.version = 1;
1065 acl.info.sd = sd;
1067 status = pvfs_acl_save(pvfs, name, fd, &acl);
1068 talloc_free(sd);
1069 talloc_free(parent);
1071 return status;
1075 return the maximum allowed access mask
1077 NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs,
1078 struct ntvfs_request *req,
1079 struct pvfs_filename *name,
1080 uint32_t *maximal_access)
1082 *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
1083 return pvfs_access_check(pvfs, req, name, maximal_access);