dsdb:extended_dn_store: We need to ignore self references on add operation
authorStefan Metzmacher <metze@samba.org>
Wed, 28 Feb 2018 07:03:24 +0000 (08:03 +0100)
committerAndreas Schneider <asn@cryptomilk.org>
Mon, 19 Mar 2018 19:30:50 +0000 (20:30 +0100)
We have several schema related tests, which already prove
that for the defaultObjectCategory attribute.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13307

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source4/dsdb/samdb/ldb_modules/extended_dn_store.c

index 119b217f5f64bdc9a668900602609302ec579e18..7f26091505ec30b68e74c998f905ceba326b1760 100644 (file)
@@ -219,6 +219,7 @@ static int extended_replace_dn(struct ldb_request *req, struct ldb_reply *ares)
 
 static int extended_store_replace(struct extended_dn_context *ac,
                                  TALLOC_CTX *callback_mem_ctx,
+                                 struct ldb_dn *self_dn,
                                  struct ldb_val *plain_dn,
                                  bool is_delete, 
                                  const struct dsdb_attribute *schema_attr)
@@ -250,6 +251,19 @@ static int extended_store_replace(struct extended_dn_context *ac,
                return LDB_ERR_INVALID_DN_SYNTAX;
        }
 
+       if (self_dn != NULL) {
+               ret = ldb_dn_compare(self_dn, os->dsdb_dn->dn);
+               if (ret == 0) {
+                       /*
+                        * If this is a reference to the object
+                        * itself during an 'add', we won't
+                        * be able to find the object.
+                        */
+                       talloc_free(os);
+                       return LDB_SUCCESS;
+               }
+       }
+
        if (is_delete && !ldb_dn_has_extended(os->dsdb_dn->dn)) {
                /* NO need to figure this DN out, this element is
                 * going to be deleted anyway, and becuase it's not
@@ -353,7 +367,9 @@ static int extended_dn_add(struct ldb_module *module, struct ldb_request *req)
                /* Re-calculate el */
                el = &ac->new_req->op.add.message->elements[i];
                for (j = 0; j < el->num_values; j++) {
-                       ret = extended_store_replace(ac, ac->new_req, &el->values[j],
+                       ret = extended_store_replace(ac, ac->new_req,
+                                                    req->op.add.message->dn,
+                                                    &el->values[j],
                                                     false, schema_attr);
                        if (ret != LDB_SUCCESS) {
                                return ret;
@@ -449,7 +465,9 @@ static int extended_dn_modify(struct ldb_module *module, struct ldb_request *req
                         * input of an extended DN */
                        bool is_delete = (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE);
 
-                       ret = extended_store_replace(ac, ac->new_req, &el->values[j],
+                       ret = extended_store_replace(ac, ac->new_req,
+                                                    NULL, /* self_dn to be ignored */
+                                                    &el->values[j],
                                                     is_delete, schema_attr);
                        if (ret != LDB_SUCCESS) {
                                talloc_free(ac);