The branch, master has been updated via db7e38d s4-tests: Tests for expansion of ACEs containing generic information. via 980f68a security: Fixed bugs in expansion of generic information ACEs from d7c2eb1 abi: force TERM=none in abi generation
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit db7e38d59a88f2d42a816f365719a76dcaee89f1 Author: Nadezhda Ivanova <nivan...@samba.org> Date: Tue Jan 11 12:23:57 2011 +0200 s4-tests: Tests for expansion of ACEs containing generic information. Autobuild-User: Nadezhda Ivanova <nivan...@samba.org> Autobuild-Date: Tue Jan 11 12:10:25 CET 2011 on sn-devel-104 commit 980f68a6f26070270313a4c7a4c0430f2bb3f078 Author: Nadezhda Ivanova <nivan...@samba.org> Date: Tue Jan 11 12:20:43 2011 +0200 security: Fixed bugs in expansion of generic information ACEs When an ACE gontaining GA, GE, GR, GW, CO or CG is provided by a user or inherited the final SD actually has to have 2 ACEs, one is an effective expanded one, and the original one with IO flag added. ----------------------------------------------------------------------- Summary of changes: libcli/security/create_descriptor.c | 120 ++++++++++++++++++--------- source4/dsdb/tests/python/sec_descriptor.py | 61 +++++++++++++- 2 files changed, 141 insertions(+), 40 deletions(-) Changeset truncated at 500 lines: diff --git a/libcli/security/create_descriptor.c b/libcli/security/create_descriptor.c index d5bb21b..2228e48 100644 --- a/libcli/security/create_descriptor.c +++ b/libcli/security/create_descriptor.c @@ -55,12 +55,12 @@ uint32_t map_generic_rights_ds(uint32_t access_mask) { if (access_mask & SEC_GENERIC_ALL) { access_mask |= SEC_ADS_GENERIC_ALL; - access_mask = ~SEC_GENERIC_ALL; + access_mask &= ~SEC_GENERIC_ALL; } if (access_mask & SEC_GENERIC_EXECUTE) { access_mask |= SEC_ADS_GENERIC_EXECUTE; - access_mask = ~SEC_GENERIC_EXECUTE; + access_mask &= ~SEC_GENERIC_EXECUTE; } if (access_mask & SEC_GENERIC_WRITE) { @@ -82,6 +82,45 @@ static bool object_in_list(struct GUID *object_list, struct GUID *object) { return true; } + +/* returns true if the ACE gontains generic information + * that needs to be processed additionally */ + +static bool desc_ace_has_generic(TALLOC_CTX *mem_ctx, + struct security_ace *ace) +{ + struct dom_sid *co, *cg; + co = dom_sid_parse_talloc(mem_ctx, SID_CREATOR_OWNER); + cg = dom_sid_parse_talloc(mem_ctx, SID_CREATOR_GROUP); + if (ace->access_mask & SEC_GENERIC_ALL || ace->access_mask & SEC_GENERIC_READ || + ace->access_mask & SEC_GENERIC_WRITE || ace->access_mask & SEC_GENERIC_EXECUTE) { + return true; + } + if (dom_sid_equal(&ace->trustee, co) || dom_sid_equal(&ace->trustee, cg)) { + return true; + } + return false; +} + +/* creates an ace in which the generic information is expanded */ + +static void desc_expand_generic(TALLOC_CTX *mem_ctx, + struct security_ace *new_ace, + struct dom_sid *owner, + struct dom_sid *group) +{ + struct dom_sid *co, *cg; + co = dom_sid_parse_talloc(mem_ctx, SID_CREATOR_OWNER); + cg = dom_sid_parse_talloc(mem_ctx, SID_CREATOR_GROUP); + new_ace->access_mask = map_generic_rights_ds(new_ace->access_mask); + if (dom_sid_equal(&new_ace->trustee, co)) { + new_ace->trustee = *owner; + } + if (dom_sid_equal(&new_ace->trustee, cg)) { + new_ace->trustee = *group; + } + new_ace->flags = 0x0; +} static struct security_acl *calculate_inherited_from_parent(TALLOC_CTX *mem_ctx, struct security_acl *acl, @@ -108,7 +147,8 @@ static struct security_acl *calculate_inherited_from_parent(TALLOC_CTX *mem_ctx, struct security_ace *ace = &acl->aces[i]; if ((ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) || (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT)) { - tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces, struct security_ace, + tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces, + struct security_ace, tmp_acl->num_aces+1); if (tmp_acl->aces == NULL) { talloc_free(tmp_ctx); @@ -128,30 +168,24 @@ static struct security_acl *calculate_inherited_from_parent(TALLOC_CTX *mem_ctx, } } - tmp_acl->aces[tmp_acl->num_aces].access_mask = - map_generic_rights_ds(ace->access_mask); tmp_acl->num_aces++; if (is_container) { if (!(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) && - ((dom_sid_equal(&ace->trustee, co) || dom_sid_equal(&ace->trustee, cg)))) { - tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces, struct security_ace, + (desc_ace_has_generic(tmp_ctx, ace))) { + tmp_acl->aces = talloc_realloc(tmp_acl, + tmp_acl->aces, + struct security_ace, tmp_acl->num_aces+1); if (tmp_acl->aces == NULL) { talloc_free(tmp_ctx); return NULL; } tmp_acl->aces[tmp_acl->num_aces] = *ace; - tmp_acl->aces[tmp_acl->num_aces].flags &= ~SEC_ACE_FLAG_INHERIT_ONLY; - tmp_acl->aces[tmp_acl->num_aces].flags |= SEC_ACE_FLAG_INHERITED_ACE; - if (dom_sid_equal(&tmp_acl->aces[tmp_acl->num_aces].trustee, co)) { - tmp_acl->aces[tmp_acl->num_aces].trustee = *owner; - } - if (dom_sid_equal(&tmp_acl->aces[tmp_acl->num_aces].trustee, cg)) { - tmp_acl->aces[tmp_acl->num_aces].trustee = *group; - } - tmp_acl->aces[tmp_acl->num_aces].flags &= ~SEC_ACE_FLAG_CONTAINER_INHERIT; - tmp_acl->aces[tmp_acl->num_aces].access_mask = - map_generic_rights_ds(ace->access_mask); + desc_expand_generic(tmp_ctx, + &tmp_acl->aces[tmp_acl->num_aces], + owner, + group); + tmp_acl->aces[tmp_acl->num_aces].flags = SEC_ACE_FLAG_INHERITED_ACE; tmp_acl->num_aces++; } } @@ -200,29 +234,39 @@ static struct security_acl *process_user_acl(TALLOC_CTX *mem_ctx, ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT)) continue; - tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces, struct security_ace, - tmp_acl->num_aces+1); - tmp_acl->aces[tmp_acl->num_aces] = *ace; - if (dom_sid_equal(&(tmp_acl->aces[tmp_acl->num_aces].trustee), co)) { - tmp_acl->aces[tmp_acl->num_aces].trustee = *owner; - tmp_acl->aces[tmp_acl->num_aces].flags &= ~SEC_ACE_FLAG_CONTAINER_INHERIT; - } - if (dom_sid_equal(&(tmp_acl->aces[tmp_acl->num_aces].trustee), cg)) { - tmp_acl->aces[tmp_acl->num_aces].trustee = *group; - tmp_acl->aces[tmp_acl->num_aces].flags &= ~SEC_ACE_FLAG_CONTAINER_INHERIT; - } - tmp_acl->aces[tmp_acl->num_aces].access_mask = - map_generic_rights_ds(tmp_acl->aces[tmp_acl->num_aces].access_mask); - tmp_acl->num_aces++; - - if (!dom_sid_equal(&ace->trustee, co) && !dom_sid_equal(&ace->trustee, cg)) - continue; - - tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces, struct security_ace, + tmp_acl->aces = talloc_realloc(tmp_acl, + tmp_acl->aces, + struct security_ace, tmp_acl->num_aces+1); tmp_acl->aces[tmp_acl->num_aces] = *ace; - tmp_acl->aces[tmp_acl->num_aces].flags |= SEC_ACE_FLAG_INHERIT_ONLY; tmp_acl->num_aces++; + if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) { + continue; + } + /* if the ACE contains CO, CG, GA, GE, GR or GW, and is inheritable + * it has to be expanded to two aces, the original as IO, + * and another one where these are translated */ + if (desc_ace_has_generic(tmp_ctx, ace)) { + if (!(ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) { + desc_expand_generic(tmp_ctx, + &tmp_acl->aces[tmp_acl->num_aces-1], + owner, + group); + } else { + /*The original ACE becomes read only */ + tmp_acl->aces[tmp_acl->num_aces-1].flags |= SEC_ACE_FLAG_INHERIT_ONLY; + tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces, + struct security_ace, + tmp_acl->num_aces+1); + /* add a new ACE with expanded generic info */ + tmp_acl->aces[tmp_acl->num_aces] = *ace; + desc_expand_generic(tmp_ctx, + &tmp_acl->aces[tmp_acl->num_aces], + owner, + group); + tmp_acl->num_aces++; + } + } } new_acl = security_acl_dup(mem_ctx,tmp_acl); diff --git a/source4/dsdb/tests/python/sec_descriptor.py b/source4/dsdb/tests/python/sec_descriptor.py index c08035b..bab0476 100755 --- a/source4/dsdb/tests/python/sec_descriptor.py +++ b/source4/dsdb/tests/python/sec_descriptor.py @@ -1238,12 +1238,19 @@ class OwnerGroupDescriptorTests(DescriptorTests): self.assertEqual("O:DAG:DA", res) ######################################################################################## - # Inharitance tests for DACL + # Inheritance tests for DACL class DaclDescriptorTests(DescriptorTests): def deleteAll(self): delete_force(self.ldb_admin, "CN=test_inherit_group,OU=test_inherit_ou," + self.base_dn) + delete_force(self.ldb_admin, "OU=test_inherit_ou5,OU=test_inherit_ou1,OU=test_inherit_ou_p," + self.base_dn) + delete_force(self.ldb_admin, "OU=test_inherit_ou6,OU=test_inherit_ou2,OU=test_inherit_ou_p," + self.base_dn) + delete_force(self.ldb_admin, "OU=test_inherit_ou1,OU=test_inherit_ou_p," + self.base_dn) + delete_force(self.ldb_admin, "OU=test_inherit_ou2,OU=test_inherit_ou_p," + self.base_dn) + delete_force(self.ldb_admin, "OU=test_inherit_ou3,OU=test_inherit_ou_p," + self.base_dn) + delete_force(self.ldb_admin, "OU=test_inherit_ou4,OU=test_inherit_ou_p," + self.base_dn) + delete_force(self.ldb_admin, "OU=test_inherit_ou_p," + self.base_dn) delete_force(self.ldb_admin, "OU=test_inherit_ou," + self.base_dn) def setUp(self): @@ -1545,7 +1552,8 @@ class DaclDescriptorTests(DescriptorTests): tmp_desc = security.descriptor.from_sddl(mod, self.domain_sid) self.ldb_admin.newgroup("test_inherit_group", groupou="OU=test_inherit_ou", grouptype=4, sd=tmp_desc) desc_sddl = self.sd_utils.get_sd_as_sddl(group_dn) - self.assertTrue("(D;;WP;;;DA)(D;CIIO;WP;;;CO)" in desc_sddl) + self.assertTrue("(D;;WP;;;DA)" in desc_sddl) + self.assertTrue("(D;CIIO;WP;;;CO)" in desc_sddl) def test_212(self): """ Provide ACE with IO flag, should be ignored @@ -1580,6 +1588,55 @@ class DaclDescriptorTests(DescriptorTests): desc_sddl = self.sd_utils.get_sd_as_sddl(group_dn) self.assertFalse("(D;IO;WP;;;DA)" in desc_sddl) + def test_214(self): + """ Test behavior of ACEs containing generic rights + """ + ou_dn = "OU=test_inherit_ou_p," + self.base_dn + ou_dn1 = "OU=test_inherit_ou1," + ou_dn + ou_dn2 = "OU=test_inherit_ou2," + ou_dn + ou_dn3 = "OU=test_inherit_ou3," + ou_dn + ou_dn4 = "OU=test_inherit_ou4," + ou_dn + ou_dn5 = "OU=test_inherit_ou5," + ou_dn1 + ou_dn6 = "OU=test_inherit_ou6," + ou_dn2 + # Create inheritable-free OU + mod = "D:P(A;CI;WPRPLCCCDCWDRC;;;DA)" + tmp_desc = security.descriptor.from_sddl(mod, self.domain_sid) + self.ldb_admin.create_ou(ou_dn, sd=tmp_desc) + mod = "D:(A;CI;GA;;;DU)" + tmp_desc = security.descriptor.from_sddl(mod, self.domain_sid) + self.ldb_admin.create_ou(ou_dn1, sd=tmp_desc) + mod = "D:(A;CIIO;GA;;;DU)" + tmp_desc = security.descriptor.from_sddl(mod, self.domain_sid) + self.ldb_admin.create_ou(ou_dn2, sd=tmp_desc) + mod = "D:(A;;GA;;;DU)" + tmp_desc = security.descriptor.from_sddl(mod, self.domain_sid) + self.ldb_admin.create_ou(ou_dn3, sd=tmp_desc) + mod = "D:(A;IO;GA;;;DU)" + tmp_desc = security.descriptor.from_sddl(mod, self.domain_sid) + self.ldb_admin.create_ou(ou_dn4, sd=tmp_desc) + + self.ldb_admin.create_ou(ou_dn5) + self.ldb_admin.create_ou(ou_dn6) + + desc_sddl = self.sd_utils.get_sd_as_sddl(ou_dn1) + self.assertTrue("(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DU)" in desc_sddl) + self.assertTrue("(A;CIIO;GA;;;DU)" in desc_sddl) + desc_sddl = self.sd_utils.get_sd_as_sddl(ou_dn2) + self.assertFalse("(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DU)" in desc_sddl) + self.assertTrue("(A;CIIO;GA;;;DU)" in desc_sddl) + desc_sddl = self.sd_utils.get_sd_as_sddl(ou_dn3) + self.assertTrue("(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DU)" in desc_sddl) + self.assertFalse("(A;CIIO;GA;;;DU)" in desc_sddl) + desc_sddl = self.sd_utils.get_sd_as_sddl(ou_dn4) + self.assertFalse("(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DU)" in desc_sddl) + self.assertFalse("(A;CIIO;GA;;;DU)" in desc_sddl) + desc_sddl = self.sd_utils.get_sd_as_sddl(ou_dn5) + self.assertTrue("(A;ID;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DU)" in desc_sddl) + self.assertTrue("(A;CIIOID;GA;;;DU)" in desc_sddl) + desc_sddl = self.sd_utils.get_sd_as_sddl(ou_dn6) + self.assertTrue("(A;ID;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DU)" in desc_sddl) + self.assertTrue("(A;CIIOID;GA;;;DU)" in desc_sddl) + ######################################################################################## -- Samba Shared Repository