summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Dieter Wallnöfer <mdw@samba.org>2010-06-07 20:46:59 +0200
committerMatthias Dieter Wallnöfer <mdw@samba.org>2010-06-07 20:54:10 +0200
commit1949864417f3d10fb8996df7db259649eb777271 (patch)
tree890ef8d0d909a29f68a151207e5daa47a03c93a4
parenta75d271373dbbff973544865c2c9715510d67669 (diff)
downloadsamba-1949864417f3d10fb8996df7db259649eb777271.tar.gz
samba-1949864417f3d10fb8996df7db259649eb777271.tar.bz2
samba-1949864417f3d10fb8996df7db259649eb777271.zip
s4:objectclass_attrs LDB module - move the single-valued attribute check into this module
It seems to me more consistent (and also to keep the same behaviour on all backends). Also the DRS hack should therefore not be needed anymore since the "repl_meta_data" module launches requests behind "objectclass_attrs".
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectclass_attrs.c14
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c44
2 files changed, 13 insertions, 45 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
index 042d26b981..5b76a0b946 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
@@ -180,7 +180,7 @@ static int attr_handler2(struct oc_context *ac)
}
/* Check if all specified attributes are valid in the given
- * objectclasses. */
+ * objectclasses and if they meet additional schema restrictions. */
msg = ac->search_res->message;
for (i = 0; i < msg->num_elements; i++) {
attr = dsdb_attribute_by_lDAPDisplayName(ac->schema,
@@ -189,6 +189,18 @@ static int attr_handler2(struct oc_context *ac)
return LDB_ERR_OPERATIONS_ERROR;
}
+ /* Check if they're single-valued if this is requested */
+ if ((msg->elements[i].num_values > 1) && (attr->isSingleValued)) {
+ ldb_asprintf_errstring(ldb, "objectclass_attrs: attribute '%s' on entry '%s' is single-valued!",
+ msg->elements[i].name,
+ ldb_dn_get_linearized(msg->dn));
+ if (ac->req->operation == LDB_ADD) {
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ } else {
+ return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+ }
+ }
+
/* We can use "str_list_check" with "strcmp" here since the
* attribute informations from the schema are always equal
* up-down-cased. */
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index c80ecd0b43..c421dda791 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -294,20 +294,12 @@ static int ltdb_add_internal(struct ldb_module *module,
for (i=0;i<msg->num_elements;i++) {
struct ldb_message_element *el = &msg->elements[i];
- const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
if (el->num_values == 0) {
ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)",
el->name, ldb_dn_get_linearized(msg->dn));
return LDB_ERR_CONSTRAINT_VIOLATION;
}
- if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
- if (el->num_values > 1) {
- 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;
- }
- }
}
ret = ltdb_store(module, msg, TDB_INSERT);
@@ -649,7 +641,6 @@ int ltdb_modify_internal(struct ldb_module *module,
for (i=0; i<msg->num_elements; i++) {
struct ldb_message_element *el = &msg->elements[i], *el2;
struct ldb_val *vals;
- const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
const char *dn;
switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
@@ -685,15 +676,6 @@ int ltdb_modify_internal(struct ldb_module *module,
}
}
- if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
- if (el->num_values > 1) {
- 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;
- goto done;
- }
- }
-
/* Checks if element already exists */
idx = find_element(msg2, el->name);
if (idx == -1) {
@@ -706,15 +688,6 @@ int ltdb_modify_internal(struct ldb_module *module,
goto done;
}
} else {
- /* We cannot add another value on a existing one
- if the attribute is single-valued */
- if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
- 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;
- goto done;
- }
-
el2 = &(msg2->elements[idx]);
/* Check that values don't exist yet on multi-
@@ -772,23 +745,6 @@ int ltdb_modify_internal(struct ldb_module *module,
case LDB_FLAG_MOD_REPLACE:
- if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
- /* 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;
- goto done;
- }
- }
-
/* TODO: This is O(n^2) - replace with more efficient check */
for (j=0; j<el->num_values; j++) {
if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {