diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/smbd/posix_acls.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index c52139495c..209387f422 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -2177,7 +2177,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ * acl_mask. Ensure all DENY Entries are at the start of the list. */ - DEBUG(10,("canonicalise_acl: ace entries before arrange :\n")); + DEBUG(10,("canonicalise_acl: %s ace entries before arrange :\n", the_acl_type == SMB_ACL_TYPE_ACCESS ? "Access" : "Default" )); for ( ace_count = 0, ace = list_head; ace; ace = next_ace, ace_count++) { next_ace = ace->next; @@ -2571,24 +2571,51 @@ static size_t merge_default_aces( SEC_ACE *nt_ace_list, size_t num_aces) for (i = 0; i < num_aces; i++) { for (j = i+1; j < num_aces; j++) { + uint32 i_flags_ni = (nt_ace_list[i].flags & ~SEC_ACE_FLAG_INHERITED_ACE); + uint32 j_flags_ni = (nt_ace_list[j].flags & ~SEC_ACE_FLAG_INHERITED_ACE); + BOOL i_inh = (nt_ace_list[i].flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False; + BOOL j_inh = (nt_ace_list[j].flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False; + /* We know the lower number ACE's are file entries. */ if ((nt_ace_list[i].type == nt_ace_list[j].type) && (nt_ace_list[i].size == nt_ace_list[j].size) && (nt_ace_list[i].info.mask == nt_ace_list[j].info.mask) && sid_equal(&nt_ace_list[i].trustee, &nt_ace_list[j].trustee) && - (nt_ace_list[i].flags == 0) && - (nt_ace_list[j].flags == (SEC_ACE_FLAG_OBJECT_INHERIT| - SEC_ACE_FLAG_CONTAINER_INHERIT| - SEC_ACE_FLAG_INHERIT_ONLY))) { + (i_inh == j_inh) && + (i_flags_ni == 0) && + (j_flags_ni == (SEC_ACE_FLAG_OBJECT_INHERIT| + SEC_ACE_FLAG_CONTAINER_INHERIT| + SEC_ACE_FLAG_INHERIT_ONLY))) { /* - * These are identical except for the flags. - * Merge the inherited ACE onto the non-inherited ACE. + * W2K wants to have access allowed zero access ACE's + * at the end of the list. If the mask is zero, merge + * the non-inherited ACE onto the inherited ACE. */ - nt_ace_list[i].flags = SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT; - if (num_aces - j - 1 > 0) - memmove(&nt_ace_list[j], &nt_ace_list[j+1], (num_aces-j-1) * - sizeof(SEC_ACE)); + if (nt_ace_list[i].info.mask == 0) { + nt_ace_list[j].flags = SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT| + (i_inh ? SEC_ACE_FLAG_INHERITED_ACE : 0); + if (num_aces - i - 1 > 0) + memmove(&nt_ace_list[i], &nt_ace_list[i+1], (num_aces-i-1) * + sizeof(SEC_ACE)); + + DEBUG(10,("merge_default_aces: Merging zero access ACE %u onto ACE %u.\n", + (unsigned int)i, (unsigned int)j )); + } else { + /* + * These are identical except for the flags. + * Merge the inherited ACE onto the non-inherited ACE. + */ + + nt_ace_list[i].flags = SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT| + (i_inh ? SEC_ACE_FLAG_INHERITED_ACE : 0); + if (num_aces - j - 1 > 0) + memmove(&nt_ace_list[j], &nt_ace_list[j+1], (num_aces-j-1) * + sizeof(SEC_ACE)); + + DEBUG(10,("merge_default_aces: Merging ACE %u onto ACE %u.\n", + (unsigned int)j, (unsigned int)i )); + } num_aces--; break; } |