summaryrefslogtreecommitdiff
path: root/source4/lib/ldb
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-12-19 20:55:11 +1100
committerAndrew Tridgell <tridge@samba.org>2010-01-02 08:16:51 +1100
commitb34db0840de701b4d42918a8da952959a6955453 (patch)
treefc885c568e7c02b701e15f8e03ca52799614ea23 /source4/lib/ldb
parent26ec526d02d78fb327fb855ce5ff037cb74af303 (diff)
downloadsamba-b34db0840de701b4d42918a8da952959a6955453.tar.gz
samba-b34db0840de701b4d42918a8da952959a6955453.tar.bz2
samba-b34db0840de701b4d42918a8da952959a6955453.zip
s4-ldb: use the RELAX control to disable single value checking on replace
When using w2k3 linked attributes we are allowed to have multiple values on a single valued attribute. This happens when the other values are deleted. Setting the RELAX control tell the ldb-tdb backend to not check for this on replace, which means the caller has to check for single valued violations.
Diffstat (limited to 'source4/lib/ldb')
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_cache.c2
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c17
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.h2
3 files changed, 16 insertions, 5 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_cache.c b/source4/lib/ldb/ldb_tdb/ldb_cache.c
index cd2249d4a2..aa19f75e9c 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_cache.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_cache.c
@@ -463,7 +463,7 @@ int ltdb_increase_sequence_number(struct ldb_module *module)
val_time.data = (uint8_t *)s;
val_time.length = strlen(s);
- ret = ltdb_modify_internal(module, msg);
+ ret = ltdb_modify_internal(module, msg, NULL);
talloc_free(msg);
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index 227a202a6f..a146b96b20 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -592,9 +592,12 @@ static int msg_delete_element(struct ldb_module *module,
yuck - this is O(n^2). Luckily n is usually small so we probably
get away with it, but if we ever have really large attribute lists
then we'll need to look at this again
+
+ 'req' is optional, and is used to specify controls if supplied
*/
int ltdb_modify_internal(struct ldb_module *module,
- const struct ldb_message *msg)
+ const struct ldb_message *msg,
+ struct ldb_request *req)
{
struct ldb_context *ldb = ldb_module_get_ctx(module);
void *data = ldb_module_get_private(module);
@@ -731,7 +734,15 @@ int ltdb_modify_internal(struct ldb_module *module,
case LDB_FLAG_MOD_REPLACE:
if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
- if (el->num_values > 1) {
+ /* the RELAX control overrides this
+ check for replace. This is needed as
+ DRS replication can produce multiple
+ values here for a single valued
+ attribute when the values are deleted
+ links
+ */
+ if (el->num_values > 1 &&
+ (!req || !ldb_request_get_control(req, LDB_CONTROL_RELAX_OID))) {
ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once",
el->name, ldb_dn_get_linearized(msg2->dn));
ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
@@ -852,7 +863,7 @@ static int ltdb_modify(struct ltdb_context *ctx)
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ltdb_modify_internal(module, req->op.mod.message);
+ ret = ltdb_modify_internal(module, req->op.mod.message, req);
return ret;
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
index bb4cb3f8b5..70b99c340c 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -130,7 +130,7 @@ int ltdb_lock_read(struct ldb_module *module);
int ltdb_unlock_read(struct ldb_module *module);
struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn);
int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs);
-int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg);
+int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg, struct ldb_request *req);
int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn);
int ltdb_err_map(enum TDB_ERROR tdb_code);