summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/ldb_tdb/ldb_match.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/ldb/ldb_tdb/ldb_match.c')
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_match.c426
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 = &ltdb->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);
-}