diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 766c7b0..f2efa3e 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -946,10 +946,21 @@ static void merge_aces( canon_ace **pp_list_head ) } /* Merge two allow or two deny ACE's. */ + if (curr_ace_outer->type == SMB_ACL_USER_OBJ || + curr_ace_outer->type == SMB_ACL_GROUP_OBJ) { + curr_ace_outer->perms = curr_ace->perms; + }else if(curr_ace->type == SMB_ACL_USER_OBJ || + curr_ace->type == SMB_ACL_GROUP_OBJ) { + curr_ace->perms = curr_ace_outer->perms; + }else{ + /* merge permission(original code) */ + curr_ace_outer->perms |= curr_ace->perms; + } + if (curr_ace->type == curr_ace_outer->type) { + DLIST_REMOVE(l_head, curr_ace); + SAFE_FREE(curr_ace); + } - curr_ace_outer->perms |= curr_ace->perms; - DLIST_REMOVE(l_head, curr_ace); - SAFE_FREE(curr_ace); curr_ace_outer_next = curr_ace_outer->next; /* We may have deleted the link. */ } } @@ -1500,6 +1511,36 @@ static void check_owning_objs(canon_ace *ace, DOM_SID *pfile_owner_sid, DOM_SID DEBUG(10,("check_owning_objs: ACL is missing an owning group entry.\n")); } +static void dup_creatorown_ace(canon_ace *dir_ace, canon_ace *ace) +{ + /* dir ace must be followings. + SMB_ACL_USER_OBJ : trustee(CREATOR_OWNER) -> Posix ACL d:u::perm + SMB_ACL_USER : not trustee -> Posix ACL u:user:perm + SMB_ACL_USER_OBJ : trustee -> convert to SMB_ACL_USER : trustee + Posix ACL u:trustee:perm + + SMB_ACL_GROUP_OBJ: trustee(CREATOR_GROUP) -> Posix ACL d:g::perm + SMB_ACL_GROUP : not trustee -> Posix ACL g:group:perm + SMB_ACL_GROUP_OBJ: trustee -> convert to SMB_ACL_GROUP : trustee + Posix ACL g:trustee:perm + */ + + if (ace->type == SMB_ACL_USER_OBJ && + !(sid_equal(&ace->trustee, &global_sid_Creator_Owner))) { + canon_ace *dup_ace = dup_canon_ace(ace); + dup_ace->type = SMB_ACL_USER; + DLIST_ADD_END(dir_ace, dup_ace, canon_ace *); + } + + if (ace->type == SMB_ACL_GROUP_OBJ && + !(sid_equal(&ace->trustee, &global_sid_Creator_Group))) { + canon_ace *dup_ace = dup_canon_ace(ace); + dup_ace->type = SMB_ACL_GROUP; + DLIST_ADD_END(dir_ace, dup_ace, canon_ace *); + } +} + + /**************************************************************************** Unpack a SEC_DESC into two canonical ace lists. ****************************************************************************/ @@ -1754,12 +1795,22 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name )); return False; } + /* duplicate ace of + SMB_ACL_USER_OBJ and + SMB_ACL_GROUP_OBJ */ + dup_creatorown_ace(dir_ace, current_ace); + /* * We must not free current_ace here as its * pointer is now owned by the dir_ace list. */ current_ace = dup_ace; } else { + /* duplicate ace of + SMB_ACL_USER_OBJ and + SMB_ACL_GROUP_OBJ */ + dup_creatorown_ace(dir_ace, current_ace); + /* * We must not free current_ace here as its * pointer is now owned by the dir_ace list.