The branch, master has been updated via 3f2a8d5... s4:urgent_replication.py test - adapt the test for the harder delete restrictions via ea5c404... s4:ldap.py - perform tests on the additional delete constraint checks via 316eda1... s4:objectclass LDB module - implement additional delete constraint checks from c59ab01... s3: Fix an uninitialized variable
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 3f2a8d508123550c7fd4c7d29ab7d53f24a61629 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Sun Aug 1 17:44:50 2010 +0200 s4:urgent_replication.py test - adapt the test for the harder delete restrictions Otherwise we are not able to delete the "test crossRef" object which points to the default NC anymore. commit ea5c40428f7e195f9db1efbd320969184bda6593 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Sun Aug 1 13:09:46 2010 +0200 s4:ldap.py - perform tests on the additional delete constraint checks commit 316eda12068af4f059a082d0a9299d8fdb02d602 Author: Matthias Dieter Wallnöfer <m...@samba.org> Date: Sun Aug 1 12:50:56 2010 +0200 s4:objectclass LDB module - implement additional delete constraint checks MS-ADTS 3.1.1.5.5.3 ----------------------------------------------------------------------- Summary of changes: source4/dsdb/samdb/ldb_modules/objectclass.c | 50 +++++++++++++++++++++- source4/dsdb/tests/python/ldap.py | 42 +++++++++++++++++-- source4/dsdb/tests/python/urgent_replication.py | 2 +- 3 files changed, 86 insertions(+), 8 deletions(-) Changeset truncated at 500 lines: diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 5883d5c..b71f91f 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -1238,7 +1238,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[] = { "systemFlags", NULL }; + static const char * const attrs[] = { "nCName", "objectClass", + "systemFlags", NULL }; struct ldb_context *ldb; struct ldb_request *search_req; struct oc_context *ac; @@ -1253,7 +1254,7 @@ static int objectclass_delete(struct ldb_module *module, struct ldb_request *req return ldb_next_request(module, req); } - /* Bypass the "systemFlags" checks when we do have the "RELAX" control + /* Bypass the constraint checks when we do have the "RELAX" control * set. */ if (ldb_request_get_control(req, LDB_CONTROL_RELAX_OID) != NULL) { return ldb_next_request(module, req); @@ -1265,7 +1266,7 @@ static int objectclass_delete(struct ldb_module *module, struct ldb_request *req } /* this looks up the entry object for fetching some important - * informations (systemFlags...) */ + * informations (object classes, system flags...) */ ret = ldb_build_search_req(&search_req, ldb, ac, req->op.del.dn, LDB_SCOPE_BASE, "(objectClass=*)", @@ -1284,7 +1285,9 @@ static int objectclass_delete(struct ldb_module *module, struct ldb_request *req static int objectclass_do_delete(struct oc_context *ac) { struct ldb_context *ldb; + struct ldb_dn *dn; int32_t systemFlags; + int ret; ldb = ldb_module_get_ctx(ac->module); @@ -1296,6 +1299,47 @@ static int objectclass_do_delete(struct oc_context *ac) return LDB_ERR_NO_SUCH_OBJECT; } + /* DC's ntDSDSA object */ + if (ldb_dn_compare(ac->req->op.del.dn, samdb_ntds_settings_dn(ldb)) == 0) { + ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, it's the DC's ntDSDSA object!", + ldb_dn_get_linearized(ac->req->op.del.dn)); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + /* DC's rIDSet object */ + ret = samdb_rid_set_dn(ldb, ac, &dn); + if (ret != LDB_SUCCESS) { + return ret; + } + + if (ldb_dn_compare(ac->req->op.del.dn, dn) == 0) { + talloc_free(dn); + ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, it's the DC's rIDSet object!", + ldb_dn_get_linearized(ac->req->op.del.dn)); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + talloc_free(dn); + + /* crossRef objects regarding config, schema and default domain NCs */ + if (samdb_find_attribute(ldb, ac->search_res->message, "objectClass", + "crossRef") != NULL) { + dn = ldb_msg_find_attr_as_dn(ldb, ac, ac->search_res->message, + "nCName"); + if ((ldb_dn_compare(dn, ldb_get_default_basedn(ldb)) == 0) || + (ldb_dn_compare(dn, ldb_get_config_basedn(ldb)) == 0) || + (ldb_dn_compare(dn, ldb_get_schema_basedn(ldb)) == 0)) { + talloc_free(dn); + + ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, it's a crossRef object to the three main partitions!", + ldb_dn_get_linearized(ac->req->op.del.dn)); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + talloc_free(dn); + } + + /* systemFlags */ + systemFlags = ldb_msg_find_attr_as_int(ac->search_res->message, "systemFlags", 0); if ((systemFlags & SYSTEM_FLAG_DISALLOW_DELETE) != 0) { diff --git a/source4/dsdb/tests/python/ldap.py b/source4/dsdb/tests/python/ldap.py index b48ee26..ea0aa3a 100755 --- a/source4/dsdb/tests/python/ldap.py +++ b/source4/dsdb/tests/python/ldap.py @@ -1569,10 +1569,9 @@ objectClass: container self.assertEquals(len(res), 1) self.assertTrue("subScheamSubEntry" not in res[0]) - def test_subtree_delete(self): - """Tests subtree deletes""" - - print "Test subtree deletes""" + def test_delete(self): + """Tests the delete operation""" + print "Tests the delete operations""" ldb.add({ "dn": "cn=ldaptestcontainer," + self.base_dn, @@ -1615,6 +1614,41 @@ objectClass: container self.delete_force(self.ldb, "cn=entry2,cn=ldaptestcontainer," + self.base_dn) self.delete_force(self.ldb, "cn=ldaptestcontainer," + self.base_dn) + # Performs some protected object delete testing + + res = ldb.search(base="", expression="", scope=SCOPE_BASE, + attrs=["dsServiceName", "dNSHostName"]) + self.assertEquals(len(res), 1) + + try: + ldb.delete(res[0]["dsServiceName"][0]) + self.fail() + except LdbError, (num, _): + self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) + + res = ldb.search(self.base_dn, scope=SCOPE_SUBTREE, + attrs=["rIDSetReferences"], + expression="(&(objectClass=computer)(dNSHostName=" + res[0]["dNSHostName"][0] + "))") + self.assertEquals(len(res), 1) + + try: + ldb.delete(res[0]["rIDSetReferences"][0]) + self.fail() + except LdbError, (num, _): + self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) + + try: + ldb.delete("cn=Enterprise Schema,cn=Partitions," + self.configuration_dn) + self.fail() + except LdbError, (num, _): + self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) + + try: + ldb.delete("cn=Enterprise Configuration,cn=Partitions," + self.configuration_dn) + self.fail() + except LdbError, (num, _): + self.assertEquals(num, ERR_UNWILLING_TO_PERFORM) + # Performs some "systemFlags" testing # Delete failing since "SYSTEM_FLAG_DISALLOW_DELETE" diff --git a/source4/dsdb/tests/python/urgent_replication.py b/source4/dsdb/tests/python/urgent_replication.py index 092466d..42f3cd0 100755 --- a/source4/dsdb/tests/python/urgent_replication.py +++ b/source4/dsdb/tests/python/urgent_replication.py @@ -43,7 +43,7 @@ class UrgentReplicationTests(samba.tests.TestCase): def delete_force(self, ldb, dn): try: - ldb.delete(dn) + ldb.delete(dn, ["relax:0"]) except LdbError, (num, _): self.assertEquals(num, ERR_NO_SUCH_OBJECT) -- Samba Shared Repository