s4-dsacl: Fixed incorrect handling of privileges in sec_access_check_ds
authorNadezhda Ivanova <nivanova@symas.com>
Mon, 14 Oct 2013 23:06:38 +0000 (02:06 +0300)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 24 Oct 2013 20:45:57 +0000 (09:45 +1300)
Restore and backup privileges are not relevant to ldap
access checks, and the TakeOwnership privilege should
grant write_owner right

Signed-off-by: Nadezhda Ivanova <nivanova@symas.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
libcli/security/access_check.c
source4/dsdb/tests/python/acl.py
source4/dsdb/tests/python/ldap.py

index 2425e8a..2be5928 100644 (file)
@@ -436,14 +436,10 @@ NTSTATUS sec_access_check_ds(const struct security_descriptor *sd,
                bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
        }
 
-       /* TODO: remove this, as it is file server specific */
-       if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
-           security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
-               bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
-       }
-       if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
-           security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
-               bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
+       /* SEC_PRIV_TAKE_OWNERSHIP grants SEC_STD_WRITE_OWNER */
+       if ((bits_remaining & (SEC_STD_WRITE_OWNER)) &&
+           security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
+               bits_remaining &= ~(SEC_STD_WRITE_OWNER);
        }
 
        /* a NULL dacl allows access */
index ecda3c5..7439be6 100755 (executable)
@@ -1250,6 +1250,32 @@ class AclRenameTests(AclTests):
         res = self.ldb_admin.search(self.base_dn, expression="(distinguishedName=%s)" % ou3_dn)
         self.assertNotEqual(len(res), 0)
 
+    def test_rename_u9(self):
+        """Rename 'User object' cross OU, with explicit deny on sd and dc"""
+        ou1_dn = "OU=test_rename_ou1," + self.base_dn
+        ou2_dn = "OU=test_rename_ou2," + self.base_dn
+        user_dn = "CN=test_rename_user2," + ou1_dn
+        rename_user_dn = "CN=test_rename_user5," + ou2_dn
+        # Create OU structure
+        self.ldb_admin.create_ou(ou1_dn)
+        self.ldb_admin.create_ou(ou2_dn)
+        self.ldb_admin.newuser(self.testuser2, self.user_pass, userou=self.ou1)
+        mod = "(D;;SD;;;DA)"
+        self.sd_utils.dacl_add_ace(user_dn, mod)
+        mod = "(D;;DC;;;DA)"
+        self.sd_utils.dacl_add_ace(ou1_dn, mod)
+        # Rename 'User object' having SD and CC to AU
+        try:
+            self.ldb_admin.rename(user_dn, rename_user_dn)
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_INSUFFICIENT_ACCESS_RIGHTS)
+        else:
+            self.fail()
+        #add an allow ace so we can delete this ou
+        mod = "(A;;DC;;;DA)"
+        self.sd_utils.dacl_add_ace(ou1_dn, mod)
+
+
 #tests on Control Access Rights
 class AclCARTests(AclTests):
 
index 63c422a..643830f 100755 (executable)
@@ -2649,7 +2649,7 @@ nTSecurityDescriptor:: """ + desc_base64)
         user_dn = "CN=%s,CN=Users,%s" % (user_name, self.base_dn)
         delete_force(self.ldb, user_dn)
         try:
-            sddl = "O:DUG:DUD:PAI(A;;RPWP;;;AU)S:PAI"
+            sddl = "O:DUG:DUD:AI(A;;RPWP;;;AU)S:PAI"
             desc = security.descriptor.from_sddl(sddl, security.dom_sid('S-1-5-21'))
             desc_base64 = base64.b64encode( ndr_pack(desc) )
             self.ldb.add_ldif("""
@@ -2659,6 +2659,10 @@ sAMAccountName: """ + user_name + """
 nTSecurityDescriptor:: """ + desc_base64)
             res = self.ldb.search(base=user_dn, attrs=["nTSecurityDescriptor"])
             self.assertTrue("nTSecurityDescriptor" in res[0])
+            desc = res[0]["nTSecurityDescriptor"][0]
+            desc = ndr_unpack(security.descriptor, desc)
+            desc_sddl = desc.as_sddl(self.domain_sid)
+            self.assertTrue("O:S-1-5-21-513G:S-1-5-21-513D:AI(A;;RPWP;;;AU)" in desc_sddl)
         finally:
             delete_force(self.ldb, user_dn)