summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectclass.c17
-rwxr-xr-xsource4/dsdb/tests/python/deletetest.py13
2 files changed, 27 insertions, 3 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index 86708eb820..02c3e4680f 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -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);
}
diff --git a/source4/dsdb/tests/python/deletetest.py b/source4/dsdb/tests/python/deletetest.py
index 2b0372db65..59ebf99c70 100755
--- a/source4/dsdb/tests/python/deletetest.py
+++ b/source4/dsdb/tests/python/deletetest.py
@@ -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"""