fixed ldb rename now that we have unique indexes
authorAndrew Tridgell <tridge@samba.org>
Thu, 4 Jun 2009 03:52:40 +0000 (13:52 +1000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 4 Jun 2009 04:10:11 +0000 (14:10 +1000)
With unique indexes, any rename of a record that has an attribute that
is uniquely indexed needs to be done as a delete followed by an add,
otherwse you'll get an error that the attribute value already exists.

source4/lib/ldb/ldb_tdb/ldb_tdb.c

index 0f84b67afaa673c9dcd42400e32da0ddefeebbd1..4a452761b8332de4431c46da1cf01ece145a8f02 100644 (file)
@@ -805,37 +805,18 @@ static int ltdb_rename(struct ltdb_context *ctx)
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
-       if (ldb_dn_compare(req->op.rename.olddn, req->op.rename.newdn) == 0) {
-               /* The rename operation is apparently only changing case -
-                  the DNs are the same.  Delete the old DN before adding
-                  the new one to avoid a TDB_ERR_EXISTS error.
-
-                  The only drawback to this is that if the delete
-                  succeeds but the add fails, we rely on the
-                  transaction to roll this all back. */
-               tret = ltdb_delete_internal(module, req->op.rename.olddn);
-               if (tret != LDB_SUCCESS) {
-                       return tret;
-               }
-
-               tret = ltdb_add_internal(module, msg);
-               if (tret != LDB_SUCCESS) {
-                       return tret;
-               }
-       } else {
-               /* The rename operation is changing DNs.  Try to add the new
-                  DN first to avoid clobbering another DN not related to
-                  this rename operation. */
-               tret = ltdb_add_internal(module, msg);
-               if (tret != LDB_SUCCESS) {
-                       return tret;
-               }
+       /* Always delete first then add, to avoid conflicts with
+        * unique indexes. We rely on the transaction to make this
+        * atomic
+        */
+       tret = ltdb_delete_internal(module, req->op.rename.olddn);
+       if (tret != LDB_SUCCESS) {
+               return tret;
+       }
 
-               tret = ltdb_delete_internal(module, req->op.rename.olddn);
-               if (tret != LDB_SUCCESS) {
-                       ltdb_delete_internal(module, req->op.rename.newdn);
-                       return LDB_ERR_OPERATIONS_ERROR;
-               }
+       tret = ltdb_add_internal(module, msg);
+       if (tret != LDB_SUCCESS) {
+               return tret;
        }
 
        return LDB_SUCCESS;