diff options
-rw-r--r-- | source4/ntvfs/posix/pvfs_acl.c | 38 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.c | 4 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.h | 6 |
3 files changed, 47 insertions, 1 deletions
diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index ce5f3a248b..ba5fa96b07 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -470,11 +470,15 @@ static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs, for (i=0;i<parent_sd->dacl->num_aces;i++) { struct security_ace ace = parent_sd->dacl->aces[i]; NTSTATUS status; + const struct dom_sid *creator = NULL, *new_id = NULL; + uint32_t orig_flags; if (!pvfs_inheritable_ace(pvfs, &ace, container)) { continue; } + orig_flags = ace.flags; + /* see the RAW-ACLS inheritance test for details on these rules */ if (!container) { ace.flags = 0; @@ -489,7 +493,39 @@ static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs, } } - status = security_descriptor_dacl_add(sd, &ace); + /* the CREATOR sids are special when inherited */ + if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) { + creator = pvfs->sid_cache.creator_owner; + new_id = sd->owner_sid; + } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) { + creator = pvfs->sid_cache.creator_group; + new_id = sd->group_sid; + } else { + new_id = &ace.trustee; + } + + if (creator && container && + (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) { + uint32_t flags = ace.flags; + + ace.trustee = *new_id; + ace.flags = 0; + status = security_descriptor_dacl_add(sd, &ace); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + ace.trustee = *creator; + ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY; + status = security_descriptor_dacl_add(sd, &ace); + } else if (container && + !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) { + status = security_descriptor_dacl_add(sd, &ace); + } else { + ace.trustee = *new_id; + status = security_descriptor_dacl_add(sd, &ace); + } + if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index eecc379064..e5bdc3faae 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -26,6 +26,7 @@ #include "includes.h" #include "vfs_posix.h" +#include "librpc/gen_ndr/ndr_security.h" /* @@ -82,6 +83,9 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { pvfs->fs_attribs |= FS_ATTR_PERSISTANT_ACLS; } + + pvfs->sid_cache.creator_owner = dom_sid_parse_talloc(pvfs, SID_CREATOR_OWNER); + pvfs->sid_cache.creator_group = dom_sid_parse_talloc(pvfs, SID_CREATOR_GROUP); } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index e80790f6fa..f7bf19c3dc 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -60,6 +60,12 @@ struct pvfs_state { /* if posix:eadb is set, then this gets setup */ struct tdb_wrap *ea_db; + + /* used to accelerate acl mapping */ + struct { + const struct dom_sid *creator_owner; + const struct dom_sid *creator_group; + } sid_cache; }; /* this is the basic information needed about a file from the filesystem */ |