summaryrefslogtreecommitdiff
path: root/source4/lib/ldb
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-09-21 19:26:59 -0700
committerAndrew Bartlett <abartlet@samba.org>2009-09-21 20:50:26 -0700
commit399c7160d56866725d8931a2f816de3b6a995704 (patch)
tree8eaa3866ac9eea306522c8b23ff6d80e0ba970a3 /source4/lib/ldb
parent9e85192e6415fbaacf394330f6e61759190485ad (diff)
downloadsamba-399c7160d56866725d8931a2f816de3b6a995704.tar.gz
samba-399c7160d56866725d8931a2f816de3b6a995704.tar.bz2
samba-399c7160d56866725d8931a2f816de3b6a995704.zip
s4:ldb Add 'single-value' support to LDB.
This is currently only triggered via Samba4's schema code.
Diffstat (limited to 'source4/lib/ldb')
-rw-r--r--source4/lib/ldb/include/ldb.h5
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c49
2 files changed, 52 insertions, 2 deletions
diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h
index 0378697f4b..fa531b26f2 100644
--- a/source4/lib/ldb/include/ldb.h
+++ b/source4/lib/ldb/include/ldb.h
@@ -392,6 +392,11 @@ const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_c
*/
#define LDB_ATTR_FLAG_UNIQUE_INDEX (1<<3)
+/*
+ when this is set, attempts to create two attribute values for this attribute on a single DN will return LDB_ERR_CONSTRAINT_VIOLATION
+ */
+#define LDB_ATTR_FLAG_SINGLE_VALUE (1<<4)
+
/**
LDAP attribute syntax for a DN
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index d4f7b452cb..e569a5a2a8 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -254,7 +254,7 @@ static int ltdb_add_internal(struct ldb_module *module,
const struct ldb_message *msg)
{
struct ldb_context *ldb = ldb_module_get_ctx(module);
- int ret;
+ int ret, i;
ret = ltdb_check_special_dn(module, msg);
if (ret != LDB_SUCCESS) {
@@ -265,6 +265,24 @@ static int ltdb_add_internal(struct ldb_module *module,
return LDB_ERR_OPERATIONS_ERROR;
}
+ 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 speicified, but with 0 values (illigal)",
+ 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 speicified more than once",
+ el->name, ldb_dn_get_linearized(msg->dn));
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+ }
+ }
+
ret = ltdb_store(module, msg, TDB_INSERT);
if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
@@ -602,15 +620,28 @@ int ltdb_modify_internal(struct ldb_module *module,
struct ldb_message_element *el2;
struct ldb_val *vals;
const char *dn;
-
+ const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name);
switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) {
case LDB_FLAG_MOD_ADD:
+
/* add this element to the message. fail if it
already exists */
idx = find_element(msg2, el->name);
+ if (el->num_values == 0) {
+ ldb_asprintf_errstring(ldb, "attribute %s on %s speicified, but with 0 values (illigal)",
+ el->name, ldb_dn_get_linearized(msg->dn));
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
if (idx == -1) {
+ if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
+ if (el->num_values > 1) {
+ ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once",
+ el->name, ldb_dn_get_linearized(msg->dn));
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+ }
if (msg_add_element(ldb, msg2, el) != 0) {
ret = LDB_ERR_OTHER;
goto failed;
@@ -618,6 +649,13 @@ int ltdb_modify_internal(struct ldb_module *module,
continue;
}
+ /* If this is an add, then if it already
+ * exists in the object, then we violoate the
+ * single-value rule */
+ if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+
el2 = &msg2->elements[idx];
/* An attribute with this name already exists,
@@ -657,6 +695,13 @@ int ltdb_modify_internal(struct ldb_module *module,
break;
case LDB_FLAG_MOD_REPLACE:
+ if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) {
+ if (el->num_values > 1) {
+ ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once",
+ el->name, ldb_dn_get_linearized(msg->dn));
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+ }
/* replace all elements of this attribute name with the elements
listed. The attribute not existing is not an error */
msg_delete_attribute(module, ldb, msg2, el->name);