Author: mkhl Date: 2006-06-24 22:58:04 +0000 (Sat, 24 Jun 2006) New Revision: 16506
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=16506 Log: Add local search callback. Martin Modified: branches/SOC/mkhl/ldb-map/modules/ldb_map.c Changeset: Modified: branches/SOC/mkhl/ldb-map/modules/ldb_map.c =================================================================== --- branches/SOC/mkhl/ldb-map/modules/ldb_map.c 2006-06-24 22:00:52 UTC (rev 16505) +++ branches/SOC/mkhl/ldb-map/modules/ldb_map.c 2006-06-24 22:58:04 UTC (rev 16506) @@ -1426,6 +1426,7 @@ return LDB_ERR_OPERATIONS_ERROR; } + /* extract remote DN */ ac->search_res = talloc_steal(ac, ares); ac->remote_dn = ldb_dn_explode(ac, ldb_msg_find_string(ares->message, @@ -1434,16 +1435,15 @@ return LDB_SUCCESS; } + /* create request that searches for DN */ static struct ldb_request * -search_self_req(struct map_async_context *ac, - const struct ldb_dn *dn) +search_base_req(struct map_async_context *ac, + const struct ldb_dn *dn, + const char * const *attrs, + int (*callback)(struct ldb_context *, void *, struct ldb_async_result *)) { - /* attrs[] is returned from this function in - ac->search_req->op.search.attrs, so it must be static, as - otherwise the compiler can put it on the stack */ - static const char * const attrs[] = { IS_MAPPED, NULL }; struct ldb_request *req; req = talloc_zero(ac, struct ldb_request); @@ -1465,50 +1465,96 @@ req->controls = NULL; req->async.context = ac; - req->async.callback = search_self_callback; + req->async.callback = callback; ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, req); return req; } +/* create request that searches for 'IS_MAPPED' in DN */ static +struct ldb_request * +search_self_req(struct map_async_context *ac, + const struct ldb_dn *dn) +{ + /* attrs[] is returned from this function in + ac->search_req->op.search.attrs, so it must be static, as + otherwise the compiler can put it on the stack */ + static const char * const attrs[] = { IS_MAPPED, NULL }; + + return search_base_req(ac, dn, attrs, search_self_callback); +} + +/* merge remote record with associated local record */ +static int +remote_search_callback(struct ldb_context *ldb, + void *context, + struct ldb_async_result *ares) +{ + return LDB_SUCCESS; +} + +/* for each result, search associated remote record */ +static +int local_search_callback(struct ldb_context *ldb, void *context, struct ldb_async_result *ares) { + struct map_async_context *ac; struct map_async_search_context *sc; + struct ldb_request *req; + struct ldb_dn *dn; if (context == NULL || ares == NULL) { ldb_set_errstring(ldb, talloc_asprintf(ldb, "NULL Context or Result in callback")); return LDB_ERR_OPERATIONS_ERROR; } - sc = talloc_get_type(context, struct map_async_search_context); + ac = talloc_get_type(context, struct map_async_context); - switch (ares->type) { - case LDB_REPLY_ENTRY: - /* we already have a local result */ - if (sc->local_res != NULL) { - ldb_set_errstring(ldb, - talloc_asprintf(ldb, - "Too many results")); - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } + /* stop searching if it's not a record */ + if (ares->type != LDB_REPLY_ENTRY) + return ac->orig_req-> + async.callback(ldb, ac->orig_req->async.context, ares); - sc->local_res = talloc_steal(sc, ares); + /* stop searching if it's not mapped */ + if (!ldb_msg_find_element(ares->message, IS_MAPPED)) + return ac->orig_req-> + async.callback(ldb, ac->orig_req->async.context, ares); - /* don't return the 'IS_MAPPED' attribute */ - ldb_msg_remove_attr(ares->message, IS_MAPPED); + /* extract remote DN */ + dn = ldb_dn_explode(ac, ldb_msg_find_string(ares->message, + IS_MAPPED, NULL)); + if (dn == NULL) + goto error; + ldb_msg_remove_attr(ares->message, IS_MAPPED); + ac->remote_dn = dn; - /* XXX: ... */ - - default: - talloc_free(ares); - ldb_set_errstring(ldb, talloc_asprintf(ldb, "Unexpected result type in search for local record")); - return LDB_ERR_OPERATIONS_ERROR; - } + /* prepare remote operation */ + req = talloc_zero(ac, struct ldb_request); + if (req == NULL) + goto error; + + sc = talloc(ac, struct map_async_search_context); + if (sc == NULL) + goto error; + + sc->ac = ac; + sc->local_res = ares; /* TODO: steal? */ + sc->remote_res = NULL; + + /* TODO: replace NULL with remote attrs! */ + req = search_base_req(ac, dn, NULL, remote_search_callback); + if (req == NULL) + goto error; + + return ldb_next_remote_request(ac->module, req); + +error: + talloc_free(ares); + return LDB_ERR_OPERATIONS_ERROR; } @@ -1760,7 +1806,8 @@ ac->local_req->async.context = ac; ac->local_req->async.callback = local_search_callback; - /* XXX: ... */ + /* TODO: separate local and remote attrs + maybe even store them in context */ ac->local_req->op.search.attrs = local_attrs;