summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Dieter Wallnöfer <mdw@samba.org>2010-08-01 12:50:56 +0200
committerMatthias Dieter Wallnöfer <mdw@samba.org>2010-08-01 18:50:57 +0200
commit316eda12068af4f059a082d0a9299d8fdb02d602 (patch)
tree8b1bf4d11ac65b64579657071998a534a16482ff
parentc59ab01e33aa5fbfd3837d311c0e65593ab7a08a (diff)
downloadsamba-316eda12068af4f059a082d0a9299d8fdb02d602.tar.gz
samba-316eda12068af4f059a082d0a9299d8fdb02d602.tar.bz2
samba-316eda12068af4f059a082d0a9299d8fdb02d602.zip
s4:objectclass LDB module - implement additional delete constraint checks
MS-ADTS 3.1.1.5.5.3
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectclass.c50
1 files changed, 47 insertions, 3 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index 5883d5c97e..b71f91f185 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) {