Author: abartlet Date: 2006-09-14 07:57:49 +0000 (Thu, 14 Sep 2006) New Revision: 18504
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=18504 Log: 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 Modified: branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/entryUUID.c branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map_outbound.c Changeset: Modified: branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/entryUUID.c =================================================================== --- branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/entryUUID.c 2006-09-14 07:30:46 UTC (rev 18503) +++ branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/entryUUID.c 2006-09-14 07:57:49 UTC (rev 18504) @@ -284,11 +284,11 @@ } }, { - .local_name = "samAccountType", + .local_name = "sAMAccountType", .type = MAP_CONVERT, .u = { .convert = { - .remote_name = "samAccountType", + .remote_name = "sAMAccountType", .convert_local = normalise_to_signed32, .convert_remote = val_copy, }, Modified: branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map_outbound.c =================================================================== --- branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map_outbound.c 2006-09-14 07:30:46 UTC (rev 18503) +++ branches/SAMBA_4_0/source/lib/ldb/modules/ldb_map_outbound.c 2006-09-14 07:57:49 UTC (rev 18504) @@ -180,37 +180,6 @@ 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 @@ 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 */