LDB:ldb_tdb.c - deny multi-valued attributes manipulation with doublets
authorMatthias Dieter Wallnöfer <mdw@samba.org>
Thu, 10 May 2012 14:18:37 +0000 (16:18 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 21 Aug 2012 23:31:57 +0000 (01:31 +0200)
This refers to LDB add operations as well, we have only to be careful on
"@ATTRIBUTES" entries.

E.g.

dn: cn=testperson,cn=users,dc=...,dc=...
objectClass: person
url: www.example.com
url: www.example.com

should not work.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
lib/ldb/ldb_tdb/ldb_tdb.c

index cc1586dc5ca59d547bab9622c3bb0f379318c449..3c181509c37c7c4f0a4bc6054fa77805136eeb9d 100644 (file)
@@ -318,7 +318,7 @@ static int ltdb_add_internal(struct ldb_module *module,
 {
        struct ldb_context *ldb = ldb_module_get_ctx(module);
        int ret = LDB_SUCCESS;
-       unsigned int i;
+       unsigned int i, j;
 
        for (i=0;i<msg->num_elements;i++) {
                struct ldb_message_element *el = &msg->elements[i];
@@ -336,6 +336,22 @@ static int ltdb_add_internal(struct ldb_module *module,
                                               el->name, ldb_dn_get_linearized(msg->dn));
                        return LDB_ERR_CONSTRAINT_VIOLATION;
                }
+
+               /* Do not check "@ATTRIBUTES" for duplicated values */
+               if (ldb_dn_is_special(msg->dn) &&
+                   ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) {
+                       continue;
+               }
+
+               /* 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]) {
+                               ldb_asprintf_errstring(ldb,
+                                                      "attribute '%s': value #%u on '%s' provided more than once",
+                                                      el->name, j, ldb_dn_get_linearized(msg->dn));
+                               return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
+                       }
+               }
        }
 
        ret = ltdb_store(module, msg, TDB_INSERT);
@@ -761,6 +777,7 @@ int ltdb_modify_internal(struct ldb_module *module,
 
                                /* Check that values don't exist yet on multi-
                                   valued attributes or aren't provided twice */
+                               /* TODO: This is O(n^2) - replace with more efficient check */
                                for (j = 0; j < el->num_values; j++) {
                                        if (ldb_msg_find_val(el2, &el->values[j]) != NULL) {
                                                if (control_permissive) {