s4:objectclass LDB module - implement additional delete constraint checks

Matthieu Patou mat at samba.org
Mon Aug 9 13:45:58 MDT 2010


> commit 316eda12068af4f059a082d0a9299d8fdb02d602
> Author: Matthias Dieter Wallnöfer<mdw at 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



More information about the samba-cvs mailing list