From 595c141a69ea0744fccba477717a71fa4abeb825 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 14 Sep 2006 07:57:49 +0000 Subject: r18504: Handle mappings for RENAME and KEEP attributes better. We don't need to mess with the values in these cases. Where we do convert the values, try and convert substrings. This isn't going to be perfect, but we should try rather than segfault. This also avoids using the wrong arm of the union for the attribute name The change in the entryUUID module is to correct the case of sAMAccountName, due to the case sensitive ldap.js test. Andrew Bartlett (This used to be commit 81d9a692c1e74ec9078bf718003eafdba85b4324) --- source4/lib/ldb/modules/ldb_map_outbound.c | 110 +++++++++++++++++------------ 1 file changed, 66 insertions(+), 44 deletions(-) (limited to 'source4/lib') diff --git a/source4/lib/ldb/modules/ldb_map_outbound.c b/source4/lib/ldb/modules/ldb_map_outbound.c index c034a86375..e1b207f6eb 100644 --- a/source4/lib/ldb/modules/ldb_map_outbound.c +++ b/source4/lib/ldb/modules/ldb_map_outbound.c @@ -180,37 +180,6 @@ static int map_attrs_partition(struct ldb_module *module, void *local_ctx, void return 0; } -/* Mapping ldb values - * ================== */ - -/* Map an ldb value from a parse tree into the remote partition. */ -static struct ldb_val ldb_val_map_subtree(struct ldb_module *module, struct ldb_parse_tree *new, const struct ldb_map_attribute *map, const struct ldb_parse_tree *tree) -{ - struct ldb_val val; - - /* Extract the old value */ - switch (tree->operation) { - case LDB_OP_EQUALITY: - val = tree->u.equality.value; - break; - case LDB_OP_LESS: - case LDB_OP_GREATER: - case LDB_OP_APPROX: - val = tree->u.comparison.value; - break; - case LDB_OP_EXTENDED: - val = tree->u.extended.value; - break; - default: - val.length = 0; - val.data = NULL; - return ldb_val_dup(new, &val); - } - - /* Convert to the new value */ - return ldb_val_map_local(module, new, map, val); -} - /* Mapping message elements * ======================== */ @@ -677,46 +646,99 @@ static int map_subtree_collect_remote_list(struct ldb_module *module, void *mem_ 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; /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); + *new = talloc(mem_ctx, struct ldb_parse_tree); if (*new == NULL) { map_oom(module); return -1; } - - /* Map attribute and value */ - attr = map_attr_map_local(*new, map, tree->u.equality.attr); - if (attr == NULL) { - talloc_free(*new); - *new = NULL; + **new = *tree; + + if (map->type == MAP_KEEP) { + /* Nothing to do here */ return 0; } - val = ldb_val_map_subtree(module, *new, map, tree); /* Store attribute and value in new tree */ switch (tree->operation) { case LDB_OP_PRESENT: + attr = map_attr_map_local(*new, map, tree->u.present.attr); (*new)->u.present.attr = attr; break; case LDB_OP_SUBSTRING: + { + attr = map_attr_map_local(*new, map, tree->u.substring.attr); (*new)->u.substring.attr = attr; - (*new)->u.substring.chunks = NULL; /* FIXME! */ break; + } case LDB_OP_EQUALITY: + attr = map_attr_map_local(*new, map, tree->u.equality.attr); (*new)->u.equality.attr = attr; - (*new)->u.equality.value = val; break; case LDB_OP_LESS: case LDB_OP_GREATER: case LDB_OP_APPROX: + attr = map_attr_map_local(*new, map, tree->u.comparison.attr); (*new)->u.comparison.attr = attr; - (*new)->u.comparison.value = val; break; case LDB_OP_EXTENDED: + attr = map_attr_map_local(*new, map, tree->u.extended.attr); (*new)->u.extended.attr = attr; - (*new)->u.extended.value = val; + break; + default: /* unknown kind of simple subtree */ + talloc_free(*new); + return -1; + } + + if (attr == NULL) { + talloc_free(*new); + *new = NULL; + return 0; + } + + if (map->type == MAP_RENAME) { + /* Nothing more to do here, the attribute has been renamed */ + return 0; + } + + /* Store attribute and value in new tree */ + switch (tree->operation) { + case LDB_OP_PRESENT: + break; + case LDB_OP_SUBSTRING: + { + int i; + /* Map value */ + (*new)->u.substring.chunks = NULL; + for (i=0; tree->u.substring.chunks[i]; i++) { + (*new)->u.substring.chunks = talloc_realloc(*new, (*new)->u.substring.chunks, struct ldb_val *, i+2); + if (!(*new)->u.substring.chunks) { + talloc_free(*new); + *new = NULL; + return 0; + } + (*new)->u.substring.chunks[i] = talloc(*new, struct ldb_val); + if (!(*new)->u.substring.chunks[i]) { + talloc_free(*new); + *new = NULL; + return 0; + } + *(*new)->u.substring.chunks[i] = ldb_val_map_local(module, *new, map, *tree->u.substring.chunks[i]); + (*new)->u.substring.chunks[i+1] = NULL; + } + break; + } + case LDB_OP_EQUALITY: + (*new)->u.equality.value = ldb_val_map_local(module, *new, map, tree->u.equality.value); + break; + case LDB_OP_LESS: + case LDB_OP_GREATER: + case LDB_OP_APPROX: + (*new)->u.comparison.value = ldb_val_map_local(module, *new, map, tree->u.comparison.value); + break; + case LDB_OP_EXTENDED: + (*new)->u.extended.value = ldb_val_map_local(module, *new, map, tree->u.extended.value); (*new)->u.extended.rule_id = talloc_strdup(*new, tree->u.extended.rule_id); break; default: /* unknown kind of simple subtree */ -- cgit