diff options
-rw-r--r-- | lib/ldb/common/ldb_parse.c | 86 | ||||
-rw-r--r-- | lib/ldb/include/ldb_module.h | 7 |
2 files changed, 77 insertions, 16 deletions
diff --git a/lib/ldb/common/ldb_parse.c b/lib/ldb/common/ldb_parse.c index 8c6c2d993e..407af9f244 100644 --- a/lib/ldb/common/ldb_parse.c +++ b/lib/ldb/common/ldb_parse.c @@ -808,50 +808,104 @@ char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tre /* - replace any occurrences of an attribute name in the parse tree with a - new name + walk a parse tree, calling the provided callback on each node */ -void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, - const char *attr, - const char *replace) +int ldb_parse_tree_walk(struct ldb_parse_tree *tree, + int (*callback)(struct ldb_parse_tree *tree, void *), + void *private_context) { unsigned int i; + int ret; + + ret = callback(tree, private_context); + if (ret != LDB_SUCCESS) { + return ret; + } + switch (tree->operation) { case LDB_OP_AND: case LDB_OP_OR: for (i=0;i<tree->u.list.num_elements;i++) { - ldb_parse_tree_attr_replace(tree->u.list.elements[i], - attr, replace); + ret = ldb_parse_tree_walk(tree->u.list.elements[i], callback, private_context); + if (ret != LDB_SUCCESS) { + return ret; + } } break; case LDB_OP_NOT: - ldb_parse_tree_attr_replace(tree->u.isnot.child, attr, replace); + ret = ldb_parse_tree_walk(tree->u.isnot.child, callback, private_context); + if (ret != LDB_SUCCESS) { + return ret; + } break; case LDB_OP_EQUALITY: case LDB_OP_GREATER: case LDB_OP_LESS: case LDB_OP_APPROX: - if (ldb_attr_cmp(tree->u.equality.attr, attr) == 0) { - tree->u.equality.attr = replace; + case LDB_OP_SUBSTRING: + case LDB_OP_PRESENT: + case LDB_OP_EXTENDED: + break; + } + return LDB_SUCCESS; +} + +struct parse_tree_attr_replace_ctx { + const char *attr; + const char *replace; +}; + +/* + callback for ldb_parse_tree_attr_replace() + */ +static int parse_tree_attr_replace(struct ldb_parse_tree *tree, void *private_context) +{ + struct parse_tree_attr_replace_ctx *ctx = private_context; + switch (tree->operation) { + case LDB_OP_EQUALITY: + case LDB_OP_GREATER: + case LDB_OP_LESS: + case LDB_OP_APPROX: + if (ldb_attr_cmp(tree->u.equality.attr, ctx->attr) == 0) { + tree->u.equality.attr = ctx->replace; } break; case LDB_OP_SUBSTRING: - if (ldb_attr_cmp(tree->u.substring.attr, attr) == 0) { - tree->u.substring.attr = replace; + if (ldb_attr_cmp(tree->u.substring.attr, ctx->attr) == 0) { + tree->u.substring.attr = ctx->replace; } break; case LDB_OP_PRESENT: - if (ldb_attr_cmp(tree->u.present.attr, attr) == 0) { - tree->u.present.attr = replace; + if (ldb_attr_cmp(tree->u.present.attr, ctx->attr) == 0) { + tree->u.present.attr = ctx->replace; } break; case LDB_OP_EXTENDED: if (tree->u.extended.attr && - ldb_attr_cmp(tree->u.extended.attr, attr) == 0) { - tree->u.extended.attr = replace; + ldb_attr_cmp(tree->u.extended.attr, ctx->attr) == 0) { + tree->u.extended.attr = ctx->replace; } break; + default: + break; } + return LDB_SUCCESS; +} + +/* + replace any occurrences of an attribute name in the parse tree with a + new name +*/ +void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, + const char *attr, + const char *replace) +{ + struct parse_tree_attr_replace_ctx ctx; + + ctx.attr = attr; + ctx.replace = replace; + + ldb_parse_tree_walk(tree, parse_tree_attr_replace, &ctx); } /* diff --git a/lib/ldb/include/ldb_module.h b/lib/ldb/include/ldb_module.h index 22d24dbdea..fecf0c7ede 100644 --- a/lib/ldb/include/ldb_module.h +++ b/lib/ldb/include/ldb_module.h @@ -348,4 +348,11 @@ int ldb_init_module(const char *version); */ bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn); +/* + walk a parse tree, calling the provided callback on each node +*/ +int ldb_parse_tree_walk(struct ldb_parse_tree *tree, + int (*callback)(struct ldb_parse_tree *tree, void *), + void *private_context); + #endif |