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/>.
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;
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(TALLOC_CTX *ctx, 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(ctx, backends,
54 struct pvfs_acl_backend, num_backends+1);
55 NT_STATUS_HAVE_NO_MEMORY(backends);
57 new_ops = (struct pvfs_acl_ops *)talloc_memdup(backends, ops, sizeof(*ops));
58 new_ops->name = talloc_strdup(new_ops, ops->name);
60 backends[num_backends].ops = new_ops;
64 DEBUG(3,("NTVFS backend '%s' registered\n", ops->name));
71 return the operations structure for a named backend
73 const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name)
77 for (i=0;i<num_backends;i++) {
78 if (strcmp(backends[i].ops->name, name) == 0) {
79 return backends[i].ops;
86 NTSTATUS pvfs_acl_init(void)
88 static bool initialized = false;
89 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
90 STATIC_pvfs_acl_MODULES_PROTO;
91 init_module_fn static_init[] = { STATIC_pvfs_acl_MODULES };
92 init_module_fn *shared_init;
94 if (initialized) return NT_STATUS_OK;
97 shared_init = load_samba_modules(NULL, "pvfs_acl");
99 run_init_functions(NULL, static_init);
100 run_init_functions(NULL, shared_init);
102 talloc_free(shared_init);
109 map a single access_mask from generic to specific bits for files/dirs
111 static uint32_t pvfs_translate_mask(uint32_t access_mask)
113 if (access_mask & SEC_MASK_GENERIC) {
114 if (access_mask & SEC_GENERIC_READ) access_mask |= SEC_RIGHTS_FILE_READ;
115 if (access_mask & SEC_GENERIC_WRITE) access_mask |= SEC_RIGHTS_FILE_WRITE;
116 if (access_mask & SEC_GENERIC_EXECUTE) access_mask |= SEC_RIGHTS_FILE_EXECUTE;
117 if (access_mask & SEC_GENERIC_ALL) access_mask |= SEC_RIGHTS_FILE_ALL;
118 access_mask &= ~SEC_MASK_GENERIC;
125 map any generic access bits in the given acl
126 this relies on the fact that the mappings for files and directories
129 static void pvfs_translate_generic_bits(struct security_acl *acl)
135 for (i=0;i<acl->num_aces;i++) {
136 struct security_ace *ace = &acl->aces[i];
137 ace->access_mask = pvfs_translate_mask(ace->access_mask);
143 setup a default ACL for a file
145 static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
146 struct ntvfs_request *req,
147 struct pvfs_filename *name, int fd,
148 struct security_descriptor **psd)
150 struct security_descriptor *sd;
152 struct security_ace ace = {};
156 *psd = security_descriptor_initialise(req);
158 return NT_STATUS_NO_MEMORY;
162 ids = talloc_zero_array(sd, struct id_map, 2);
163 NT_STATUS_HAVE_NO_MEMORY(ids);
165 ids[0].xid.id = name->st.st_uid;
166 ids[0].xid.type = ID_TYPE_UID;
169 ids[1].xid.id = name->st.st_gid;
170 ids[1].xid.type = ID_TYPE_GID;
173 status = wbc_xids_to_sids(ids, 2);
174 NT_STATUS_NOT_OK_RETURN(status);
176 sd->owner_sid = talloc_steal(sd, ids[0].sid);
177 sd->group_sid = talloc_steal(sd, ids[1].sid);
180 sd->type |= SEC_DESC_DACL_PRESENT;
182 mode = name->st.st_mode;
185 we provide up to 4 ACEs
193 /* setup owner ACE */
194 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
196 ace.trustee = *sd->owner_sid;
199 if (mode & S_IRUSR) {
200 if (mode & S_IWUSR) {
201 ace.access_mask |= SEC_RIGHTS_FILE_ALL;
203 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
206 if (mode & S_IWUSR) {
207 ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
209 if (ace.access_mask) {
210 security_descriptor_dacl_add(sd, &ace);
214 /* setup group ACE */
215 ace.trustee = *sd->group_sid;
217 if (mode & S_IRGRP) {
218 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
220 if (mode & S_IWGRP) {
221 /* note that delete is not granted - this matches posix behaviour */
222 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
224 if (ace.access_mask) {
225 security_descriptor_dacl_add(sd, &ace);
228 /* setup other ACE */
229 ace.trustee = *dom_sid_parse_talloc(req, SID_WORLD);
231 if (mode & S_IROTH) {
232 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
234 if (mode & S_IWOTH) {
235 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
237 if (ace.access_mask) {
238 security_descriptor_dacl_add(sd, &ace);
241 /* setup system ACE */
242 ace.trustee = *dom_sid_parse_talloc(req, SID_NT_SYSTEM);
243 ace.access_mask = SEC_RIGHTS_FILE_ALL;
244 security_descriptor_dacl_add(sd, &ace);
251 omit any security_descriptor elements not specified in the given
254 static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags)
256 if (!(secinfo_flags & SECINFO_OWNER)) {
257 sd->owner_sid = NULL;
259 if (!(secinfo_flags & SECINFO_GROUP)) {
260 sd->group_sid = NULL;
262 if (!(secinfo_flags & SECINFO_DACL)) {
265 if (!(secinfo_flags & SECINFO_SACL)) {
270 static bool pvfs_privileged_access(uid_t uid)
274 if (uid_wrapper_enabled()) {
275 setenv("UID_WRAPPER_MYUID", "1", 1);
280 if (uid_wrapper_enabled()) {
281 unsetenv("UID_WRAPPER_MYUID");
284 return (uid == euid);
288 answer a setfileinfo for an ACL
290 NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
291 struct ntvfs_request *req,
292 struct pvfs_filename *name, int fd,
293 uint32_t access_mask,
294 union smb_setfileinfo *info)
296 uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
297 struct security_descriptor *new_sd, *sd, orig_sd;
298 NTSTATUS status = NT_STATUS_NOT_FOUND;
305 if (pvfs->acl_ops != NULL) {
306 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
308 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
309 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
311 if (!NT_STATUS_IS_OK(status)) {
315 ids = talloc(req, struct id_map);
316 NT_STATUS_HAVE_NO_MEMORY(ids);
317 ZERO_STRUCT(ids->xid);
319 ids->status = ID_UNKNOWN;
321 new_sd = info->set_secdesc.in.sd;
324 old_uid = name->st.st_uid;
325 old_gid = name->st.st_gid;
327 /* only set the elements that have been specified */
328 if (secinfo_flags & SECINFO_OWNER) {
329 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
330 return NT_STATUS_ACCESS_DENIED;
332 if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
333 ids->sid = new_sd->owner_sid;
334 status = wbc_sids_to_xids(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(ids, 1);
352 NT_STATUS_NOT_OK_RETURN(status);
354 if (ids->xid.type == ID_TYPE_BOTH ||
355 ids->xid.type == ID_TYPE_GID) {
356 new_gid = ids->xid.id;
360 sd->group_sid = new_sd->group_sid;
363 if (secinfo_flags & SECINFO_DACL) {
364 if (!(access_mask & SEC_STD_WRITE_DAC)) {
365 return NT_STATUS_ACCESS_DENIED;
367 sd->dacl = new_sd->dacl;
368 pvfs_translate_generic_bits(sd->dacl);
369 sd->type |= SEC_DESC_DACL_PRESENT;
372 if (secinfo_flags & SECINFO_SACL) {
373 if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
374 return NT_STATUS_ACCESS_DENIED;
376 sd->sacl = new_sd->sacl;
377 pvfs_translate_generic_bits(sd->sacl);
378 sd->type |= SEC_DESC_SACL_PRESENT;
381 if (secinfo_flags & SECINFO_PROTECTED_DACL) {
382 if (new_sd->type & SEC_DESC_DACL_PROTECTED) {
383 sd->type |= SEC_DESC_DACL_PROTECTED;
385 sd->type &= ~SEC_DESC_DACL_PROTECTED;
389 if (secinfo_flags & SECINFO_PROTECTED_SACL) {
390 if (new_sd->type & SEC_DESC_SACL_PROTECTED) {
391 sd->type |= SEC_DESC_SACL_PROTECTED;
393 sd->type &= ~SEC_DESC_SACL_PROTECTED;
397 if (new_uid == old_uid) {
401 if (new_gid == old_gid) {
405 /* if there's something to change try it */
406 if (new_uid != -1 || new_gid != -1) {
409 ret = chown(name->full_name, new_uid, new_gid);
411 ret = fchown(fd, new_uid, new_gid);
413 if (errno == EPERM) {
414 if (pvfs_privileged_access(name->st.st_uid)) {
417 /* try again as root if we have SEC_PRIV_RESTORE or
418 SEC_PRIV_TAKE_OWNERSHIP */
419 if (security_token_has_privilege(req->session_info->security_token,
421 security_token_has_privilege(req->session_info->security_token,
422 SEC_PRIV_TAKE_OWNERSHIP)) {
424 privs = root_privileges();
426 ret = chown(name->full_name, new_uid, new_gid);
428 ret = fchown(fd, new_uid, new_gid);
435 return pvfs_map_errno(pvfs, errno);
439 /* we avoid saving if the sd is the same. This means when clients
440 copy files and end up copying the default sd that we don't
441 needlessly use xattrs */
442 if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
443 status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
451 answer a fileinfo query for the ACL
453 NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs,
454 struct ntvfs_request *req,
455 struct pvfs_filename *name, int fd,
456 union smb_fileinfo *info)
458 NTSTATUS status = NT_STATUS_NOT_FOUND;
459 struct security_descriptor *sd;
462 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
464 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
465 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
467 if (!NT_STATUS_IS_OK(status)) {
471 normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
473 info->query_secdesc.out.sd = sd;
480 check the read only bit against any of the write access bits
482 static bool pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask)
484 if ((pvfs->flags & PVFS_FLAG_READONLY) &&
485 (access_mask & (SEC_FILE_WRITE_DATA |
486 SEC_FILE_APPEND_DATA |
488 SEC_FILE_WRITE_ATTRIBUTE |
491 SEC_STD_WRITE_OWNER |
492 SEC_DIR_DELETE_CHILD))) {
499 see if we are a member of the appropriate unix group
501 static bool pvfs_group_member(struct pvfs_state *pvfs, gid_t gid)
505 if (getegid() == gid) {
508 ngroups = getgroups(0, NULL);
512 groups = talloc_array(pvfs, gid_t, ngroups);
513 if (groups == NULL) {
516 if (getgroups(ngroups, groups) != ngroups) {
520 for (i=0; i<ngroups; i++) {
521 if (groups[i] == gid) break;
528 default access check function based on unix permissions
529 doing this saves on building a full security descriptor
530 for the common case of access check on files with no
533 If name is NULL then treat as a new file creation
535 static NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
536 struct ntvfs_request *req,
537 struct pvfs_filename *name,
538 uint32_t *access_mask)
540 uint32_t max_bits = 0;
541 struct security_token *token = req->session_info->security_token;
543 if (pvfs_read_only(pvfs, *access_mask)) {
544 return NT_STATUS_ACCESS_DENIED;
548 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
549 } else if (pvfs_privileged_access(name->st.st_uid)) {
550 /* use the IxUSR bits */
551 if ((name->st.st_mode & S_IWUSR)) {
552 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
553 } else if ((name->st.st_mode & (S_IRUSR | S_IXUSR))) {
554 max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
556 } else if (pvfs_group_member(pvfs, name->st.st_gid)) {
557 /* use the IxGRP bits */
558 if ((name->st.st_mode & S_IWGRP)) {
559 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
560 } else if ((name->st.st_mode & (S_IRGRP | S_IXGRP))) {
561 max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
564 /* use the IxOTH bits */
565 if ((name->st.st_mode & S_IWOTH)) {
566 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
567 } else if ((name->st.st_mode & (S_IROTH | S_IXOTH))) {
568 max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
572 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
573 *access_mask |= max_bits;
574 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
577 if ((*access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
578 security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
579 max_bits |= SEC_FLAG_SYSTEM_SECURITY;
582 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_RESTORE) &&
583 security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
584 max_bits |= ~(SEC_RIGHTS_PRIV_RESTORE);
586 if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_BACKUP) &&
587 security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
588 max_bits |= ~(SEC_RIGHTS_PRIV_BACKUP);
591 if (*access_mask & ~max_bits) {
592 DEBUG(5,(__location__ " denied access to '%s' - wanted 0x%08x but got 0x%08x (missing 0x%08x)\n",
593 name?name->full_name:"(new file)", *access_mask, max_bits, *access_mask & ~max_bits));
594 return NT_STATUS_ACCESS_DENIED;
597 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
598 /* on SMB, this bit is always granted, even if not
600 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
608 check the security descriptor on a file, if any
610 *access_mask is modified with the access actually granted
612 NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
613 struct ntvfs_request *req,
614 struct pvfs_filename *name,
615 uint32_t *access_mask)
617 struct security_token *token = req->session_info->security_token;
618 struct xattr_NTACL *acl;
620 struct security_descriptor *sd;
621 bool allow_delete = false;
623 /* on SMB2 a blank access mask is always denied */
624 if (pvfs->ntvfs->ctx->protocol >= PROTOCOL_SMB2_02 &&
626 return NT_STATUS_ACCESS_DENIED;
629 if (pvfs_read_only(pvfs, *access_mask)) {
630 return NT_STATUS_ACCESS_DENIED;
633 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
634 *access_mask & SEC_STD_DELETE) {
635 status = pvfs_access_check_parent(pvfs, req,
636 name, SEC_DIR_DELETE_CHILD);
637 if (NT_STATUS_IS_OK(status)) {
639 *access_mask &= ~SEC_STD_DELETE;
643 acl = talloc(req, struct xattr_NTACL);
645 return NT_STATUS_NO_MEMORY;
648 /* expand the generic access bits to file specific bits */
649 *access_mask = pvfs_translate_mask(*access_mask);
650 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
651 *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
654 status = pvfs_acl_load(pvfs, name, -1, acl);
655 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
657 status = pvfs_access_check_unix(pvfs, req, name, access_mask);
660 if (!NT_STATUS_IS_OK(status)) {
664 switch (acl->version) {
669 return NT_STATUS_INVALID_ACL;
672 /* check the acl against the required access mask */
673 status = se_file_access_check(sd, token, false, *access_mask, access_mask);
676 /* if we used a NT acl, then allow access override if the
677 share allows for posix permission override
679 if (NT_STATUS_IS_OK(status)) {
680 name->allow_override = (pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) != 0;
684 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
685 /* on SMB, this bit is always granted, even if not
687 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
691 *access_mask |= SEC_STD_DELETE;
699 a simplified interface to access check, designed for calls that
700 do not take or return an access check mask
702 NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs,
703 struct ntvfs_request *req,
704 struct pvfs_filename *name,
705 uint32_t access_needed)
707 if (access_needed == 0) {
710 return pvfs_access_check(pvfs, req, name, &access_needed);
714 access check for creating a new file/directory
716 NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs,
717 struct ntvfs_request *req,
718 struct pvfs_filename *name,
719 uint32_t *access_mask,
721 struct security_descriptor **sd)
723 struct pvfs_filename *parent;
725 uint32_t parent_mask;
726 bool allow_delete = false;
728 if (pvfs_read_only(pvfs, *access_mask)) {
729 return NT_STATUS_ACCESS_DENIED;
732 status = pvfs_resolve_parent(pvfs, req, name, &parent);
733 NT_STATUS_NOT_OK_RETURN(status);
736 parent_mask = SEC_DIR_ADD_SUBDIR;
738 parent_mask = SEC_DIR_ADD_FILE;
740 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
741 *access_mask & SEC_STD_DELETE) {
742 parent_mask |= SEC_DIR_DELETE_CHILD;
745 status = pvfs_access_check(pvfs, req, parent, &parent_mask);
746 if (NT_STATUS_IS_OK(status)) {
747 if (parent_mask & SEC_DIR_DELETE_CHILD) {
750 } else if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
752 * on ACCESS_DENIED we get the rejected bits
753 * remove the non critical SEC_DIR_DELETE_CHILD
754 * and check if something else was rejected.
756 parent_mask &= ~SEC_DIR_DELETE_CHILD;
757 if (parent_mask != 0) {
758 return NT_STATUS_ACCESS_DENIED;
760 status = NT_STATUS_OK;
766 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, sd);
770 if (!NT_STATUS_IS_OK(status)) {
774 /* expand the generic access bits to file specific bits */
775 *access_mask = pvfs_translate_mask(*access_mask);
777 if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
778 *access_mask |= SEC_RIGHTS_FILE_ALL;
779 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
782 if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
783 /* on SMB, this bit is always granted, even if not
785 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
789 *access_mask |= SEC_STD_DELETE;
796 access check for creating a new file/directory - no access mask supplied
798 NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs,
799 struct ntvfs_request *req,
800 struct pvfs_filename *name,
801 uint32_t access_mask)
803 struct pvfs_filename *parent;
806 status = pvfs_resolve_parent(pvfs, req, name, &parent);
807 if (!NT_STATUS_IS_OK(status)) {
811 status = pvfs_access_check_simple(pvfs, req, parent, access_mask);
812 if (NT_STATUS_IS_OK(status) && parent->allow_override) {
813 name->allow_override = true;
820 determine if an ACE is inheritable
822 static bool pvfs_inheritable_ace(struct pvfs_state *pvfs,
823 const struct security_ace *ace,
827 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
830 if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
834 if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
835 !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
843 this is the core of ACL inheritance. It copies any inheritable
844 aces from the parent SD to the child SD. Note that the algorithm
845 depends on whether the child is a container or not
847 static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs,
848 struct security_descriptor *parent_sd,
849 struct security_descriptor *sd,
854 for (i=0;i<parent_sd->dacl->num_aces;i++) {
855 struct security_ace ace = parent_sd->dacl->aces[i];
857 const struct dom_sid *creator = NULL, *new_id = NULL;
860 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
864 orig_flags = ace.flags;
866 /* see the RAW-ACLS inheritance test for details on these rules */
870 ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
872 if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
873 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
875 if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
880 /* the CREATOR sids are special when inherited */
881 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
882 creator = pvfs->sid_cache.creator_owner;
883 new_id = sd->owner_sid;
884 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
885 creator = pvfs->sid_cache.creator_group;
886 new_id = sd->group_sid;
888 new_id = &ace.trustee;
891 if (creator && container &&
892 (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
893 uint32_t flags = ace.flags;
895 ace.trustee = *new_id;
897 status = security_descriptor_dacl_add(sd, &ace);
898 if (!NT_STATUS_IS_OK(status)) {
902 ace.trustee = *creator;
903 ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
904 status = security_descriptor_dacl_add(sd, &ace);
905 } else if (container &&
906 !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
907 status = security_descriptor_dacl_add(sd, &ace);
909 ace.trustee = *new_id;
910 status = security_descriptor_dacl_add(sd, &ace);
913 if (!NT_STATUS_IS_OK(status)) {
924 calculate the ACL on a new file/directory based on the inherited ACL
925 from the parent. If there is no inherited ACL then return a NULL
926 ACL, which means the default ACL should be used
928 NTSTATUS pvfs_acl_inherited_sd(struct pvfs_state *pvfs,
930 struct ntvfs_request *req,
931 struct pvfs_filename *parent,
933 struct security_descriptor **ret_sd)
935 struct xattr_NTACL *acl;
937 struct security_descriptor *parent_sd, *sd;
939 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
943 acl = talloc(req, struct xattr_NTACL);
945 TALLOC_FREE(tmp_ctx);
946 return NT_STATUS_NO_MEMORY;
949 status = pvfs_acl_load(pvfs, parent, -1, acl);
950 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
951 talloc_free(tmp_ctx);
954 if (!NT_STATUS_IS_OK(status)) {
955 TALLOC_FREE(tmp_ctx);
959 switch (acl->version) {
961 parent_sd = acl->info.sd;
964 talloc_free(tmp_ctx);
965 return NT_STATUS_INVALID_ACL;
968 if (parent_sd == NULL ||
969 parent_sd->dacl == NULL ||
970 parent_sd->dacl->num_aces == 0) {
971 /* go with the default ACL */
972 talloc_free(tmp_ctx);
976 /* create the new sd */
977 sd = security_descriptor_initialise(req);
979 TALLOC_FREE(tmp_ctx);
980 return NT_STATUS_NO_MEMORY;
983 ids = talloc_array(sd, struct id_map, 2);
985 TALLOC_FREE(tmp_ctx);
986 return NT_STATUS_NO_MEMORY;
989 ids[0].xid.id = geteuid();
990 ids[0].xid.type = ID_TYPE_UID;
992 ids[0].status = ID_UNKNOWN;
994 ids[1].xid.id = getegid();
995 ids[1].xid.type = ID_TYPE_GID;
997 ids[1].status = ID_UNKNOWN;
999 status = wbc_xids_to_sids(ids, 2);
1000 if (!NT_STATUS_IS_OK(status)) {
1001 TALLOC_FREE(tmp_ctx);
1005 sd->owner_sid = talloc_steal(sd, ids[0].sid);
1006 sd->group_sid = talloc_steal(sd, ids[1].sid);
1008 sd->type |= SEC_DESC_DACL_PRESENT;
1010 /* fill in the aces from the parent */
1011 status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
1012 if (!NT_STATUS_IS_OK(status)) {
1013 TALLOC_FREE(tmp_ctx);
1017 /* if there is nothing to inherit then we fallback to the
1019 if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
1020 talloc_free(tmp_ctx);
1021 return NT_STATUS_OK;
1024 *ret_sd = talloc_steal(mem_ctx, sd);
1026 talloc_free(tmp_ctx);
1027 return NT_STATUS_OK;
1032 setup an ACL on a new file/directory based on the inherited ACL from
1033 the parent. If there is no inherited ACL then we don't set anything,
1034 as the default ACL applies anyway
1036 NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs,
1037 struct ntvfs_request *req,
1038 struct pvfs_filename *name,
1041 struct xattr_NTACL acl;
1043 struct security_descriptor *sd;
1044 struct pvfs_filename *parent;
1047 /* form the parents path */
1048 status = pvfs_resolve_parent(pvfs, req, name, &parent);
1049 NT_STATUS_NOT_OK_RETURN(status);
1051 container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false;
1053 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, &sd);
1054 if (!NT_STATUS_IS_OK(status)) {
1055 talloc_free(parent);
1060 return NT_STATUS_OK;
1066 status = pvfs_acl_save(pvfs, name, fd, &acl);
1068 talloc_free(parent);
1074 return the maximum allowed access mask
1076 NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs,
1077 struct ntvfs_request *req,
1078 struct pvfs_filename *name,
1079 uint32_t *maximal_access)
1081 *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
1082 return pvfs_access_check(pvfs, req, name, maximal_access);