s4-ldb: added an optional operator_fn in the schema syntax
authorAndrew Tridgell <tridge@samba.org>
Wed, 13 Oct 2010 09:02:18 +0000 (20:02 +1100)
committerAndrew Tridgell <tridge@samba.org>
Wed, 13 Oct 2010 11:00:04 +0000 (11:00 +0000)
this function takes the operator being invoked, which will allow
schema functions to provide more fine grained control over
comparisons.

The key bug this was introduced to fix is the incorrect handling of
the LDB_OP_PRESENT test for deleted linked attributes. The backends
are unaware of the deleted state of these links, so they cannot do a
LDB_OP_PRESENT test on their own.

Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>

source4/lib/ldb/include/ldb.h
source4/lib/ldb/ldb_tdb/ldb_tdb.c
source4/lib/ldb/modules/rdn_name.c

index d29aed491abd76d50a5f4556146934cc03ba7bc8..c53cb7a6bfda8cd78d775ab6f11b3317d4a40a80 100644 (file)
@@ -353,6 +353,10 @@ char *ldb_binary_encode_string(TALLOC_CTX *mem_ctx, const char *string);
 */
 typedef int (*ldb_attr_handler_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, struct ldb_val *);
 typedef int (*ldb_attr_comparison_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, const struct ldb_val *);
+struct ldb_schema_attribute;
+typedef int (*ldb_attr_operator_t)(struct ldb_context *, enum ldb_parse_op operation,
+                                  const struct ldb_schema_attribute *a,
+                                  const struct ldb_val *, const struct ldb_val *, bool *matched);
 
 /*
   attribute handler structure
@@ -370,6 +374,7 @@ struct ldb_schema_syntax {
        ldb_attr_handler_t ldif_write_fn;
        ldb_attr_handler_t canonicalise_fn;
        ldb_attr_comparison_t comparison_fn;
+       ldb_attr_operator_t operator_fn;
 };
 
 struct ldb_schema_attribute {
index 7f8342b06777365f5c55a836c00c04d34cccbbb3..f12bc58f65781923b1d5cf1aab95d0e891007390 100644 (file)
@@ -553,8 +553,16 @@ static int msg_delete_element(struct ldb_module *module,
        a = ldb_schema_attribute_by_name(ldb, el->name);
 
        for (i=0;i<el->num_values;i++) {
-               if (a->syntax->comparison_fn(ldb, ldb,
-                                            &el->values[i], val) == 0) {
+               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);
+               }
+               if (matched) {
                        if (el->num_values == 1) {
                                return msg_delete_attribute(module, ldb, msg, name);
                        }
index 5dc122f254a8e8ac9d9a64fb6ed79e1c7c0ab72f..a0867c0f51d33501fbb335d908ab481453f7231e 100644 (file)
@@ -147,9 +147,16 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req)
                }
                /* normalise attribute value */
                for (i = 0; i < attribute->num_values; i++) {
-                       ret = a->syntax->comparison_fn(ldb, msg,
-                                       &rdn_val, &attribute->values[i]);
-                       if (ret == 0) {
+                       bool matched;
+                       if (a->syntax->operator_fn) {
+                               ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a,
+                                                            &rdn_val, &attribute->values[i], &matched);
+                               if (ret != LDB_SUCCESS) return ret;
+                       } else {
+                               matched = (a->syntax->comparison_fn(ldb, msg,
+                                                                   &rdn_val, &attribute->values[i]) == 0);
+                       }
+                       if (matched) {
                                /* overwrite so it matches in case */
                                attribute->values[i] = rdn_val;
                                break;