s4:objectclass LDB module - implement the "isCriticalSystemObject" subtree delete...
authorMatthias Dieter Wallnöfer <mdw@samba.org>
Sat, 16 Oct 2010 10:28:25 +0000 (12:28 +0200)
committerMatthias Dieter Wallnöfer <mdw@samba.org>
Sat, 16 Oct 2010 11:24:09 +0000 (11:24 +0000)
MS-ADTS 3.1.1.5.5.7.2

Autobuild-User: Matthias Dieter Wallnöfer <mdw@samba.org>
Autobuild-Date: Sat Oct 16 11:24:09 UTC 2010 on sn-devel-104

source4/dsdb/samdb/ldb_modules/objectclass.c
source4/dsdb/tests/python/deletetest.py

index 86708eb820dd9e939b7ec68433c6ff5592c2fd99..02c3e4680fc43b7e849051193d29a839ddac2c9e 100644 (file)
@@ -1348,7 +1348,8 @@ static int objectclass_do_delete(struct oc_context *ac);
 static int objectclass_delete(struct ldb_module *module, struct ldb_request *req)
 {
        static const char * const attrs[] = { "nCName", "objectClass",
-                                             "systemFlags", NULL };
+                                             "systemFlags",
+                                             "isCriticalSystemObject", NULL };
        struct ldb_context *ldb;
        struct ldb_request *search_req;
        struct oc_context *ac;
@@ -1397,6 +1398,7 @@ static int objectclass_do_delete(struct oc_context *ac)
        struct ldb_context *ldb;
        struct ldb_dn *dn;
        int32_t systemFlags;
+       bool isCriticalSystemObject;
        int ret;
 
        ldb = ldb_module_get_ctx(ac->module);
@@ -1466,6 +1468,19 @@ static int objectclass_do_delete(struct oc_context *ac)
                return LDB_ERR_UNWILLING_TO_PERFORM;
        }
 
+       /* isCriticalSystemObject - but this only applies on tree delete
+        * operations - MS-ADTS 3.1.1.5.5.7.2 */
+       if (ldb_request_get_control(ac->req, LDB_CONTROL_TREE_DELETE_OID) != NULL) {
+               isCriticalSystemObject = ldb_msg_find_attr_as_bool(ac->search_res->message,
+                                                                  "isCriticalSystemObject", false);
+               if (isCriticalSystemObject) {
+                       ldb_asprintf_errstring(ldb,
+                                              "objectclass: Cannot tree-delete %s, it's a critical system object!",
+                                              ldb_dn_get_linearized(ac->req->op.del.dn));
+                       return LDB_ERR_UNWILLING_TO_PERFORM;
+               }
+       }
+
        return ldb_next_request(ac->module, ac->req);
 }
 
index 2b0372db65be8a670937cbae086e13e749f72a57..59ebf99c70a6a380a462ee0ced37932a55cd5af5 100755 (executable)
@@ -181,6 +181,7 @@ class BasicDeleteTests(unittest.TestCase):
                          attrs=["dsServiceName", "dNSHostName"])
         self.assertEquals(len(res), 1)
 
+        # Delete failing since DC's nTDSDSA object is protected
         try:
             ldb.delete(res[0]["dsServiceName"][0])
             self.fail()
@@ -191,6 +192,7 @@ class BasicDeleteTests(unittest.TestCase):
                          expression="(&(objectClass=computer)(dNSHostName=" + res[0]["dNSHostName"][0] + "))")
         self.assertEquals(len(res), 1)
 
+        # Deletes failing since DC's rIDSet object is protected
         try:
             ldb.delete(res[0]["rIDSetReferences"][0])
             self.fail()
@@ -202,6 +204,8 @@ class BasicDeleteTests(unittest.TestCase):
         except LdbError, (num, _):
             self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
+        # Deletes failing since three main crossRef objects are protected
+
         try:
             ldb.delete("cn=Enterprise Schema,cn=Partitions," + self.configuration_dn)
             self.fail()
@@ -239,8 +243,6 @@ class BasicDeleteTests(unittest.TestCase):
         except LdbError, (num, _):
             self.assertEquals(num, ERR_NOT_ALLOWED_ON_NON_LEAF)
 
-        # Performs some "systemFlags" testing
-
         # Delete failing since "SYSTEM_FLAG_DISALLOW_DELETE"
         try:
             ldb.delete("CN=Users," + self.base_dn)
@@ -248,6 +250,13 @@ class BasicDeleteTests(unittest.TestCase):
         except LdbError, (num, _):
             self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
 
+        # Tree-delete failing since "isCriticalSystemObject"
+        try:
+            ldb.delete("CN=Computers," + self.base_dn, ["tree_delete:1"])
+            self.fail()
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_UNWILLING_TO_PERFORM)
+
     def test_all(self):
         """Basic delete tests"""