summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/modules/ldb_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/ldb/modules/ldb_map.c')
-rw-r--r--source4/lib/ldb/modules/ldb_map.c198
1 files changed, 133 insertions, 65 deletions
diff --git a/source4/lib/ldb/modules/ldb_map.c b/source4/lib/ldb/modules/ldb_map.c
index 48aa7e2ef5..49261d155c 100644
--- a/source4/lib/ldb/modules/ldb_map.c
+++ b/source4/lib/ldb/modules/ldb_map.c
@@ -24,6 +24,7 @@
#include "includes.h"
#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_errors.h"
#include "ldb/include/ldb_private.h"
#include "ldb/modules/ldb_map.h"
@@ -687,8 +688,10 @@ static struct ldb_message *ldb_map_message_incoming(struct ldb_module *module, c
/*
rename a record
*/
-static int map_rename(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
+static int map_rename(struct ldb_module *module, struct ldb_request *req)
{
+ const struct ldb_dn *olddn = req->op.rename.olddn;
+ const struct ldb_dn *newdn = req->op.rename.newdn;
struct ldb_map_context *privdat = map_get_privdat(module);
struct ldb_dn *n_olddn, *n_newdn;
int ret;
@@ -699,9 +702,9 @@ static int map_rename(struct ldb_module *module, const struct ldb_dn *olddn, con
ret = ldb_rename(privdat->mapped_ldb, n_olddn, n_newdn);
if (ret != -1) {
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Mapped record renamed");
- ldb_next_rename_record(module, olddn, newdn);
+ ldb_next_request(module, req);
} else {
- ret = ldb_next_rename_record(module, olddn, newdn);
+ ret = ldb_next_request(module, req);
if (ret != -1) {
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Fallback record renamed");
@@ -718,8 +721,9 @@ static int map_rename(struct ldb_module *module, const struct ldb_dn *olddn, con
/*
delete a record
*/
-static int map_delete(struct ldb_module *module, const struct ldb_dn *dn)
+static int map_delete(struct ldb_module *module, struct ldb_request *req)
{
+ const struct ldb_dn *dn = req->op.del.dn;
struct ldb_map_context *privdat = map_get_privdat(module);
struct ldb_dn *newdn;
int ret;
@@ -730,13 +734,15 @@ static int map_delete(struct ldb_module *module, const struct ldb_dn *dn)
if (ret != -1) {
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Mapped record deleted");
} else {
- ret = ldb_next_delete_record(module, dn);
+ ret = ldb_next_request(module, req);
if (ret != -1) {
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Fallback record deleted");
}
}
- ldb_next_delete_record(module, newdn);
+ req->op.del.dn = newdn;
+ ret = ldb_next_request(module, req);
+ req->op.del.dn = dn;
talloc_free(newdn);
@@ -744,12 +750,11 @@ static int map_delete(struct ldb_module *module, const struct ldb_dn *dn)
}
/* search fallback database */
-static int map_search_fb(struct ldb_module *module, const struct ldb_dn *base,
- enum ldb_scope scope, struct ldb_parse_tree *tree,
- const char * const *attrs, struct ldb_message ***res)
+static int map_search_fb(struct ldb_module *module, struct ldb_request *req)
{
- int ret;
+ struct ldb_parse_tree *tree = req->op.search.tree;
struct ldb_parse_tree t_and, t_not, t_present, *childs[2];
+ int ret;
char *ismapped;
t_present.operation = LDB_OP_PRESENT;
@@ -764,8 +769,10 @@ static int map_search_fb(struct ldb_module *module, const struct ldb_dn *base,
t_and.operation = LDB_OP_AND;
t_and.u.list.num_elements = 2;
t_and.u.list.elements = childs;
-
- ret = ldb_next_search_bytree(module, base, scope, &t_and, attrs, res);
+
+ req->op.search.tree = &t_and;
+ ret = ldb_next_request(module, req);
+ req->op.search.tree = tree;
talloc_free(ismapped);
@@ -773,13 +780,17 @@ static int map_search_fb(struct ldb_module *module, const struct ldb_dn *base,
}
/* Search in the database against which we are mapping */
-static int map_search_mp(struct ldb_module *module, const struct ldb_dn *base,
- enum ldb_scope scope, struct ldb_parse_tree *tree,
- const char * const *attrs, struct ldb_message ***res)
+static int map_search_mp(struct ldb_module *module, struct ldb_request *req)
{
+ const struct ldb_dn *base = req->op.search.base;
+ enum ldb_scope scope = req->op.search.scope;
+ struct ldb_parse_tree *tree = req->op.search.tree;
+ const char * const *attrs = req->op.search.attrs;
+ struct ldb_result **res = req->op.search.res;
+ struct ldb_request new_req;
struct ldb_parse_tree *new_tree;
struct ldb_dn *new_base;
- struct ldb_message **newres;
+ struct ldb_result *newres;
const char **newattrs;
int mpret, ret;
struct ldb_map_context *privdat = map_get_privdat(module);
@@ -801,15 +812,22 @@ static int map_search_mp(struct ldb_module *module, const struct ldb_dn *base,
newattrs = ldb_map_attrs(module, attrs);
new_base = map_local_dn(module, module, base);
- mpret = ldb_search_bytree(privdat->mapped_ldb, new_base, scope, new_tree, newattrs, &newres);
+ memset((char *)&(new_req), 0, sizeof(new_req));
+ new_req.operation = LDB_REQ_SEARCH;
+ new_req.op.search.base = new_base;
+ new_req.op.search.scope = scope;
+ new_req.op.search.tree = new_tree;
+ new_req.op.search.attrs = newattrs;
+ new_req.op.search.res = &newres;
+ mpret = ldb_request(privdat->mapped_ldb, req);
talloc_free(new_base);
talloc_free(new_tree);
talloc_free(newattrs);
- if (mpret == -1) {
+ if (mpret != LDB_SUCCESS) {
ldb_set_errstring(module, talloc_strdup(module, ldb_errstring(privdat->mapped_ldb)));
- return -1;
+ return mpret;
}
/*
@@ -817,23 +835,34 @@ static int map_search_mp(struct ldb_module *module, const struct ldb_dn *base,
- test if (full expression) is now true
*/
- *res = talloc_array(module, struct ldb_message *, mpret);
+ *res = talloc(module, struct ldb_result);
+ (*res)->msgs = talloc_array(module, struct ldb_message *, newres->count);
+ (*res)->count = newres->count;
ret = 0;
for (i = 0; i < mpret; i++) {
+ struct ldb_request mergereq;
struct ldb_message *merged;
- struct ldb_message **extrares = NULL;
+ struct ldb_result *extrares = NULL;
int extraret;
/* Always get special DN's from the fallback database */
- if (ldb_dn_is_special(newres[i]->dn))
+ if (ldb_dn_is_special(newres->msgs[i]->dn))
continue;
- merged = ldb_map_message_incoming(module, attrs, newres[i]);
+ merged = ldb_map_message_incoming(module, attrs, newres->msgs[i]);
/* Merge with additional data from fallback database */
- extraret = ldb_next_search(module, merged->dn, LDB_SCOPE_BASE, "", NULL, &extrares);
+ memset((char *)&(mergereq), 0, sizeof(mergereq)); /* zero off the request structure */
+ mergereq.operation = LDB_REQ_SEARCH;
+ mergereq.op.search.base = merged->dn;
+ mergereq.op.search.scope = LDB_SCOPE_BASE;
+ mergereq.op.search.tree = ldb_parse_tree(module, "");
+ mergereq.op.search.attrs = NULL;
+ mergereq.op.search.res = &extrares;
+
+ extraret = ldb_next_request(module, &mergereq);
if (extraret == -1) {
ldb_debug(module->ldb, LDB_DEBUG_ERROR, "Error searching for extra data!\n");
@@ -848,13 +877,13 @@ static int map_search_mp(struct ldb_module *module, const struct ldb_dn *base,
if (extraret == 1) {
int j;
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Extra data found for remote DN: %s", ldb_dn_linearize(merged, merged->dn));
- for (j = 0; j < extrares[0]->num_elements; j++) {
- ldb_msg_add(merged, &(extrares[0]->elements[j]), extrares[0]->elements[j].flags);
+ for (j = 0; j < extrares->msgs[0]->num_elements; j++) {
+ ldb_msg_add(merged, &(extrares->msgs[0]->elements[j]), extrares->msgs[0]->elements[j].flags);
}
}
if (ldb_match_msg(module->ldb, merged, tree, base, scope) != 0) {
- (*res)[ret] = merged;
+ (*res)->msgs[ret] = merged;
ret++;
} else {
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Discarded merged message because it did not match");
@@ -863,45 +892,51 @@ static int map_search_mp(struct ldb_module *module, const struct ldb_dn *base,
talloc_free(newres);
- return ret;
+ (*res)->count = ret;
+ return LDB_SUCCESS;
}
/*
search for matching records using a ldb_parse_tree
*/
-static int map_search_bytree(struct ldb_module *module, const struct ldb_dn *base,
- enum ldb_scope scope, struct ldb_parse_tree *tree,
- const char * const *attrs, struct ldb_message ***res)
+static int map_search_bytree(struct ldb_module *module, struct ldb_request *req)
{
- struct ldb_message **fbres, **mpres = NULL;
- int i;
- int ret_fb, ret_mp;
+ const struct ldb_dn *base = req->op.search.base;
+ struct ldb_result **res = req->op.search.res;
+ struct ldb_result *fbres, *mpres = NULL;
+ int i, ret;
- ret_fb = map_search_fb(module, base, scope, tree, attrs, &fbres);
- if (ret_fb == -1)
- return -1;
+ req->op.search.res = &fbres;
+ ret = map_search_fb(module, req);
+ req->op.search.res = res;
+ if (ret != LDB_SUCCESS)
+ return ret;
/* special dn's are never mapped.. */
if (ldb_dn_is_special(base)) {
*res = fbres;
- return ret_fb;
+ return ret;
}
- ret_mp = map_search_mp(module, base, scope, tree, attrs, &mpres);
- if (ret_mp == -1) {
- return -1;
+ req->op.search.res = &mpres;
+ ret = map_search_mp(module, req);
+ req->op.search.res = res;
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
/* Merge results */
- *res = talloc_array(module, struct ldb_message *, ret_fb + ret_mp);
+ *res = talloc(module, struct ldb_result);
+ (*res)->msgs = talloc_array(*res, struct ldb_message *, fbres->count + mpres->count);
- ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Merging %d mapped and %d fallback messages", ret_mp, ret_fb);
+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Merging %d mapped and %d fallback messages", mpres->count, fbres->count);
- for (i = 0; i < ret_fb; i++) (*res)[i] = fbres[i];
- for (i = 0; i < ret_mp; i++) (*res)[ret_fb+i] = mpres[i];
+ for (i = 0; i < fbres->count; i++) (*res)->msgs[i] = fbres->msgs[i];
+ for (i = 0; i < mpres->count; i++) (*res)->msgs[fbres->count + i] = mpres->msgs[i];
- return ret_fb + ret_mp;
+ (*res)->count = fbres->count + mpres->count;
+ return LDB_SUCCESS;
}
static int msg_contains_objectclass(const struct ldb_message *msg, const char *name)
@@ -921,19 +956,20 @@ static int msg_contains_objectclass(const struct ldb_message *msg, const char *n
/*
add a record
*/
-static int map_add(struct ldb_module *module, const struct ldb_message *msg)
+static int map_add(struct ldb_module *module, struct ldb_request *req)
{
- int ret;
+ const struct ldb_message *msg = req->op.add.message;
struct ldb_map_context *privdat = map_get_privdat(module);
struct ldb_message *fb, *mp;
struct ldb_message_element *ocs;
+ int ret;
int i;
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_add");
if (ldb_dn_is_special(msg->dn)) {
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_add: Added fallback record");
- return ldb_next_add_record(module, msg);
+ return ldb_next_request(module, req);
}
mp = talloc_zero(module, struct ldb_message);
@@ -981,7 +1017,7 @@ static int map_add(struct ldb_module *module, const struct ldb_message *msg)
ocs = ldb_msg_find_element(mp, "objectClass");
if (ocs->num_values == 1) { /* Only top */
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_add: Added fallback record");
- return ldb_next_add_record(module, msg);
+ return ldb_next_request(module, req);
}
/*
@@ -1098,7 +1134,10 @@ static int map_add(struct ldb_module *module, const struct ldb_message *msg)
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_add: Added mapped record");
ldb_msg_add_string(fb, "isMapped", "TRUE");
- ret = ldb_next_add_record(module, fb);
+
+ req->op.add.message = fb;
+ ret = ldb_next_request(module, req);
+ req->op.add.message = msg;
if (ret == -1) {
ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Adding fallback record failed: %s", ldb_errstring(module->ldb));
return -1;
@@ -1114,8 +1153,9 @@ static int map_add(struct ldb_module *module, const struct ldb_message *msg)
/*
modify a record
*/
-static int map_modify(struct ldb_module *module, const struct ldb_message *msg)
+static int map_modify(struct ldb_module *module, struct ldb_request *req)
{
+ const struct ldb_message *msg = req->op.mod.message;
struct ldb_map_context *privdat = map_get_privdat(module);
struct ldb_message *fb, *mp;
struct ldb_message_element *elm;
@@ -1125,7 +1165,7 @@ static int map_modify(struct ldb_module *module, const struct ldb_message *msg)
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map_modify");
if (ldb_dn_is_special(msg->dn))
- return ldb_next_modify_record(module, msg);
+ return ldb_next_request(module, req);
fb = talloc_zero(module, struct ldb_message);
fb->dn = talloc_reference(fb, msg->dn);
@@ -1217,11 +1257,16 @@ static int map_modify(struct ldb_module *module, const struct ldb_message *msg)
if (fb->num_elements > 0) {
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "Modifying fallback record with %d elements", fb->num_elements);
- fb_ret = ldb_next_modify_record(module, fb);
+ req->op.mod.message = fb;
+ fb_ret = ldb_next_request(module, req);
if (fb_ret == -1) {
ldb_msg_add_string(fb, "isMapped", "TRUE");
- fb_ret = ldb_next_add_record(module, fb);
+ req->operation = LDB_REQ_ADD;
+ req->op.add.message = fb;
+ fb_ret = ldb_next_request(module, req);
+ req->operation = LDB_REQ_MODIFY;
}
+ req->op.mod.message = msg;
} else fb_ret = 0;
talloc_free(fb);
@@ -1234,19 +1279,42 @@ static int map_modify(struct ldb_module *module, const struct ldb_message *msg)
return (mp_ret == -1 || fb_ret == -1)?-1:0;
}
+
+static int map_request(struct ldb_module *module, struct ldb_request *req)
+{
+ switch (req->operation) {
+
+ case LDB_REQ_SEARCH:
+ return map_search_bytree(module, req);
+
+ case LDB_REQ_ADD:
+ return map_add(module, req);
+
+ case LDB_REQ_MODIFY:
+ return map_modify(module, req);
+
+ case LDB_REQ_DELETE:
+ return map_delete(module, req);
+
+ case LDB_REQ_RENAME:
+ return map_rename(module, req);
+
+ default:
+ return ldb_next_request(module, req);
+
+ }
+}
+
+
static const struct ldb_module_ops map_ops = {
.name = "map",
- .search_bytree = map_search_bytree,
- .add_record = map_add,
- .modify_record = map_modify,
- .delete_record = map_delete,
- .rename_record = map_rename
+ .request = map_request
};
static char *map_find_url(struct ldb_context *ldb, const char *name)
{
const char * const attrs[] = { "@MAP_URL" , NULL};
- struct ldb_message **msg = NULL;
+ struct ldb_result *result = NULL;
struct ldb_dn *mods;
char *url;
int ret;
@@ -1257,16 +1325,16 @@ static char *map_find_url(struct ldb_context *ldb, const char *name)
return NULL;
}
- ret = ldb_search(ldb, mods, LDB_SCOPE_BASE, "", attrs, &msg);
+ ret = ldb_search(ldb, mods, LDB_SCOPE_BASE, "", attrs, &result);
talloc_free(mods);
- if (ret < 1) {
+ if (ret != LDB_SUCCESS || result->count == 0) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "Not enough results found looking for @MAP");
return NULL;
}
- url = talloc_strdup(ldb, ldb_msg_find_string(msg[0], "@MAP_URL", NULL));
+ url = talloc_strdup(ldb, ldb_msg_find_string(result->msgs[0], "@MAP_URL", NULL));
- talloc_free(msg);
+ talloc_free(result);
return url;
}