summaryrefslogtreecommitdiff
path: root/lib/ldb/ldb_map
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ldb/ldb_map')
-rw-r--r--lib/ldb/ldb_map/ldb_map.c16
-rw-r--r--lib/ldb/ldb_map/ldb_map.h3
-rw-r--r--lib/ldb/ldb_map/ldb_map_inbound.c21
-rw-r--r--lib/ldb/ldb_map/ldb_map_outbound.c64
-rw-r--r--lib/ldb/ldb_map/ldb_map_private.h2
5 files changed, 65 insertions, 41 deletions
diff --git a/lib/ldb/ldb_map/ldb_map.c b/lib/ldb/ldb_map/ldb_map.c
index d35e5c604fc..66b00592921 100644
--- a/lib/ldb/ldb_map/ldb_map.c
+++ b/lib/ldb/ldb_map/ldb_map.c
@@ -223,12 +223,18 @@ int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *reque
case LDB_ADD:
msg = ldb_msg_copy_shallow(request, request->op.add.message);
+ if (msg == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn);
request->op.add.message = msg;
break;
case LDB_MODIFY:
msg = ldb_msg_copy_shallow(request, request->op.mod.message);
+ if (msg == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn);
request->op.mod.message = msg;
break;
@@ -326,6 +332,7 @@ const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_contex
break;
case LDB_MAP_RENAME:
+ case LDB_MAP_RENDROP:
case LDB_MAP_CONVERT:
if (ldb_attr_cmp(map->u.rename.remote_name, name) == 0) {
return map;
@@ -333,7 +340,7 @@ const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_contex
break;
case LDB_MAP_GENERATE:
- for (j = 0; map->u.generate.remote_names && map->u.generate.remote_names[j]; j++) {
+ for (j = 0; map->u.generate.remote_names[j]; j++) {
if (ldb_attr_cmp(map->u.generate.remote_names[j], name) == 0) {
return map;
}
@@ -377,6 +384,7 @@ const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *ma
return talloc_strdup(mem_ctx, attr);
case LDB_MAP_RENAME:
+ case LDB_MAP_RENDROP:
case LDB_MAP_CONVERT:
return talloc_strdup(mem_ctx, map->u.rename.remote_name);
@@ -518,6 +526,7 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct
/* fall through */
case LDB_MAP_KEEP:
case LDB_MAP_RENAME:
+ case LDB_MAP_RENDROP:
name = map_attr_map_local(newdn, map, ldb_dn_get_component_name(dn, i));
if (name == NULL) goto failed;
@@ -593,6 +602,7 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struc
/* fall through */
case LDB_MAP_KEEP:
case LDB_MAP_RENAME:
+ case LDB_MAP_RENDROP:
name = map_attr_map_remote(newdn, map, ldb_dn_get_component_name(dn, i));
if (name == NULL) goto failed;
@@ -869,9 +879,9 @@ static int map_objectclass_convert_operator(struct ldb_module *module, void *mem
* ============================== */
/* Build a request to search a record by its DN. */
-struct ldb_request *map_search_base_req(struct map_context *ac, struct ldb_dn *dn, const char * const *attrs, const struct ldb_parse_tree *tree, void *context, ldb_map_callback_t callback)
+struct ldb_request *map_search_base_req(struct map_context *ac, struct ldb_dn *dn, const char * const *attrs, struct ldb_parse_tree *tree, void *context, ldb_map_callback_t callback)
{
- const struct ldb_parse_tree *search_tree;
+ struct ldb_parse_tree *search_tree;
struct ldb_context *ldb;
struct ldb_request *req;
int ret;
diff --git a/lib/ldb/ldb_map/ldb_map.h b/lib/ldb/ldb_map/ldb_map.h
index 5db3e02a08a..46ef3cca45a 100644
--- a/lib/ldb/ldb_map/ldb_map.h
+++ b/lib/ldb/ldb_map/ldb_map.h
@@ -63,9 +63,10 @@ struct ldb_map_attribute {
LDB_MAP_KEEP, /* Keep as is. Same name locally and remotely. */
LDB_MAP_RENAME, /* Simply rename the attribute. Name changes, data is the same */
LDB_MAP_CONVERT, /* Rename + convert data */
- LDB_MAP_GENERATE /* Use generate function for generating new name/data.
+ LDB_MAP_GENERATE, /* Use generate function for generating new name/data.
Used for generating attributes based on
multiple remote attributes. */
+ LDB_MAP_RENDROP /* Rename the attribute. Strip from Add requests. */
} type;
/* if set, will be called for search expressions that contain this attribute */
diff --git a/lib/ldb/ldb_map/ldb_map_inbound.c b/lib/ldb/ldb_map/ldb_map_inbound.c
index 38dd5ac066d..461e68113ab 100644
--- a/lib/ldb/ldb_map/ldb_map_inbound.c
+++ b/lib/ldb/ldb_map/ldb_map_inbound.c
@@ -65,7 +65,7 @@ static struct ldb_message_element *ldb_msg_el_map_local(struct ldb_module *modul
/* Add a message element either to a local or to a remote message,
* depending on whether it goes into the local or remote partition. */
-static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg, const char *attr_name, /* const char * const names[], */ const struct ldb_message_element *old)
+static int ldb_msg_el_partition(struct ldb_module *module, enum ldb_request_type optype, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg, const char *attr_name, /* const char * const names[], */ const struct ldb_message_element *old)
{
const struct ldb_map_context *data = map_get_context(module);
const struct ldb_map_attribute *map = map_attr_find_local(data, attr_name);
@@ -81,6 +81,13 @@ static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *l
}
switch (map->type) {
+ case LDB_MAP_RENDROP:
+ if (optype != LDB_ADD) {
+ /* do the same as LDB_MAP_RENAME */
+ el = ldb_msg_el_map_local(module, remote, map, old);
+ break;
+ }
+ /* fall through */
case LDB_MAP_IGNORE:
goto local;
@@ -157,7 +164,7 @@ static bool ldb_msg_check_remote(struct ldb_module *module, const struct ldb_mes
/* Split message elements that stay in the local partition from those
* that are mapped into the remote partition. */
-static int ldb_msg_partition(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg)
+static int ldb_msg_partition(struct ldb_module *module, enum ldb_request_type optype, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg)
{
/* const char * const names[]; */
struct ldb_context *ldb;
@@ -175,7 +182,7 @@ static int ldb_msg_partition(struct ldb_module *module, struct ldb_message *loca
continue;
}
- ret = ldb_msg_el_partition(module, local, remote, msg, msg->elements[i].name, &msg->elements[i]);
+ ret = ldb_msg_el_partition(module, optype, local, remote, msg, msg->elements[i].name, &msg->elements[i]);
if (ret) {
return ret;
}
@@ -408,7 +415,7 @@ int ldb_map_add(struct ldb_module *module, struct ldb_request *req)
remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn);
/* Split local from remote message */
- ldb_msg_partition(module, ac->local_msg, remote_msg, msg);
+ ldb_msg_partition(module, req->operation, ac->local_msg, remote_msg, msg);
/* Prepare the remote operation */
ret = ldb_build_add_req(&ac->remote_req, ldb,
@@ -469,7 +476,7 @@ static int map_add_do_local(struct map_context *ac)
int ldb_map_modify(struct ldb_module *module, struct ldb_request *req)
{
const struct ldb_message *msg = req->op.mod.message;
- struct ldb_request *search_req;
+ struct ldb_request *search_req = NULL;
struct ldb_message *remote_msg;
struct ldb_context *ldb;
struct map_context *ac;
@@ -518,7 +525,7 @@ int ldb_map_modify(struct ldb_module *module, struct ldb_request *req)
remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn);
/* Split local from remote message */
- ldb_msg_partition(module, ac->local_msg, remote_msg, msg);
+ ldb_msg_partition(module, req->operation, ac->local_msg, remote_msg, msg);
/* Prepare the remote operation */
ret = ldb_build_mod_req(&ac->remote_req, ldb,
@@ -692,7 +699,7 @@ static int map_delete_do_local(struct map_context *ac)
/* Rename a record. */
int ldb_map_rename(struct ldb_module *module, struct ldb_request *req)
{
- struct ldb_request *search_req;
+ struct ldb_request *search_req = NULL;
struct ldb_context *ldb;
struct map_context *ac;
int ret;
diff --git a/lib/ldb/ldb_map/ldb_map_outbound.c b/lib/ldb/ldb_map/ldb_map_outbound.c
index 2c517a625dc..1ee2dfe12de 100644
--- a/lib/ldb/ldb_map/ldb_map_outbound.c
+++ b/lib/ldb/ldb_map/ldb_map_outbound.c
@@ -134,6 +134,7 @@ static const char **map_attrs_collect_remote(struct ldb_module *module, void *me
goto named;
case LDB_MAP_RENAME:
+ case LDB_MAP_RENDROP:
case LDB_MAP_CONVERT:
name = map->u.rename.remote_name;
goto named;
@@ -189,26 +190,30 @@ static int map_attrs_partition(struct ldb_module *module, void *mem_ctx, const c
static int ldb_msg_replace(struct ldb_message *msg, const struct ldb_message_element *el)
{
struct ldb_message_element *old;
-
+ int j;
old = ldb_msg_find_element(msg, el->name);
/* no local result, add as new element */
if (old == NULL) {
if (ldb_msg_add_empty(msg, el->name, 0, &old) != 0) {
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
- talloc_free(discard_const_p(char, old->name));
+ }
+ else {
+ talloc_free(old->values);
}
- /* copy new element */
- *old = *el;
-
- /* and make sure we reference the contents */
- if (!talloc_reference(msg->elements, el->name)) {
- return -1;
+ old->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
+ old->num_values = el->num_values;
+ if (old->values == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
}
- if (!talloc_reference(msg->elements, el->values)) {
- return -1;
+ /* copy the values into the element */
+ for (j=0;j<el->num_values;j++) {
+ old->values[j] = ldb_val_dup(old->values, &el->values[j]);
+ if (old->values[j].data == NULL && el->values[j].length != 0) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
}
return 0;
@@ -241,7 +246,7 @@ static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *modu
for (i = 0; data->attribute_maps[i].local_name; i++) {
struct ldb_map_attribute *am = &data->attribute_maps[i];
- if ((am->type == LDB_MAP_RENAME &&
+ if (((am->type == LDB_MAP_RENAME || am->type == LDB_MAP_RENDROP) &&
!strcmp(am->u.rename.remote_name, attr_name))
|| (am->type == LDB_MAP_CONVERT &&
!strcmp(am->u.convert.remote_name, attr_name))) {
@@ -306,6 +311,7 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
remote_name = attr_name;
break;
case LDB_MAP_RENAME:
+ case LDB_MAP_RENDROP:
remote_name = map->u.rename.remote_name;
break;
case LDB_MAP_GENERATE:
@@ -327,6 +333,7 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
/* fall through */
case LDB_MAP_KEEP:
case LDB_MAP_RENAME:
+ case LDB_MAP_RENDROP:
old = ldb_msg_find_element(remote, remote_name);
if (old) {
el = ldb_msg_el_map_remote(module, local, map, attr_name, old);
@@ -480,7 +487,7 @@ static int map_reply_remote(struct map_context *ac, struct ldb_reply *ares)
msg = ldb_msg_new(ares);
if (msg == NULL) {
map_oom(ac->module);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
/* Merge remote message into new message */
@@ -494,7 +501,7 @@ static int map_reply_remote(struct map_context *ac, struct ldb_reply *ares)
dn = ldb_dn_map_rebase_remote(ac->module, msg, ares->message->dn);
if (dn == NULL) {
talloc_free(msg);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
msg->dn = dn;
@@ -581,7 +588,7 @@ static int map_subtree_select_local_not(struct ldb_module *module, void *mem_ctx
*new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree));
if (*new == NULL) {
map_oom(module);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
/* Generate new subtree */
@@ -613,7 +620,7 @@ static int map_subtree_select_local_list(struct ldb_module *module, void *mem_ct
*new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree));
if (*new == NULL) {
map_oom(module);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
/* Prepare list of subtrees */
@@ -622,7 +629,7 @@ static int map_subtree_select_local_list(struct ldb_module *module, void *mem_ct
if ((*new)->u.list.elements == NULL) {
map_oom(module);
talloc_free(*new);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
/* Generate new list of subtrees */
@@ -662,7 +669,7 @@ static int map_subtree_select_local_simple(struct ldb_module *module, void *mem_
*new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree));
if (*new == NULL) {
map_oom(module);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
return 0;
@@ -705,7 +712,7 @@ static int map_subtree_collect_remote_not(struct ldb_module *module, void *mem_c
*new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree));
if (*new == NULL) {
map_oom(module);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
/* Generate new subtree */
@@ -737,7 +744,7 @@ static int map_subtree_collect_remote_list(struct ldb_module *module, void *mem_
*new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree));
if (*new == NULL) {
map_oom(module);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
/* Prepare list of subtrees */
@@ -746,7 +753,7 @@ static int map_subtree_collect_remote_list(struct ldb_module *module, void *mem_
if ((*new)->u.list.elements == NULL) {
map_oom(module);
talloc_free(*new);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
/* Generate new list of subtrees */
@@ -788,7 +795,7 @@ int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx,
*new = talloc(mem_ctx, struct ldb_parse_tree);
if (*new == NULL) {
map_oom(module);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
**new = *tree;
@@ -825,7 +832,7 @@ int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx,
break;
default: /* unknown kind of simple subtree */
talloc_free(*new);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
if (attr == NULL) {
@@ -834,7 +841,7 @@ int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx,
return 0;
}
- if (map->type == LDB_MAP_RENAME) {
+ if (map->type == LDB_MAP_RENAME || map->type == LDB_MAP_RENDROP) {
/* Nothing more to do here, the attribute has been renamed */
return 0;
}
@@ -848,7 +855,7 @@ int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx,
int i;
/* Map value */
(*new)->u.substring.chunks = NULL;
- for (i=0; tree->u.substring.chunks[i]; i++) {
+ for (i=0; tree->u.substring.chunks && 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);
@@ -880,7 +887,7 @@ int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx,
break;
default: /* unknown kind of simple subtree */
talloc_free(*new);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
return 0;
@@ -1031,7 +1038,7 @@ done:
oom:
map_oom(module);
- return -1;
+ return LDB_ERR_OPERATIONS_ERROR;
}
@@ -1264,8 +1271,7 @@ static int map_remote_search_callback(struct ldb_request *req,
if (ret != LDB_SUCCESS) {
talloc_free(ares);
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
+ return ldb_module_done(ac->req, NULL, NULL, ret);
}
break;
diff --git a/lib/ldb/ldb_map/ldb_map_private.h b/lib/ldb/ldb_map/ldb_map_private.h
index 7faaa997088..6e4a9dded58 100644
--- a/lib/ldb/ldb_map/ldb_map_private.h
+++ b/lib/ldb/ldb_map/ldb_map_private.h
@@ -75,7 +75,7 @@ struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx
struct ldb_request *map_search_base_req(struct map_context *ac,
struct ldb_dn *dn,
const char * const *attrs,
- const struct ldb_parse_tree *tree,
+ struct ldb_parse_tree *tree,
void *context,
ldb_map_callback_t callback);
struct ldb_request *map_build_fixup_req(struct map_context *ac,