r17542: In using ldb_map, I ran across some very odd behaviours when we search
authorAndrew Bartlett <abartlet@samba.org>
Mon, 14 Aug 2006 23:25:04 +0000 (23:25 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:15:35 +0000 (14:15 -0500)
for objectClass=xyz.  The code has been warning at me 'no
covert_operator set', and indeed this is the case.  (It then proceeds to
strip this as a search expression)

In this commit, I have implemented a convert_operator for objectClass,
by pretending it is a simple MAP_CONVERT operator for the search
requests.

I also have changed the logic for when we should bail out.  I can only
see reason to bail out on the search if we have both local and remote
trees.  How can a remote-only search be un-splittable?

Andrew Bartlett
(This used to be commit 656e58672c357121647a080400fcab4e5d30b46b)

source4/lib/ldb/modules/ldb_map.c
source4/lib/ldb/modules/ldb_map.h
source4/lib/ldb/modules/ldb_map_outbound.c
source4/lib/ldb/modules/ldb_map_private.h

index cdb9f5b4a90b3f9d2204cefca141b3bed5646b6e..8eff612d1b46239a7b4ea79ddf70ac7936622c35 100644 (file)
@@ -798,7 +798,27 @@ static struct ldb_message_element *map_objectclass_generate_local(struct ldb_mod
        return el;
 }
 
+/* Mappings for searches on objectClass= assuming a one-to-one
+ * mapping.  Needed because this is a generate operator for the
+ * add/modify code */
+static int map_objectclass_convert_operator(struct ldb_module *module, void *mem_ctx, 
+                                           struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) 
+{
+       
+       static const struct ldb_map_attribute objectclass_map = {
+               .local_name = "objectclass",
+               .type = MAP_CONVERT,
+               .u = {
+                       .convert = {
+                                .remote_name = "objectclass",
+                                .convert_local = map_objectclass_convert_local,
+                                .convert_remote = map_objectclass_convert_remote,
+                        },
+               },
+       };
 
+       return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, &objectclass_map);
+}
 
 /* Auxiliary request construction
  * ============================== */
@@ -1142,6 +1162,7 @@ static const struct ldb_map_attribute builtin_attribute_maps[] = {
        {
                .local_name = "objectclass",
                .type = MAP_GENERATE,
+               .convert_operator = map_objectclass_convert_operator,
                .u = {
                        .generate = {
                                 .remote_names = { "objectclass", NULL },
index f9e2086ee170f56d15bf3e402af1ff9a6cfd5d4e..99231e61f1ab61dccb55d25055393b9d3db35f6c 100644 (file)
@@ -68,7 +68,7 @@ struct ldb_map_attribute {
        } type;
        
        /* if set, will be called for search expressions that contain this attribute */
-       struct ldb_parse_tree *(*convert_operator)(const struct ldb_map_context *, TALLOC_CTX *ctx, const struct ldb_parse_tree *);
+       int (*convert_operator)(struct ldb_module *, TALLOC_CTX *ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *);
 
        union { 
                struct {
index 046c92bb995d5230eac1271d51eda006889851c5..229299288caddd49076bcc18e6486c2a7788e219 100644 (file)
@@ -679,7 +679,7 @@ static int map_subtree_collect_remote_list(struct ldb_module *module, void *mem_
 }
 
 /* Collect a simple subtree that queries attributes in the remote partition */
-static int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree, const struct ldb_map_attribute *map)
+int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree, const struct ldb_map_attribute *map)
 {
        const char *attr;
        struct ldb_val val;
@@ -757,8 +757,7 @@ static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx,
 
        map = map_attr_find_local(data, tree->u.equality.attr);
        if (map->convert_operator) {
-               *new = map->convert_operator(data, mem_ctx, tree);
-               return 0;
+               return map->convert_operator(module, mem_ctx, new, tree);
        }
 
        if (map->type == MAP_GENERATE) {
@@ -1084,7 +1083,7 @@ int map_search(struct ldb_module *module, struct ldb_request *req)
                goto failed;
        }
 
-       if (((local_tree == NULL) ^ (remote_tree == NULL)) &&
+       if (((local_tree != NULL) && (remote_tree != NULL)) &&
            (!ldb_parse_tree_check_splittable(req->op.search.tree))) {
                /* The query can't safely be split, enumerate the remote partition */
                local_tree = NULL;
index 1b21fcf558d799f83904f72be1684710941b79b3..89d0fe0afe43829cc2b79ed12aa4d037ad0d445b 100644 (file)
@@ -92,6 +92,7 @@ struct ldb_request *map_search_base_req(struct map_context *ac, const struct ldb
 struct ldb_request *map_search_self_req(struct map_context *ac, const struct ldb_dn *dn);
 struct ldb_request *map_build_fixup_req(struct map_context *ac, const struct ldb_dn *olddn, const struct ldb_dn *newdn);
 
+int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree, const struct ldb_map_attribute *map);
 
 /* LDB Requests
  * ============ */