summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_index.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c
index c4243e9b40..6c21ae2986 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_index.c
@@ -96,6 +96,7 @@ static int ldb_msg_find_idx(const struct ldb_message *msg, const char *attr,
return -1;
}
+
/*
return a list of dn's that might match a simple indexed search or
*/
@@ -169,6 +170,68 @@ static int ltdb_index_dn_simple(struct ldb_context *ldb,
}
/*
+ return a list of dn's that might match a simple indexed search on
+ the special objectclass attribute
+ */
+static int ltdb_index_dn_objectclass(struct ldb_context *ldb,
+ struct ldb_parse_tree *tree,
+ const struct ldb_message *index_list,
+ struct dn_list *list)
+{
+ struct ltdb_private *ltdb = ldb->private_data;
+ int i;
+ int ret;
+ const char *target = tree->u.simple.value.data;
+ static int list_union(struct dn_list *, const struct dn_list *);
+
+ list->count = 0;
+ list->dn = NULL;
+
+ ret = ltdb_index_dn_simple(ldb, tree, index_list, list);
+
+ 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, target) == 0) {
+ int j;
+ for (j=0;j<el->num_values;j++) {
+ struct ldb_parse_tree tree2;
+ struct dn_list list2;
+ tree2.operation = LDB_OP_SIMPLE;
+ tree2.u.simple.attr = LTDB_OBJECTCLASS;
+ tree2.u.simple.value = el->values[j];
+ if (ltdb_index_dn_objectclass(ldb, &tree2,
+ index_list, &list2) == 1) {
+ if (list->count == 0) {
+ *list = list2;
+ ret = 1;
+ } else {
+ list_union(list, &list2);
+ dn_list_free(&list2);
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*
+ return a list of dn's that might match a leaf indexed search
+ */
+static int ltdb_index_dn_leaf(struct ldb_context *ldb,
+ struct ldb_parse_tree *tree,
+ const struct ldb_message *index_list,
+ struct dn_list *list)
+{
+ if (ldb_attr_cmp(tree->u.simple.attr, LTDB_OBJECTCLASS) == 0) {
+ return ltdb_index_dn_objectclass(ldb, tree, index_list, list);
+ }
+ return ltdb_index_dn_simple(ldb, tree, index_list, list);
+}
+
+
+/*
list intersection
list = list & list2
relies on the lists being sorted
@@ -393,7 +456,7 @@ static int ltdb_index_dn(struct ldb_context *ldb,
switch (tree->operation) {
case LDB_OP_SIMPLE:
- ret = ltdb_index_dn_simple(ldb, tree, index_list, list);
+ ret = ltdb_index_dn_leaf(ldb, tree, index_list, list);
break;
case LDB_OP_AND: