summaryrefslogtreecommitdiff
path: root/source4/lib/ldb
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/ldb')
-rw-r--r--source4/lib/ldb/modules/ldb_map_outbound.c110
1 files changed, 66 insertions, 44 deletions
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 */