diff options
Diffstat (limited to 'source4/lib/ldb/ldb_tdb/ldb_match.c')
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_match.c | 426 |
1 files changed, 0 insertions, 426 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_match.c b/source4/lib/ldb/ldb_tdb/ldb_match.c deleted file mode 100644 index b5b023bc09..0000000000 --- a/source4/lib/ldb/ldb_tdb/ldb_match.c +++ /dev/null @@ -1,426 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb expression matching - * - * Description: ldb expression matching for tdb backend - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/ldb.h" -#include "ldb/include/ldb_private.h" -#include "ldb/ldb_tdb/ldb_tdb.h" -#include <fnmatch.h> - -/* - see if two ldb_val structures contain the same data as integers - return 1 for a match, 0 for a mis-match -*/ -static int ltdb_val_equal_integer(const struct ldb_val *v1, const struct ldb_val *v2) -{ - uint64_t i1, i2; - - i1 = strtoull(v1->data, NULL, 0); - i2 = strtoull(v2->data, NULL, 0); - - return i1 == i2; -} - -/* - see if two ldb_val structures contain the same data as case insensitive strings - return 1 for a match, 0 for a mis-match -*/ -static int ltdb_val_equal_case_insensitive(const struct ldb_val *v1, - const struct ldb_val *v2) -{ - if (v1->length != v2->length) { - return 0; - } - if (strncasecmp(v1->data, v2->data, v1->length) == 0) { - return 1; - } - return 0; -} - -/* - see if two ldb_val structures contain the same data with wildcards - and case insensitive - return 1 for a match, 0 for a mis-match -*/ -static int ltdb_val_equal_wildcard_ci(struct ldb_module *module, - const struct ldb_val *v1, - const struct ldb_val *v2) -{ - struct ldb_context *ldb = module->ldb; - char *s1, *s2; - int ret; - - if (!v1->data || !v2->data) { - return v1->data == v2->data; - } - - s1 = ldb_casefold(ldb, v1->data); - if (!s1) { - return -1; - } - - s2 = ldb_casefold(ldb, v2->data); - if (!s2) { - talloc_free(s1); - return -1; - } - - ret = fnmatch(s2, s1, 0); - - talloc_free(s1); - talloc_free(s2); - - if (ret == 0) { - return 1; - } - - return 0; -} - -/* - see if two ldb_val structures contain the same data with wildcards - return 1 for a match, 0 for a mis-match -*/ -static int ltdb_val_equal_wildcard(struct ldb_module *module, - const struct ldb_val *v1, - const struct ldb_val *v2, - int flags) -{ - if (flags & LTDB_FLAG_CASE_INSENSITIVE) { - return ltdb_val_equal_wildcard_ci(module, v1, v2); - } - if (!v1->data || !v2->data) { - return v1->data == v2->data; - } - if (fnmatch(v2->data, v1->data, 0) == 0) { - return 1; - } - return 0; -} - - -/* - see if two objectclasses are considered equal. This handles - the subclass attributes - - v1 contains the in-database value, v2 contains the value - that the user gave - - return 1 for a match, 0 for a mis-match -*/ -static int ltdb_val_equal_objectclass(struct ldb_module *module, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - struct ltdb_private *ltdb = module->private_data; - unsigned int i; - - if (ltdb_val_equal_case_insensitive(v1, v2) == 1) { - return 1; - } - - for (i=0;i<ltdb->cache->subclasses->num_elements;i++) { - struct ldb_message_element *el = <db->cache->subclasses->elements[i]; - if (ldb_attr_cmp(el->name, v2->data) == 0) { - unsigned int j; - for (j=0;j<el->num_values;j++) { - if (ltdb_val_equal_objectclass(module, v1, &el->values[j])) { - return 1; - } - } - } - } - - return 0; -} - - -/* - see if two ldb_val structures contain the same data - - v1 contains the in-database value, v2 contains the value - that the user gave - - return 1 for a match, 0 for a mis-match -*/ -int ltdb_val_equal(struct ldb_module *module, - const char *attr_name, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - int flags = ltdb_attribute_flags(module, attr_name); - - if (flags & LTDB_FLAG_OBJECTCLASS) { - return ltdb_val_equal_objectclass(module, v1, v2); - } - - if (flags & LTDB_FLAG_INTEGER) { - return ltdb_val_equal_integer(v1, v2); - } - - if (flags & LTDB_FLAG_WILDCARD) { - return ltdb_val_equal_wildcard(module, v1, v2, flags); - } - - if (flags & LTDB_FLAG_CASE_INSENSITIVE) { - return ltdb_val_equal_case_insensitive(v1, v2); - } - - if (v1->length != v2->length) return 0; - - if (v1->length == 0) return 1; - - if (memcmp(v1->data, v2->data, v1->length) == 0) { - return 1; - } - - return 0; -} - -/* - check if the scope matches in a search result -*/ -static int scope_match(const char *dn, const char *base, enum ldb_scope scope) -{ - size_t dn_len, base_len; - - if (base == NULL) { - return 1; - } - - base_len = strlen(base); - dn_len = strlen(dn); - - if (scope != LDB_SCOPE_ONELEVEL && ldb_dn_cmp(dn, base) == 0) { - return 1; - } - - if (base_len+1 >= dn_len) { - return 0; - } - - switch (scope) { - case LDB_SCOPE_BASE: - break; - - case LDB_SCOPE_ONELEVEL: - if (ldb_dn_cmp(dn + (dn_len - base_len), base) == 0 && - dn[dn_len - base_len - 1] == ',' && - strchr(dn, ',') == &dn[dn_len - base_len - 1]) { - return 1; - } - break; - - case LDB_SCOPE_SUBTREE: - default: - if (ldb_dn_cmp(dn + (dn_len - base_len), base) == 0 && - dn[dn_len - base_len - 1] == ',') { - return 1; - } - break; - } - - return 0; -} - - -/* - match a leaf node -*/ -static int match_leaf(struct ldb_module *module, - struct ldb_message *msg, - struct ldb_parse_tree *tree, - const char *base, - enum ldb_scope scope) -{ - unsigned int i; - struct ldb_message_element *el; - - if (!scope_match(msg->dn, base, scope)) { - return 0; - } - - if (ldb_attr_cmp(tree->u.simple.attr, "dn") == 0) { - if (strcmp(tree->u.simple.value.data, "*") == 0) { - return 1; - } - return ldb_dn_cmp(msg->dn, tree->u.simple.value.data) == 0; - } - - el = ldb_msg_find_element(msg, tree->u.simple.attr); - if (el == NULL) { - return 0; - } - - if (strcmp(tree->u.simple.value.data, "*") == 0) { - return 1; - } - - for (i=0;i<el->num_values;i++) { - if (ltdb_val_equal(module, el->name, &el->values[i], - &tree->u.simple.value)) { - return 1; - } - } - - return 0; -} - - -/* - bitwise-and comparator -*/ -static int comparator_and(struct ldb_val *v1, struct ldb_val *v2) -{ - uint64_t i1, i2; - i1 = strtoull(v1->data, NULL, 0); - i2 = strtoull(v2->data, NULL, 0); - return ((i1 & i2) == i2); -} - -/* - bitwise-or comparator -*/ -static int comparator_or(struct ldb_val *v1, struct ldb_val *v2) -{ - uint64_t i1, i2; - i1 = strtoull(v1->data, NULL, 0); - i2 = strtoull(v2->data, NULL, 0); - return ((i1 & i2) != 0); -} - - -/* - extended match, handles things like bitops -*/ -static int ltdb_extended_match(struct ldb_module *module, - struct ldb_message *msg, - struct ldb_parse_tree *tree, - const char *base, - enum ldb_scope scope) -{ - int i; - const struct { - const char *oid; - int (*comparator)(struct ldb_val *, struct ldb_val *); - } rules[] = { - { LDB_OID_COMPARATOR_AND, comparator_and}, - { LDB_OID_COMPARATOR_OR, comparator_or} - }; - int (*comp)(struct ldb_val *, struct ldb_val *) = NULL; - struct ldb_message_element *el; - - if (tree->u.extended.dnAttributes) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb: dnAttributes extended match not supported yet"); - return -1; - } - if (tree->u.extended.rule_id == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb: no-rule extended matches not supported yet"); - return -1; - } - if (tree->u.extended.attr == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb: no-attribute extended matches not supported yet"); - return -1; - } - - for (i=0;i<ARRAY_SIZE(rules);i++) { - if (strcmp(rules[i].oid, tree->u.extended.rule_id) == 0) { - comp = rules[i].comparator; - break; - } - } - if (comp == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s\n", - tree->u.extended.rule_id); - return -1; - } - - /* find the message element */ - el = ldb_msg_find_element(msg, tree->u.extended.attr); - if (el == NULL) { - return 0; - } - - for (i=0;i<el->num_values;i++) { - int ret = comp(&el->values[i], &tree->u.extended.value); - if (ret == -1 || ret == 1) return ret; - } - - return 0; -} - -/* - return 0 if the given parse tree matches the given message. Assumes - the message is in sorted order - - return 1 if it matches, and 0 if it doesn't match - - this is a recursive function, and does short-circuit evaluation - */ -int ltdb_message_match(struct ldb_module *module, - struct ldb_message *msg, - struct ldb_parse_tree *tree, - const char *base, - enum ldb_scope scope) -{ - unsigned int i; - int v; - - switch (tree->operation) { - case LDB_OP_SIMPLE: - break; - - case LDB_OP_EXTENDED: - return ltdb_extended_match(module, msg, tree, base, scope); - - case LDB_OP_NOT: - return ! ltdb_message_match(module, msg, tree->u.not.child, base, scope); - - case LDB_OP_AND: - for (i=0;i<tree->u.list.num_elements;i++) { - v = ltdb_message_match(module, msg, tree->u.list.elements[i], - base, scope); - if (!v) return 0; - } - return 1; - - case LDB_OP_OR: - for (i=0;i<tree->u.list.num_elements;i++) { - v = ltdb_message_match(module, msg, tree->u.list.elements[i], - base, scope); - if (v) return 1; - } - return 0; - } - - return match_leaf(module, msg, tree, base, scope); -} |