lib/ldb: switch ldb_tdb to schema-based attribute comparison
authorAndrew Bartlett <abartlet@samba.org>
Fri, 11 May 2012 08:00:29 +0000 (10:00 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 29 Aug 2013 10:28:33 +0000 (12:28 +0200)
Based on an earlier patch by Matthias Dieter Wallnöfer <mdw@samba.org>

This is necessary to perform correct schema enforcement, becuase we
must enforce uniquiness based on the schema matching rules.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=7485
Bug: https://bugzilla.samba.org/show_bug.cgi?id=8929

Andrew Bartlett

Small fix by Matthias Dieter Wallnöfer <mdw@samba.org>

Reviewed-by: Stefan Metzmacher <metze@samba.org>
lib/ldb/ldb_tdb/ldb_tdb.c

index e22536e271988be88f8bc286b16bcc8a9933a2ef..753d2b4c1dfd22d89e8d1981bd0bb5dd579bc322 100644 (file)
@@ -347,7 +347,13 @@ static int ltdb_add_internal(struct ldb_module *module,
 
                /* 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]) {
+                       struct ldb_val *found_val;
+                       ret = ldb_msg_find_val_schema(ldb, a, el,
+                                                     &el->values[j], &found_val);
+                       if (ret != LDB_SUCCESS) {
+                               return ret;
+                       }
+                       if (found_val != &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));
@@ -614,13 +620,9 @@ static int msg_delete_element(struct ldb_module *module,
 
        for (i=0;i<el->num_values;i++) {
                bool matched;
-               if (a->syntax->operator_fn) {
-                       ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a,
-                                                    &el->values[i], val, &matched);
-                       if (ret != LDB_SUCCESS) return ret;
-               } else {
-                       matched = (a->syntax->comparison_fn(ldb, ldb,
-                                                           &el->values[i], val) == 0);
+               ret = ldb_val_equal_schema(ldb, a, &el->values[i], val, &matched);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
                }
                if (matched) {
                        if (el->num_values == 1) {
@@ -781,7 +783,13 @@ int ltdb_modify_internal(struct ldb_module *module,
                                   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) {
+                                       struct ldb_val *matched_val;
+                                       ret = ldb_msg_find_val_schema(ldb, a, el2,
+                                                                     &el->values[j], &matched_val);
+                                       if (ret != LDB_SUCCESS) {
+                                               return ret;
+                                       }
+                                       if (matched_val != NULL) {
                                                if (control_permissive) {
                                                        /* remove this one as if it was never added */
                                                        el->num_values--;
@@ -799,7 +807,12 @@ int ltdb_modify_internal(struct ldb_module *module,
                                                ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
                                                goto done;
                                        }
-                                       if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) {
+                                       ret = ldb_msg_find_val_schema(ldb, a, el,
+                                                                     &el->values[j], &matched_val);
+                                       if (ret != LDB_SUCCESS) {
+                                               return ret;
+                                       }
+                                       if (matched_val != &el->values[j]) {
                                                ldb_asprintf_errstring(ldb,
                                                                       "attribute '%s': value #%u on '%s' provided more than once",
                                                                       el->name, j, ldb_dn_get_linearized(msg2->dn));
@@ -846,7 +859,13 @@ int ltdb_modify_internal(struct ldb_module *module,
 
                        /* 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]) {
+                               struct ldb_val *matched_val;
+                               ret = ldb_msg_find_val_schema(ldb, a, el,
+                                                             &el->values[j], &matched_val);
+                               if (ret != LDB_SUCCESS) {
+                                       return ret;
+                               }
+                               if (matched_val != &el->values[j]) {
                                        ldb_asprintf_errstring(ldb,
                                                               "attribute '%s': value #%u on '%s' provided more than once",
                                                               el->name, j, ldb_dn_get_linearized(msg2->dn));