r23762: Fix DN renames over LDAP, and instrument the partition module. Add a
authorAndrew Bartlett <abartlet@samba.org>
Mon, 9 Jul 2007 12:31:35 +0000 (12:31 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:59:11 +0000 (14:59 -0500)
test to prove the behaviour of LDAP renames etc.

Fix LDB to return correct error code when failing to rename one DN
onto another.

Andrew Bartlett

source/dsdb/samdb/ldb_modules/partition.c
source/ldap_server/ldap_backend.c
source/lib/ldb/ldb_tdb/ldb_tdb.c
testprogs/ejs/ldap.js

index b0875d2965e7baba0b4db3cc05c0bd3ebaee733e..73ee4ef3a6f83c7597b2cce61a14e1223a3f2411 100644 (file)
@@ -120,25 +120,6 @@ static struct dsdb_control_current_partition *find_partition(struct partition_pr
        return NULL;
 };
 
-static struct ldb_module *find_backend(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn)
-{
-       struct dsdb_control_current_partition *partition;
-       struct partition_private_data *data = talloc_get_type(module->private_data, 
-                                                             struct partition_private_data);
-
-       /* Skip the lot if 'data' isn't here yet (initialistion) */
-       if (!data) {
-               return module;
-       }
-
-       partition = find_partition(data, dn);
-       if (!partition) {
-               return module;
-       }
-
-       return make_module_for_next_request(req, module->ldb, partition->module);
-};
-
 /*
   fire the caller's callback for every entry, but only send 'done' once.
 */
@@ -442,10 +423,31 @@ static int partition_delete(struct ldb_module *module, struct ldb_request *req)
 static int partition_rename(struct ldb_module *module, struct ldb_request *req)
 {
        /* Find backend */
-       struct ldb_module *backend = find_backend(module, req, req->op.rename.olddn);
-       struct ldb_module *backend2 = find_backend(module, req, req->op.rename.newdn);
+       struct dsdb_control_current_partition *backend, *backend2;
+       
+       struct partition_private_data *data = talloc_get_type(module->private_data, 
+                                                             struct partition_private_data);
+
+       /* Skip the lot if 'data' isn't here yet (initialistion) */
+       if (!data) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       backend = find_partition(data, req->op.rename.olddn);
+       backend2 = find_partition(data, req->op.rename.newdn);
+
+       if ((backend && !backend2) || (!backend && backend2)) {
+               return LDB_ERR_AFFECTS_MULTIPLE_DSAS;
+       }
 
-       if (backend->next != backend2->next) {
+       if (backend != backend2) {
+               ldb_asprintf_errstring(module->ldb, 
+                                      "Cannot rename from %s in %s to %s in %s: %s",
+                                      ldb_dn_get_linearized(req->op.rename.olddn),
+                                      ldb_dn_get_linearized(backend->dn),
+                                      ldb_dn_get_linearized(req->op.rename.newdn),
+                                      ldb_dn_get_linearized(backend2->dn),
+                                      ldb_strerror(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
                return LDB_ERR_AFFECTS_MULTIPLE_DSAS;
        }
 
index fa8c07fa5529dd235b334fc7787adb178a10a4eb..bfcdbd2dc1ee22c9d8ada8cd9db9c1835da072e1 100644 (file)
@@ -621,6 +621,7 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call)
                result = LDAP_OTHER;
                goto reply;
        }
+       newdn = parentdn;
 
 reply:
        modifydn_r = ldapsrv_init_reply(call, LDAP_TAG_ModifyDNResponse);
index 6dff3942a87f5f56d39f68f2d7e3d503a37c6f66..335e7d540ef0b31695231c702708bc9e050b8634 100644 (file)
@@ -857,9 +857,8 @@ static int ltdb_rename(struct ldb_module *module, struct ldb_request *req)
                goto done;
        }
 
-       tret = ltdb_add_internal(module, msg);
-       if (tret != LDB_SUCCESS) {
-               ret = LDB_ERR_OPERATIONS_ERROR;
+       ret = ltdb_add_internal(module, msg);
+       if (ret != LDB_SUCCESS) {
                goto done;
        }
 
index 72d8c9acf8785ec81ae2eae272deaaa6554e626d..a91285c3af7148775ab95871d81c90edac22813e 100755 (executable)
@@ -140,6 +140,60 @@ cn: LDAPtestUSER2
                }
        }
 
+       ok = ldb.del("cn=ldaptestuser3,cn=users," + base_dn);
+
+       ok = ldb.rename("cn=ldaptestuser2,cn=users," + base_dn, "cn=ldaptestuser3,cn=users," + base_dn);
+       if (ok.error != 0) {
+               println("Could not rename cn=ldaptestuser2,cn=users," + base_dn + " into cn=ldaptestuser3,cn=users," + base_dn + ": " + ok.errstr);
+               assert(ok.error == 0);
+       }
+
+       // ensure we cannot add it again
+       ok = ldb.add("
+dn: cn=ldaptestuser3,cn=users," + base_dn + "
+objectClass: person
+objectClass: user
+cn: LDAPtestUSER3
+");
+//LDB_ERR_ENTRY_ALREADY_EXISTS
+       if (ok.error != 68) {
+               println("expected error LDB_ERR_ENTRY_ALREADY_EXISTS, got: " + ok.errstr);
+               assert(ok.error == 68);
+       }
+
+       // rename back
+       ok = ldb.rename("cn=ldaptestuser3,cn=users," + base_dn, "cn=ldaptestuser2,cn=users," + base_dn);
+       if (ok.error != 0) {
+               println(ok.errstr);
+               assert(ok.error == 0);
+       }
+
+       // ensure we cannnot rename it twice
+       ok = ldb.rename("cn=ldaptestuser3,cn=users," + base_dn, "cn=ldaptestuser2,cn=users," + base_dn);
+//LDB_ERR_NO_SUCH_OBJECT
+       assert(ok.error == 32);
+
+       // ensure can now use that name
+       ok = ldb.add("
+dn: cn=ldaptestuser3,cn=users," + base_dn + "
+objectClass: person
+objectClass: user
+cn: LDAPtestUSER3
+");
+       
+       // ensure we now cannnot rename
+       ok = ldb.rename("cn=ldaptestuser2,cn=users," + base_dn, "cn=ldaptestuser3,cn=users," + base_dn);
+//LDB_ERR_ENTRY_ALREADY_EXISTS
+       if (ok.error != 68) {
+               println("expected error LDB_ERR_ENTRY_ALREADY_EXISTS, got: " + ok.errstr);
+               assert(ok.error == 68);
+       }
+       assert(ok.error == 68);
+       ok = ldb.rename("cn=ldaptestuser3,cn=users," + base_dn, "cn=ldaptestuser3,cn=configuration," + base_dn);
+       assert(ok.error == 71);
+
+       ok = ldb.del("cn=ldaptestuser3,cn=users," + base_dn);
+
        ok = ldb.add("
 dn: cn=ldaptestutf8user èùéìòà ,cn=users," + base_dn + "
 objectClass: user