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;
+ }
Could it be possible to be a bit less "violent" here ?
This change breaks upgradeprovision in full mode when upgrading at least
alpha10 but I'm pretty sure that alpha8,9 and 11 are broken too ...
The thing is that old provision do not have the rid_set ... it seems :
#0 samdb_reference_dn (ldb=0x84db9b0, mem_ctx=0x8687458,
base=0x90e9ab8, attribute=0xb79f3a14 "rIDSetReferences",
dn=0xbfffe2b8) at ../dsdb/common/util.c:1646
#1 0xb787f03d in samdb_rid_set_dn (ldb=0x84db9b0, mem_ctx=0x8687458,
dn=0xbfffe2b8) at ../dsdb/common/util.c:1697
#2 0xb788c334 in objectclass_do_delete (ac=0x8687458) at
../dsdb/samdb/ldb_modules/objectclass.c:1370
1646 talloc_free(res);
(gdb) list
1641 return LDB_ERR_NO_SUCH_OBJECT;
1642 }
1643
1644 *dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, res->msgs[0],
attribute);
1645 if (!*dn) {
1646 talloc_free(res);
1647 return LDB_ERR_NO_SUCH_ATTRIBUTE;
1648 }
1649
1650 talloc_free(res);
The breakpoint is just before the return LDB_ERR_NO_SUCH_ATTRIBUTE
Is something like this sensible ?:
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -1367,19 +1367,20 @@ static int objectclass_do_delete(struct
oc_context *ac)
/* DC's rIDSet object */
ret = samdb_rid_set_dn(ldb, ac, &dn);
- if (ret != LDB_SUCCESS) {
+ if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) {
return ret;
}
+ if (ret == LDB_SUCCESS) {
+ 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;
+ }
- 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) {
Matthieu.
--
Matthieu Patou
Samba Team http://samba.org