ldb-tdb: Introduce a flag on ltdb_add_internal to indicate whether unique value test...
authorMatthieu Patou <mat@matws.net>
Tue, 12 Jul 2011 15:22:35 +0000 (19:22 +0400)
committerMatthieu Patou <mat@samba.org>
Wed, 13 Jul 2011 00:29:20 +0000 (02:29 +0200)
The function ltdb_add_internal is called either from ltdb_add or
ltdb_rename. In case of add we enforce the unique test (unless it has
been relaxed by a upper module through the
LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK flag), but for rename as it
is translated by a delete + a add we relax the test as we can have one
or more attribute which are supposed to be single valued but that are
not (ie. when we have a couple of deleted value on a single valued
attribute), we have already done the tests on insert so make the
assumption that the values are OK.

Without this patch deleting a subnet that has been affected to more than
one site fails as the delete is in fact a rename to GUID\0DEL ... with
an attribute siteObject that has 1 active link value and 1 inactive link
value

Autobuild-User: Matthieu Patou <mat@samba.org>
Autobuild-Date: Wed Jul 13 02:29:20 CEST 2011 on sn-devel-104

lib/ldb/ldb_tdb/ldb_tdb.c

index 0d4be49123501d4de36d0a016130595d6aafc0a3..d111e01118f27b03c6a846d72c4a94be7f032162 100644 (file)
@@ -311,7 +311,8 @@ static bool ldb_tdb_single_valued(const struct ldb_schema_attribute *a,
 }
 
 static int ltdb_add_internal(struct ldb_module *module,
-                            const struct ldb_message *msg)
+                            const struct ldb_message *msg,
+                            bool check_single_value)
 {
        struct ldb_context *ldb = ldb_module_get_ctx(module);
        int ret = LDB_SUCCESS;
@@ -326,7 +327,9 @@ static int ltdb_add_internal(struct ldb_module *module,
                                               el->name, ldb_dn_get_linearized(msg->dn));
                        return LDB_ERR_CONSTRAINT_VIOLATION;
                }
-               if (el->num_values > 1 && ldb_tdb_single_valued(a, el)) {
+               if (check_single_value &&
+                               el->num_values > 1 &&
+                               ldb_tdb_single_valued(a, el)) {
                        ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
                                               el->name, ldb_dn_get_linearized(msg->dn));
                        return LDB_ERR_CONSTRAINT_VIOLATION;
@@ -373,7 +376,7 @@ static int ltdb_add(struct ltdb_context *ctx)
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
-       ret = ltdb_add_internal(module, req->op.add.message);
+       ret = ltdb_add_internal(module, req->op.add.message, true);
 
        return ret;
 }
@@ -998,7 +1001,11 @@ static int ltdb_rename(struct ltdb_context *ctx)
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
-       ret = ltdb_add_internal(module, msg);
+       /* We don't check single value as we can have more than 1 with
+        * deleted attributes. We could go through all elements but that's
+        * maybe not the most efficient way
+        */
+       ret = ltdb_add_internal(module, msg, false);
 
        return ret;
 }