summaryrefslogtreecommitdiff
path: root/server/providers/ldap
diff options
context:
space:
mode:
Diffstat (limited to 'server/providers/ldap')
-rw-r--r--server/providers/ldap/ldap_id.c27
-rw-r--r--server/providers/ldap/sdap.h28
-rw-r--r--server/providers/ldap/sdap_async.c845
3 files changed, 403 insertions, 497 deletions
diff --git a/server/providers/ldap/ldap_id.c b/server/providers/ldap/ldap_id.c
index 83d009ee..3008f9be 100644
--- a/server/providers/ldap/ldap_id.c
+++ b/server/providers/ldap/ldap_id.c
@@ -113,7 +113,7 @@ static bool connected(struct sdap_id_ctx *ctx)
struct sdap_id_connect_state {
struct tevent_context *ev;
- struct sdap_options *opts;
+ struct sdap_id_ctx *ctx;
bool use_start_tls;
struct sdap_handle *sh;
@@ -124,7 +124,7 @@ static void sdap_id_anon_bind_done(struct tevent_req *subreq);
struct tevent_req *sdap_id_connect_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
- struct sdap_options *opts,
+ struct sdap_id_ctx *ctx,
bool use_start_tls)
{
struct tevent_req *req, *subreq;
@@ -134,10 +134,10 @@ struct tevent_req *sdap_id_connect_send(TALLOC_CTX *memctx,
if (!req) return NULL;
state->ev = ev;
- state->opts = opts;
+ state->ctx = ctx;
state->use_start_tls = use_start_tls;
- subreq = sdap_connect_send(state, ev, opts, use_start_tls);
+ subreq = sdap_connect_send(state, ev, ctx->opts, use_start_tls);
if (!subreq) {
talloc_zfree(req);
return NULL;
@@ -193,8 +193,7 @@ static void sdap_id_anon_bind_done(struct tevent_req *subreq)
tevent_req_done(req);
}
-static int sdap_id_connect_recv(struct tevent_req *req,
- TALLOC_CTX *memctx, struct sdap_handle **sh)
+static int sdap_id_connect_recv(struct tevent_req *req)
{
struct sdap_id_connect_state *state = tevent_req_data(req,
struct sdap_id_connect_state);
@@ -206,8 +205,8 @@ static int sdap_id_connect_recv(struct tevent_req *req,
return EIO;
}
- *sh = talloc_steal(memctx, state->sh);
- if (!*sh) {
+ state->ctx->gsh = talloc_steal(state->ctx, state->sh);
+ if (!state->ctx->gsh) {
return ENOMEM;
}
return EOK;
@@ -283,7 +282,7 @@ static struct tevent_req *users_get_send(TALLOC_CTX *memctx,
/* FIXME: add option to decide if tls should be used
* or SASL/GSSAPI, etc ... */
- subreq = sdap_id_connect_send(state, ev, ctx->opts, false);
+ subreq = sdap_id_connect_send(state, ev, ctx, false);
if (!subreq) {
ret = ENOMEM;
goto fail;
@@ -320,7 +319,7 @@ static void users_get_connect_done(struct tevent_req *subreq)
struct users_get_state);
int ret;
- ret = sdap_id_connect_recv(subreq, state->ctx, &state->ctx->gsh);
+ ret = sdap_id_connect_recv(subreq);
talloc_zfree(subreq);
if (ret) {
tevent_req_error(req, ret);
@@ -440,7 +439,7 @@ static struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
/* FIXME: add option to decide if tls should be used
* or SASL/GSSAPI, etc ... */
- subreq = sdap_id_connect_send(state, ev, ctx->opts, false);
+ subreq = sdap_id_connect_send(state, ev, ctx, false);
if (!subreq) {
ret = ENOMEM;
goto fail;
@@ -477,7 +476,7 @@ static void groups_get_connect_done(struct tevent_req *subreq)
struct users_get_state);
int ret;
- ret = sdap_id_connect_recv(subreq, state->ctx, &state->ctx->gsh);
+ ret = sdap_id_connect_recv(subreq);
talloc_zfree(subreq);
if (ret) {
tevent_req_error(req, ret);
@@ -572,7 +571,7 @@ static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
/* FIXME: add option to decide if tls should be used
* or SASL/GSSAPI, etc ... */
- subreq = sdap_id_connect_send(state, ev, ctx->opts, false);
+ subreq = sdap_id_connect_send(state, ev, ctx, false);
if (!subreq) {
ret = ENOMEM;
goto fail;
@@ -609,7 +608,7 @@ static void groups_by_user_connect_done(struct tevent_req *subreq)
struct groups_by_user_state);
int ret;
- ret = sdap_id_connect_recv(subreq, state->ctx, &state->ctx->gsh);
+ ret = sdap_id_connect_recv(subreq);
talloc_zfree(subreq);
if (ret) {
tevent_req_error(req, ret);
diff --git a/server/providers/ldap/sdap.h b/server/providers/ldap/sdap.h
index 85b17515..8466473e 100644
--- a/server/providers/ldap/sdap.h
+++ b/server/providers/ldap/sdap.h
@@ -23,10 +23,32 @@
#include "db/sysdb.h"
#include <ldap.h>
+struct sdap_msg {
+ LDAPMessage *msg;
+};
+
+typedef void (sdap_op_callback_t)(void *, int, struct sdap_msg *);
+
+struct sdap_handle;
+
+struct sdap_op {
+ struct sdap_op *prev, *next;
+ struct sdap_handle *sh;
+
+ int msgid;
+ bool done;
+
+ sdap_op_callback_t *callback;
+ void *data;
+};
+
struct sdap_handle {
LDAP *ldap;
bool connected;
- int fd;
+
+ struct tevent_fd *fde;
+
+ struct sdap_op *ops;
};
enum sdap_result {
@@ -39,10 +61,6 @@ enum sdap_result {
SDAP_AUTH_FAILED
};
-struct sdap_msg {
- LDAPMessage *msg;
-};
-
#define SDAP_URI 0
#define SDAP_DEFAULT_BIND_DN 1
#define SDAP_DEFAULT_AUTHTOK_TYPE 2
diff --git a/server/providers/ldap/sdap_async.c b/server/providers/ldap/sdap_async.c
index b795e83d..57234e38 100644
--- a/server/providers/ldap/sdap_async.c
+++ b/server/providers/ldap/sdap_async.c
@@ -45,17 +45,8 @@ static int sdap_msg_attach(TALLOC_CTX *memctx, LDAPMessage *msg)
/* ==sdap-hanlde-utility-functions======================================== */
-static int sdap_handle_destructor(void *mem)
-{
- struct sdap_handle *h = talloc_get_type(mem, struct sdap_handle);
- if (h->connected) {
- ldap_unbind_ext(h->ldap, NULL, NULL);
- h->connected = false;
- h->ldap = NULL;
- h->fd = -1;
- }
- return 0;
-}
+static inline void sdap_handle_release(struct sdap_handle *sh);
+static int sdap_handle_destructor(void *mem);
static struct sdap_handle *sdap_handle_create(TALLOC_CTX *memctx)
{
@@ -64,13 +55,38 @@ static struct sdap_handle *sdap_handle_create(TALLOC_CTX *memctx)
sh = talloc_zero(memctx, struct sdap_handle);
if (!sh) return NULL;
- sh->fd = -1;
-
talloc_set_destructor((TALLOC_CTX *)sh, sdap_handle_destructor);
return sh;
}
+static int sdap_handle_destructor(void *mem)
+{
+ struct sdap_handle *sh = talloc_get_type(mem, struct sdap_handle);
+
+ sdap_handle_release(sh);
+
+ return 0;
+}
+
+static inline void sdap_handle_release(struct sdap_handle *sh)
+{
+ if (sh->connected) {
+ struct sdap_op *op;
+
+ while (sh->ops) {
+ op = sh->ops;
+ op->callback(op->data, EIO, NULL);
+ talloc_free(op);
+ }
+
+ talloc_zfree(sh->fde);
+ ldap_unbind_ext(sh->ldap, NULL, NULL);
+ sh->connected = false;
+ sh->ldap = NULL;
+ }
+}
+
static int get_fd_from_ldap(LDAP *ldap, int *fd)
{
int ret;
@@ -85,81 +101,203 @@ static int get_fd_from_ldap(LDAP *ldap, int *fd)
return EOK;
}
-static bool valid_handle(struct sdap_handle *sh)
+/* ==Parse-Results-And-Handle-Disconnections============================== */
+
+static void sdap_process_message(struct sdap_handle *sh, LDAPMessage *msg)
{
- if (!sh) return false;
- if (sh->ldap) return true;
- return false;
-}
+ struct sdap_msg *reply = NULL;
+ struct sdap_op *op;
+ int msgid;
+ int msgtype;
+ int ret;
-/* ==Parse-Results-And-Handle-Disconnections============================== */
+ msgid = ldap_msgid(msg);
+ if (msgid == -1) {
+ DEBUG(2, ("can't fire callback, message id invalid!\n"));
+ ldap_msgfree(msg);
+ return;
+ }
-static enum sdap_result sdap_check_result(struct sdap_handle *sh,
- int msgid, bool wait_all,
- LDAPMessage **msg, int *restype)
+ for (op = sh->ops; op; op = op->next) {
+ if (op->msgid == msgid && !op->done) {
+ msgtype = ldap_msgtype(msg);
+
+ switch (msgtype) {
+ case LDAP_RES_SEARCH_ENTRY:
+ case LDAP_RES_SEARCH_REFERENCE:
+ /* more ops to come with this msgid */
+ ret = EOK;
+ break;
+
+ case LDAP_RES_BIND:
+ case LDAP_RES_SEARCH_RESULT:
+ case LDAP_RES_MODIFY:
+ case LDAP_RES_ADD:
+ case LDAP_RES_DELETE:
+ case LDAP_RES_MODDN:
+ case LDAP_RES_COMPARE:
+ case LDAP_RES_EXTENDED:
+ case LDAP_RES_INTERMEDIATE:
+ /* no more results expected with this msgid */
+ op->done = true;
+ ret = EOK;
+ break;
+
+ default:
+ /* unkwon msg type ?? */
+ DEBUG(1, ("Couldn't figure out the msg type! [%0x]\n",
+ msgtype));
+ ret = EIO;
+ }
+
+ if (ret == EOK) {
+ reply = talloc(op, struct sdap_msg);
+ if (!reply) {
+ ldap_msgfree(msg);
+ ret = ENOMEM;
+ } else {
+ reply->msg = msg;
+ ret = sdap_msg_attach(reply, msg);
+ if (ret != EOK) {
+ ldap_msgfree(msg);
+ talloc_zfree(reply);
+ }
+ }
+ }
+
+ op->callback(op->data, ret, reply);
+
+ break;
+ }
+ }
+
+ if (op == NULL) {
+ DEBUG(2, ("Unmatched msgid, discarding message (type: %0x)\n",
+ ldap_msgtype(msg)));
+ return;
+ }
+}
+
+static void sdap_ldap_results(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags, void *pvt)
{
+ struct sdap_handle *sh = talloc_get_type(pvt, struct sdap_handle);
struct timeval no_timeout = {0, 0};
+ LDAPMessage *msg;
int ret;
- ret = ldap_result(sh->ldap, msgid, wait_all, &no_timeout, msg);
- if (ret == 0) {
- DEBUG(8, ("ldap result not ready yet (%d)\n", msgid));
- /* retry */
- return SDAP_RETRY;
- }
- if (ret == -1) {
- DEBUG(2, ("ldap result not available (%d)\n", msgid));
+ while (1) {
+ if (!sh->connected) {
+ DEBUG(2, ("FDE fired but LDAP connection is not connected!\n"));
+ sdap_handle_release(sh);
+ return;
+ }
- /* Fatal error returned, kill the connection, and reset the handle */
- ldap_unbind_ext(sh->ldap, NULL, NULL);
- sh->connected = false;
- sh->ldap = NULL;
- sh->fd = -1;
+ ret = ldap_result(sh->ldap, LDAP_RES_ANY, 0, &no_timeout, &msg);
+ if (ret == 0) {
+ DEBUG(6, ("FDE fired but ldap_result found nothing!\n"));
+ return;
+ }
+
+ if (ret == -1) {
+ DEBUG(4, ("ldap_result gave -1, something bad happend!\n"));
- return SDAP_ERROR;
+ sdap_handle_release(sh);
+ return;
+ }
+
+ sdap_process_message(sh, msg);
}
- DEBUG(8, ("ldap result returned %d\n", ret));
+}
+
+static int sdap_install_ldap_callbacks(struct sdap_handle *sh,
+ struct tevent_context *ev)
+{
+ int fd;
+ int ret;
+
+ ret = get_fd_from_ldap(sh->ldap, &fd);
+ if (ret) return ret;
- *restype = ret;
- return SDAP_SUCCESS;
+ sh->fde = tevent_add_fd(ev, sh, fd, TEVENT_FD_READ, sdap_ldap_results, sh);
+ if (!sh->fde) return ENOMEM;
+
+ return EOK;
}
+
/* ==LDAP-Operations-Helpers============================================== */
-struct ldap_operation_destructor_state {
- struct sdap_handle *sh;
- int msgid;
-};
+static int sdap_op_destructor(void *mem)
+{
+ struct sdap_op *op = (struct sdap_op *)mem;
+
+ DLIST_REMOVE(op->sh->ops, op);
+
+ if (op->done) return 0;
+
+ /* we don't check the result here, if a message was really abandoned,
+ * hopefully the server will get an abandon.
+ * If the operation was already fully completed, this is going to be
+ * just a noop */
+ ldap_abandon_ext(op->sh->ldap, op->msgid, NULL, NULL);
+
+ return 0;
+}
-static int ldap_operation_destructor(void *mem)
+static void sdap_op_timeout(struct tevent_req *req)
{
- struct ldap_operation_destructor_state *state =
- (struct ldap_operation_destructor_state *)mem;
+ struct sdap_op *op = tevent_req_callback_data(req, struct sdap_op);
- if (valid_handle(state->sh)) {
- /* we don't check the result here, if a message was really abandoned,
- * hopefully the server will get an abandon.
- * If the operation was already fully completed, this is going to be
- * just a noop */
- ldap_abandon_ext(state->sh->ldap, state->msgid, NULL, NULL);
+ /* should never happen, but just in case */
+ if (op->done) {
+ DEBUG(2, ("Timeout happened after op was finished !?\n"));
+ return;
}
- return 0;
+ /* signal the caller that we have a timeout */
+ op->callback(op->data, ETIME, NULL);
+
+ /* send back to the server an abandon (see destructor) and free the op */
+ talloc_free(op);
}
-static int set_ldap_operation_destructor(TALLOC_CTX *parent,
- struct sdap_handle *sh, int msgid)
+static int sdap_op_add(TALLOC_CTX *memctx, struct tevent_context *ev,
+ struct sdap_handle *sh, int msgid,
+ sdap_op_callback_t *callback, void *data,
+ int timeout)
{
- struct ldap_operation_destructor_state *state;
+ struct sdap_op *op;
- state = talloc(parent, struct ldap_operation_destructor_state);
- if (!state) return ENOMEM;
+ op = talloc_zero(memctx, struct sdap_op);
+ if (!op) return ENOMEM;
-/* TODO: should we talloc_reference sdap_handle here ? */
- state->sh = sh;
- state->msgid = msgid;
+ op->sh = sh;
+ op->msgid = msgid;
+ op->callback = callback;
+ op->data = data;
+
+ /* check if we need to set a timeout */
+ if (timeout) {
+ struct tevent_req *req;
+ struct timeval tv;
+
+ tv = tevent_timeval_current();
+ tv = tevent_timeval_add(&tv, timeout, 0);
+
+ /* allocate on op, so when it get freed the timeout is removed */
+ req = tevent_wakeup_send(op, ev, tv);
+ if (!req) {
+ talloc_zfree(op);
+ return ENOMEM;
+ }
+ tevent_req_set_callback(req, sdap_op_timeout, op);
+ }
- talloc_set_destructor((TALLOC_CTX *)state, ldap_operation_destructor);
+ DLIST_ADD(sh->ops, op);
+
+ talloc_set_destructor((TALLOC_CTX *)op, sdap_op_destructor);
return EOK;
}
@@ -167,6 +305,7 @@ static int set_ldap_operation_destructor(TALLOC_CTX *parent,
/* ==Connect-to-LDAP-Server=============================================== */
struct sdap_connect_state {
+ struct tevent_context *ev;
struct sdap_options *opts;
struct sdap_handle *sh;
@@ -176,9 +315,7 @@ struct sdap_connect_state {
int result;
};
-static void sdap_connect_done(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *pvt);
+static void sdap_connect_done(void *pvt, int error, struct sdap_msg *reply);
struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
@@ -187,10 +324,10 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
{
struct tevent_req *req;
struct sdap_connect_state *state;
- struct tevent_fd *fde;
struct timeval tv;
int ver;
- int ret;
+ int lret;
+ int ret = EOK;
req = tevent_req_create(memctx, &state, struct sdap_connect_state);
if (!req) return NULL;
@@ -201,6 +338,7 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
return NULL;
}
+ state->ev = ev;
state->opts = opts;
state->sh = sdap_handle_create(state);
if (!state->sh) {
@@ -208,16 +346,16 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
return NULL;
}
/* Initialize LDAP handler */
- ret = ldap_initialize(&state->sh->ldap, opts->basic[SDAP_URI].value);
- if (ret != LDAP_SUCCESS) {
+ lret = ldap_initialize(&state->sh->ldap, opts->basic[SDAP_URI].value);
+ if (lret != LDAP_SUCCESS) {
DEBUG(1, ("ldap_initialize failed: %s\n", ldap_err2string(ret)));
goto fail;
}
/* Force ldap version to 3 */
ver = LDAP_VERSION3;
- ret = ldap_set_option(state->sh->ldap, LDAP_OPT_PROTOCOL_VERSION, &ver);
- if (ret != LDAP_OPT_SUCCESS) {
+ lret = ldap_set_option(state->sh->ldap, LDAP_OPT_PROTOCOL_VERSION, &ver);
+ if (lret != LDAP_OPT_SUCCESS) {
DEBUG(1, ("Failed to set ldap version to 3\n"));
goto fail;
}
@@ -225,8 +363,8 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
/* Set Network Timeout */
tv.tv_sec = opts->network_timeout;
tv.tv_usec = 0;
- ret = ldap_set_option(state->sh->ldap, LDAP_OPT_NETWORK_TIMEOUT, &tv);
- if (ret != LDAP_OPT_SUCCESS) {
+ lret = ldap_set_option(state->sh->ldap, LDAP_OPT_NETWORK_TIMEOUT, &tv);
+ if (lret != LDAP_OPT_SUCCESS) {
DEBUG(1, ("Failed to set network timeout to %d\n",
opts->network_timeout));
goto fail;
@@ -235,8 +373,8 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
/* Set Default Timeout */
tv.tv_sec = opts->opt_timeout;
tv.tv_usec = 0;
- ret = ldap_set_option(state->sh->ldap, LDAP_OPT_TIMEOUT, &tv);
- if (ret != LDAP_OPT_SUCCESS) {
+ lret = ldap_set_option(state->sh->ldap, LDAP_OPT_TIMEOUT, &tv);
+ if (lret != LDAP_OPT_SUCCESS) {
DEBUG(1, ("Failed to set default timeout to %d\n",
opts->opt_timeout));
goto fail;
@@ -251,61 +389,54 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
DEBUG(4, ("Executing START TLS\n"));
- ret = ldap_start_tls(state->sh->ldap, NULL, NULL, &state->msgid);
- if (ret != LDAP_SUCCESS) {
+ lret = ldap_start_tls(state->sh->ldap, NULL, NULL, &state->msgid);
+ if (lret != LDAP_SUCCESS) {
DEBUG(3, ("ldap_start_tls failed: [%s]", ldap_err2string(ret)));
goto fail;
}
state->sh->connected = true;
- ret = get_fd_from_ldap(state->sh->ldap, &state->sh->fd);
+ ret = sdap_install_ldap_callbacks(state->sh, state->ev);
if (ret) goto fail;
- fde = tevent_add_fd(ev, state,
- state->sh->fd, TEVENT_FD_READ,
- sdap_connect_done, req);
- if (!fde) {
- DEBUG(1, ("Failed to set up fd event!\n"));
+ /* FIXME: get timeouts from configuration, for now 5 secs. */
+ ret = sdap_op_add(state, ev, state->sh, state->msgid,
+ sdap_connect_done, req, 5);
+ if (ret) {
+ DEBUG(1, ("Failed to set up operation!\n"));
goto fail;
}
return req;
fail:
- if (ret == LDAP_SERVER_DOWN) {
- tevent_req_error(req, EAGAIN);
+ if (ret) {
+ tevent_req_error(req, ret);
} else {
- tevent_req_error(req, EIO);
+ if (lret == LDAP_SERVER_DOWN) {
+ tevent_req_error(req, EAGAIN);
+ } else {
+ tevent_req_error(req, EIO);
+ }
}
tevent_req_post(req, ev);
return req;
}
-static void sdap_connect_done(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *pvt)
+static void sdap_connect_done(void *pvt, int error, struct sdap_msg *reply)
{
struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
struct sdap_connect_state *state = tevent_req_data(req,
struct sdap_connect_state);
- enum sdap_result res;
char *errmsg;
- int restype;
int ret;
- res = sdap_check_result(state->sh, state->msgid, true,
- &state->reply->msg, &restype);
- if (res != SDAP_SUCCESS) {
- if (res != SDAP_RETRY) {
- tevent_req_error(req, EIO);
- }
+ if (error) {
+ tevent_req_error(req, error);
return;
}
- ret = sdap_msg_attach(state->reply, state->reply->msg);
- if (ret) {
- DEBUG(1, ("Error appending memory: %s(%d)\n", strerror(ret), ret));
- }
+ state->reply = talloc_steal(state, reply);
ret = ldap_parse_result(state->sh->ldap, state->reply->msg,
&state->result, NULL, &errmsg, NULL, NULL, 0);
@@ -341,7 +472,7 @@ int sdap_connect_recv(struct tevent_req *req,
if (tevent_req_is_error(req, &tstate, &err)) {
/* if tstate shows in progress, it is because
- * we did not asq to perform tls, just pretend all is fine */
+ * we did not ask to perform tls, just pretend all is fine */
if (tstate != TEVENT_REQ_IN_PROGRESS) {
return err;
}
@@ -357,6 +488,7 @@ int sdap_connect_recv(struct tevent_req *req,
/* ==Simple-Bind========================================================== */
struct simple_bind_state {
+ struct tevent_context *ev;
struct sdap_handle *sh;
const char *user_dn;
struct berval *pw;
@@ -366,9 +498,7 @@ struct simple_bind_state {
int result;
};
-static void simple_bind_done(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *pvt);
+static void simple_bind_done(void *pvt, int error, struct sdap_msg *reply);
static struct tevent_req *simple_bind_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
@@ -378,8 +508,7 @@ static struct tevent_req *simple_bind_send(TALLOC_CTX *memctx,
{
struct tevent_req *req;
struct simple_bind_state *state;
- struct tevent_fd *fde;
- int ret;
+ int ret = EOK;
req = tevent_req_create(memctx, &state, struct simple_bind_state);
if (!req) return NULL;
@@ -390,6 +519,7 @@ static struct tevent_req *simple_bind_send(TALLOC_CTX *memctx,
return NULL;
}
+ state->ev = ev;
state->sh = sh;
state->user_dn = user_dn;
state->pw = pw;
@@ -406,16 +536,18 @@ static struct tevent_req *simple_bind_send(TALLOC_CTX *memctx,
if (!sh->connected) {
sh->connected = true;
- ret = get_fd_from_ldap(sh->ldap, &sh->fd);
+ ret = sdap_install_ldap_callbacks(sh, ev);
if (ret) goto fail;
}
- fde = tevent_add_fd(ev, state,
- sh->fd, TEVENT_FD_READ,
- simple_bind_done, req);
- if (!fde) {
- talloc_zfree(req);
+ /* FIXME: get timeouts from configuration, for now 5 secs. */
+ ret = sdap_op_add(state, ev, sh, state->msgid,
+ simple_bind_done, req, 5);
+ if (ret) {
+ DEBUG(1, ("Failed to set up operation!\n"));
+ goto fail;
}
+
return req;
fail:
@@ -428,31 +560,20 @@ fail:
return req;
}
-static void simple_bind_done(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *pvt)
+static void simple_bind_done(void *pvt, int error, struct sdap_msg *reply)
{
struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
struct simple_bind_state *state = tevent_req_data(req,
struct simple_bind_state);
- enum sdap_result res;
char *errmsg;
- int restype;
int ret;
- res = sdap_check_result(state->sh, state->msgid, true,
- &state->reply->msg, &restype);
- if (res != SDAP_SUCCESS) {
- if (res != SDAP_RETRY) {
- tevent_req_error(req, EIO);
- }
+ if (error) {
+ tevent_req_error(req, error);
return;
}
- ret = sdap_msg_attach(state->reply, state->reply->msg);
- if (ret) {
- DEBUG(1, ("Error appending memory: %s(%d)\n", strerror(ret), ret));
- }
+ state->reply = talloc_steal(state, reply);
ret = ldap_parse_result(state->sh->ldap, state->reply->msg,
&state->result, NULL, &errmsg, NULL, NULL, 0);
@@ -861,18 +982,17 @@ struct sdap_get_users_state {
struct tevent_context *ev;
struct sdap_options *opts;
struct sdap_handle *sh;
-
struct sss_domain_info *dom;
- struct sysdb_handle *handle;
+ const char **attrs;
+ const char *filter;
- struct tevent_fd *fde;
+ struct sysdb_handle *handle;
int msgid;
};
static void sdap_get_users_transaction(struct tevent_req *subreq);
-static void sdap_get_users_done(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *pvt);
+static void sdap_get_users_done(void *pvt, int error,
+ struct sdap_msg *reply);
static void sdap_get_users_save_done(struct tevent_req *subreq);
struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx,
@@ -886,7 +1006,6 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx,
{
struct tevent_req *req, *subreq;
struct sdap_get_users_state *state;
- int ret;
req = tevent_req_create(memctx, &state, struct sdap_get_users_state);
if (!req) return NULL;
@@ -895,35 +1014,14 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx,
state->opts = opts;
state->dom = dom;
state->sh = sh;
-
- DEBUG(5, ("calling ldap_search_ext with [%s].\n", filter));
-
- ret = ldap_search_ext(state->sh->ldap,
- opts->basic[SDAP_USER_SEARCH_BASE].value,
- LDAP_SCOPE_SUBTREE, filter, discard_const(attrs),
- false, NULL, NULL, NULL, 0, &state->msgid);
- if (ret != LDAP_SUCCESS) {
- DEBUG(3, ("ldap_search_ext failed: %s\n", ldap_err2string(ret)));
- goto fail;
- }
- DEBUG(8, ("ldap_search_ext called, msgid = %d\n", state->msgid));
-
- ret = set_ldap_operation_destructor(state, sh, state->msgid);
- if (ret) goto fail;
+ state->filter = filter;
+ state->attrs = attrs;
subreq = sysdb_transaction_send(state, state->ev, sysdb);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
+ if (!subreq) return NULL;
tevent_req_set_callback(subreq, sdap_get_users_transaction, req);
return req;
-
-fail:
- tevent_req_error(req, EIO);
- tevent_req_post(req, ev);
- return req;
}
static void sdap_get_users_transaction(struct tevent_req *subreq)
@@ -932,7 +1030,7 @@ static void sdap_get_users_transaction(struct tevent_req *subreq)
struct tevent_req);
struct sdap_get_users_state *state = tevent_req_data(req,
struct sdap_get_users_state);
- int ret;
+ int lret, ret;
ret = sysdb_transaction_recv(subreq, state, &state->handle);
talloc_zfree(subreq);
@@ -941,76 +1039,55 @@ static void sdap_get_users_transaction(struct tevent_req *subreq)
return;
}
- state->fde = tevent_add_fd(state->ev, state,
- state->sh->fd, TEVENT_FD_READ,
- sdap_get_users_done, req);
- if (!state->fde) {
- DEBUG(1, ("Failed to set up fd event!\n"));
- tevent_req_error(req, ENOMEM);
+ DEBUG(5, ("calling ldap_search_ext with [%s].\n", state->filter));
+
+ lret = ldap_search_ext(state->sh->ldap,
+ state->opts->basic[SDAP_USER_SEARCH_BASE].value,
+ LDAP_SCOPE_SUBTREE, state->filter,
+ discard_const(state->attrs),
+ false, NULL, NULL, NULL, 0, &state->msgid);
+ if (lret != LDAP_SUCCESS) {
+ DEBUG(3, ("ldap_search_ext failed: %s\n", ldap_err2string(lret)));
+ tevent_req_error(req, EIO);
+ return;
+ }
+ DEBUG(8, ("ldap_search_ext called, msgid = %d\n", state->msgid));
+
+ /* FIXME: get timeouts from configuration, for now 10 minutes */
+ ret = sdap_op_add(state, state->ev, state->sh, state->msgid,
+ sdap_get_users_done, req, 600);
+ if (ret) {
+ DEBUG(1, ("Failed to set up operation!\n"));
+ tevent_req_error(req, ret);
}
}
-static void sdap_get_users_done(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *pvt)
+static void sdap_get_users_done(void *pvt, int error, struct sdap_msg *reply)
{
struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
struct sdap_get_users_state *state = tevent_req_data(req,
struct sdap_get_users_state);
struct tevent_req *subreq;
- LDAPMessage *msg = NULL;
- struct sdap_msg *reply;
- enum sdap_result res;
char *errmsg;
- int restype;
int result;
int ret;
- res = sdap_check_result(state->sh, state->msgid, false,
- &msg, &restype);
- if (res != SDAP_SUCCESS) {
- if (res != SDAP_RETRY) {
- tevent_req_error(req, EIO);
- return;
- }
-
- /* make sure fd is readable so we can fetch the next result */
- TEVENT_FD_READABLE(state->fde);
- return;
- }
-
- if (!msg) {
- tevent_req_error(req, EIO);
- return;
- }
-
- reply = talloc_zero(state, struct sdap_msg);
- if (!reply) {
- ldap_msgfree(msg);
- tevent_req_error(req, ENOMEM);
+ if (error) {
+ tevent_req_error(req, error);
return;
}
- reply->msg = msg;
- ret = sdap_msg_attach(reply, msg);
- if (ret) {
- DEBUG(1, ("Error appending memory: %s(%d)\n", strerror(ret), ret));
- tevent_req_error(req, EFAULT);
- return;
- }
-
- switch (restype) {
+ switch (ldap_msgtype(reply->msg)) {
case LDAP_RES_SEARCH_REFERENCE:
/* ignore references for now */
- ldap_msgfree(msg);
+ talloc_free(reply);
break;
case LDAP_RES_SEARCH_ENTRY:
/* FIXME: should we set a timeout tevent timed function ? */
- /* stop reading until operation is done */
- TEVENT_FD_NOT_READABLE(state->fde);
-
+ /* FIXME: use a queue of requests so they are performed one at
+ * a time (tevent_queue_*) */
subreq = sdap_save_user_send(state, state->ev, state->handle,
state->opts, state->dom,
state->sh, reply);
@@ -1018,11 +1095,11 @@ static void sdap_get_users_done(struct tevent_context *ev,
tevent_req_error(req, ENOMEM);
return;
}
+ tevent_req_set_callback(subreq, sdap_get_users_save_done, req);
/* attach reply to subreq,
* will not be needed anymore once subreq is done */
talloc_steal(subreq, reply);
- tevent_req_set_callback(subreq, sdap_get_users_save_done, req);
break;
case LDAP_RES_SEARCH_RESULT:
@@ -1056,18 +1133,10 @@ static void sdap_get_users_done(struct tevent_context *ev,
}
}
-static void sdap_fake_users_done(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt);
-
static void sdap_get_users_save_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
- struct sdap_get_users_state *state = tevent_req_data(req,
- struct sdap_get_users_state);
- struct timeval tv = { 0, 0 };
- struct tevent_timer *te;
int ret;
ret = sdap_save_user_recv(subreq);
@@ -1076,32 +1145,8 @@ static void sdap_get_users_save_done(struct tevent_req *subreq)
tevent_req_error(req, ret);
return;
}
-
- /* unfortunately LDAP libraries consume everything sitting on the wire but
- * do not give us a way to know if there is anything waiting to be read or
- * or not. So schedule a fake fde event and wake up ourselves again. If we
- * get a SDAP_RETRY it is fine. */
-
- te = tevent_add_timer(state->ev, state, tv,
- sdap_fake_users_done, req);
- if (!te) {
- tevent_req_error(req, ENOMEM);
- return;
- }
-}
-
-static void sdap_fake_users_done(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt)
-{
- struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
- struct sdap_get_users_state *state = tevent_req_data(req,
- struct sdap_get_users_state);
-
- sdap_get_users_done(state->ev, state->fde, 0, pvt);
}
-
int sdap_get_users_recv(struct tevent_req *req)
{
enum tevent_req_state tstate;
@@ -1121,18 +1166,17 @@ struct sdap_get_groups_state {
struct tevent_context *ev;
struct sdap_options *opts;
struct sdap_handle *sh;
-
struct sss_domain_info *dom;
- struct sysdb_handle *handle;
+ const char **attrs;
+ const char *filter;
- struct tevent_fd *fde;
+ struct sysdb_handle *handle;
int msgid;
};
static void sdap_get_groups_transaction(struct tevent_req *subreq);
-static void sdap_get_groups_done(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *pvt);
+static void sdap_get_groups_done(void *pvt, int error,
+ struct sdap_msg *reply);
static void sdap_get_groups_save_done(struct tevent_req *subreq);
struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
@@ -1146,7 +1190,6 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
{
struct tevent_req *req, *subreq;
struct sdap_get_groups_state *state;
- int ret;
req = tevent_req_create(memctx, &state, struct sdap_get_groups_state);
if (!req) return NULL;
@@ -1155,35 +1198,14 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
state->opts = opts;
state->dom = dom;
state->sh = sh;
-
- DEBUG(5, ("calling ldap_search_ext with [%s].\n", filter));
-
- ret = ldap_search_ext(state->sh->ldap,
- opts->basic[SDAP_GROUP_SEARCH_BASE].value,
- LDAP_SCOPE_SUBTREE, filter, discard_const(attrs),
- false, NULL, NULL, NULL, 0, &state->msgid);
- if (ret != LDAP_SUCCESS) {
- DEBUG(3, ("ldap_search_ext failed: %s\n", ldap_err2string(ret)));
- goto fail;
- }
- DEBUG(8, ("ldap_search_ext called, msgid = %d\n", state->msgid));
-
- ret = set_ldap_operation_destructor(state, sh, state->msgid);
- if (ret) goto fail;
+ state->filter = filter;
+ state->attrs = attrs;
subreq = sysdb_transaction_send(state, state->ev, sysdb);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
+ if (!subreq) return NULL;
tevent_req_set_callback(subreq, sdap_get_groups_transaction, req);
return req;
-
-fail:
- tevent_req_error(req, EIO);
- tevent_req_post(req, ev);
- return req;
}
static void sdap_get_groups_transaction(struct tevent_req *subreq)
@@ -1192,7 +1214,7 @@ static void sdap_get_groups_transaction(struct tevent_req *subreq)
struct tevent_req);
struct sdap_get_groups_state *state = tevent_req_data(req,
struct sdap_get_groups_state);
- int ret;
+ int ret, lret;
ret = sysdb_transaction_recv(subreq, state, &state->handle);
talloc_zfree(subreq);
@@ -1201,76 +1223,56 @@ static void sdap_get_groups_transaction(struct tevent_req *subreq)
return;
}
- state->fde = tevent_add_fd(state->ev, state,
- state->sh->fd, TEVENT_FD_READ,
- sdap_get_groups_done, req);
- if (!state->fde) {
- DEBUG(1, ("Failed to set up fd event!\n"));
- tevent_req_error(req, ENOMEM);
+ DEBUG(5, ("calling ldap_search_ext with [%s].\n", state->filter));
+
+ lret = ldap_search_ext(state->sh->ldap,
+ state->opts->basic[SDAP_GROUP_SEARCH_BASE].value,
+ LDAP_SCOPE_SUBTREE, state->filter,
+ discard_const(state->attrs),
+ false, NULL, NULL, NULL, 0, &state->msgid);
+ if (lret != LDAP_SUCCESS) {
+ DEBUG(3, ("ldap_search_ext failed: %s\n", ldap_err2string(lret)));
+ tevent_req_error(req, EIO);
+ return;
+ }
+ DEBUG(8, ("ldap_search_ext called, msgid = %d\n", state->msgid));
+
+ /* FIXME: get timeouts from configuration, for now 10 minutes */
+ ret = sdap_op_add(state, state->ev, state->sh, state->msgid,
+ sdap_get_groups_done, req, 600);
+ if (ret) {
+ DEBUG(1, ("Failed to set up operation!\n"));
+ tevent_req_error(req, ret);
}
}
-static void sdap_get_groups_done(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *pvt)
+static void sdap_get_groups_done(void *pvt, int error,
+ struct sdap_msg *reply)
{
struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
struct sdap_get_groups_state *state = tevent_req_data(req,
struct sdap_get_groups_state);
struct tevent_req *subreq;
- LDAPMessage *msg = NULL;
- struct sdap_msg *reply;
- enum sdap_result res;
char *errmsg;
- int restype;
int result;
int ret;
- res = sdap_check_result(state->sh, state->msgid, false,
- &msg, &restype);
- if (res != SDAP_SUCCESS) {
- if (res != SDAP_RETRY) {
- tevent_req_error(req, EIO);
- return;
- }
-
- /* make sure fd is readable so we can fetch the next result */
- TEVENT_FD_READABLE(state->fde);
+ if (error) {
+ tevent_req_error(req, error);
return;
}
- if (!msg) {
- tevent_req_error(req, EIO);
- return;
- }
-
- reply = talloc_zero(state, struct sdap_msg);
- if (!reply) {
- ldap_msgfree(msg);
- tevent_req_error(req, ENOMEM);
- return;
- }
-
- reply->msg = msg;
- ret = sdap_msg_attach(reply, msg);
- if (ret) {
- DEBUG(1, ("Error appending memory: %s(%d)\n", strerror(ret), ret));
- tevent_req_error(req, EFAULT);
- return;
- }
-
- switch (restype) {
+ switch (ldap_msgtype(reply->msg)) {
case LDAP_RES_SEARCH_REFERENCE:
/* ignore references for now */
- ldap_msgfree(msg);
+ talloc_free(reply);
break;
case LDAP_RES_SEARCH_ENTRY:
/* FIXME: should we set a timeout tevent timed function ? */
- /* stop reading until operation is done */
- TEVENT_FD_NOT_READABLE(state->fde);
-
+ /* FIXME: use a queue of requests so they are performed one at
+ * a time (tevent_queue_*) */
subreq = sdap_save_group_send(state, state->ev, state->handle,
state->opts, state->dom,
state->sh, reply);
@@ -1278,11 +1280,11 @@ static void sdap_get_groups_done(struct tevent_context *ev,
tevent_req_error(req, ENOMEM);
return;
}
+ tevent_req_set_callback(subreq, sdap_get_groups_save_done, req);
/* attach reply to subreq,
* will not be needed anymore once subreq is done */
talloc_steal(subreq, reply);
- tevent_req_set_callback(subreq, sdap_get_groups_save_done, req);
break;
case LDAP_RES_SEARCH_RESULT:
@@ -1316,18 +1318,10 @@ static void sdap_get_groups_done(struct tevent_context *ev,
}
}
-static void sdap_get_groups_fake_done(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt);
-
static void sdap_get_groups_save_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
- struct sdap_get_groups_state *state = tevent_req_data(req,
- struct sdap_get_groups_state);
- struct timeval tv = { 0, 0 };
- struct tevent_timer *te;
int ret;
ret = sdap_save_group_recv(subreq);
@@ -1336,32 +1330,8 @@ static void sdap_get_groups_save_done(struct tevent_req *subreq)
tevent_req_error(req, ret);
return;
}
-
- /* unfortunately LDAP libraries consume everything sitting on the wire but
- * do not give us a way to know if there is anything waiting to be read or
- * or not. So schedule a fake fde event and wake up ourselves again. If we
- * get a SDAP_RETRY it is fine. */
-
- te = tevent_add_timer(state->ev, state, tv,
- sdap_get_groups_fake_done, req);
- if (!te) {
- tevent_req_error(req, ENOMEM);
- return;
- }
}
-static void sdap_get_groups_fake_done(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt)
-{
- struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
- struct sdap_get_groups_state *state = tevent_req_data(req,
- struct sdap_get_groups_state);
-
- sdap_get_groups_done(state->ev, state->fde, 0, pvt);
-}
-
-
int sdap_get_groups_recv(struct tevent_req *req)
{
enum tevent_req_state tstate;
@@ -1386,16 +1356,15 @@ struct sdap_get_initgr_state {
const char *name;
const char **grp_attrs;
+ const char *filter;
+
struct sysdb_handle *handle;
- struct tevent_fd *fde;
int msgid;
};
static void sdap_get_initgr_process(struct tevent_req *subreq);
static void sdap_get_initgr_transaction(struct tevent_req *subreq);
-static void sdap_get_initgr_done(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *pvt);
+static void sdap_get_initgr_done(void *pvt, int error, struct sdap_msg *reply);
static void sdap_get_initgr_save_done(struct tevent_req *subreq);
struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
@@ -1475,7 +1444,6 @@ static void sdap_get_initgr_process(struct tevent_req *subreq)
struct sdap_get_initgr_state);
struct ldb_message *msg;
const char *user_dn;
- char *filter;
int ret;
switch (state->opts->schema_type) {
@@ -1487,15 +1455,10 @@ static void sdap_get_initgr_process(struct tevent_req *subreq)
}
talloc_zfree(subreq);
- filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
- state->opts->group_map[SDAP_AT_GROUP_MEMBER].name,
- state->name,
- state->opts->group_map[SDAP_OC_GROUP].name);
- if (!filter) {
- tevent_req_error(req, ENOENT);
- return;
- }
-
+ state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
+ state->opts->group_map[SDAP_AT_GROUP_MEMBER].name,
+ state->name,
+ state->opts->group_map[SDAP_OC_GROUP].name);
break;
case SDAP_SCHEMA_RFC2307BIS:
@@ -1513,17 +1476,12 @@ static void sdap_get_initgr_process(struct tevent_req *subreq)
return;
}
- filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
- state->opts->user_map[SDAP_AT_GROUP_MEMBER].name,
- user_dn,
- state->opts->user_map[SDAP_OC_GROUP].name);
- if (!filter) {
- tevent_req_error(req, ENOMEM);
- return;
- }
+ state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
+ state->opts->user_map[SDAP_AT_GROUP_MEMBER].name,
+ user_dn,
+ state->opts->user_map[SDAP_OC_GROUP].name);
talloc_free(msg);
-
break;
default:
@@ -1531,25 +1489,8 @@ static void sdap_get_initgr_process(struct tevent_req *subreq)
return;
}
- DEBUG(5, ("calling ldap_search_ext with filter:[%s].\n", filter));
-
-
- ret = ldap_search_ext(state->sh->ldap,
- state->opts->basic[SDAP_GROUP_SEARCH_BASE].value,
- LDAP_SCOPE_SUBTREE, filter,
- discard_const(state->grp_attrs),
- false, NULL, NULL, NULL, 0, &state->msgid);
- if (ret != LDAP_SUCCESS) {
- DEBUG(3, ("ldap_search_ext failed: %s\n", ldap_err2string(ret)));
- tevent_req_error(req, EIO);
- return;
- }
-
- DEBUG(8, ("ldap_search_ext called, msgid = %d\n", state->msgid));
-
- ret = set_ldap_operation_destructor(state, state->sh, state->msgid);
- if (ret) {
- tevent_req_error(req, ret);
+ if (!state->filter) {
+ tevent_req_error(req, ENOMEM);
return;
}
@@ -1567,7 +1508,7 @@ static void sdap_get_initgr_transaction(struct tevent_req *subreq)
struct tevent_req);
struct sdap_get_initgr_state *state = tevent_req_data(req,
struct sdap_get_initgr_state);
- int ret;
+ int ret, lret;
ret = sysdb_transaction_recv(subreq, state, &state->handle);
talloc_zfree(subreq);
@@ -1576,76 +1517,56 @@ static void sdap_get_initgr_transaction(struct tevent_req *subreq)
return;
}
- state->fde = tevent_add_fd(state->ev, state,
- state->sh->fd, TEVENT_FD_READ,
- sdap_get_initgr_done, req);
- if (!state->fde) {
- DEBUG(1, ("Failed to set up fd event!\n"));
- tevent_req_error(req, ENOMEM);
+ DEBUG(5, ("calling ldap_search_ext with filter:[%s].\n", state->filter));
+
+ lret = ldap_search_ext(state->sh->ldap,
+ state->opts->basic[SDAP_GROUP_SEARCH_BASE].value,
+ LDAP_SCOPE_SUBTREE, state->filter,
+ discard_const(state->grp_attrs),
+ false, NULL, NULL, NULL, 0, &state->msgid);
+ if (lret != LDAP_SUCCESS) {
+ DEBUG(3, ("ldap_search_ext failed: %s\n", ldap_err2string(lret)));
+ tevent_req_error(req, EIO);
+ return;
+ }
+
+ DEBUG(8, ("ldap_search_ext called, msgid = %d\n", state->msgid));
+
+ /* FIXME: get timeouts from configuration, for now 10 minutes */
+ ret = sdap_op_add(state, state->ev, state->sh, state->msgid,
+ sdap_get_initgr_done, req, 600);
+ if (ret) {
+ DEBUG(1, ("Failed to set up operation!\n"));
+ tevent_req_error(req, ret);
}
}
-static void sdap_get_initgr_done(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *pvt)
+static void sdap_get_initgr_done(void *pvt, int error, struct sdap_msg *reply)
{
struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
struct sdap_get_initgr_state *state = tevent_req_data(req,
struct sdap_get_initgr_state);
struct tevent_req *subreq;
- LDAPMessage *msg = NULL;
- struct sdap_msg *reply;
- enum sdap_result res;
char *errmsg;
- int restype;
int result;
int ret;
- res = sdap_check_result(state->sh, state->msgid, false,
- &msg, &restype);
- if (res != SDAP_SUCCESS) {
- if (res != SDAP_RETRY) {
- tevent_req_error(req, EIO);
- return;
- }
-
- /* make sure fd is readable so we can fetch the next result */
- TEVENT_FD_READABLE(state->fde);
- return;
- }
-
- if (!msg) {
- tevent_req_error(req, EIO);
- return;
- }
-
- reply = talloc_zero(state, struct sdap_msg);
- if (!reply) {
- ldap_msgfree(msg);
- tevent_req_error(req, ENOMEM);
- return;
- }
-
- reply->msg = msg;
- ret = sdap_msg_attach(reply, msg);
- if (ret) {
- DEBUG(1, ("Error appending memory: %s(%d)\n", strerror(ret), ret));
- tevent_req_error(req, EFAULT);
+ if (error) {
+ tevent_req_error(req, error);
return;
}
- switch (restype) {
+ switch (ldap_msgtype(reply->msg)) {
case LDAP_RES_SEARCH_REFERENCE:
/* ignore references for now */
- ldap_msgfree(msg);
+ talloc_free(reply);
break;
case LDAP_RES_SEARCH_ENTRY:
/* FIXME: should we set a timeout tevent timed function ? */
- /* stop reading until operation is done */
- TEVENT_FD_NOT_READABLE(state->fde);
-
+ /* FIXME: use a queue of requests so they are performed one at
+ * a time (tevent_queue_*) */
subreq = sdap_save_group_send(state, state->ev, state->handle,
state->opts, state->dom,
state->sh, reply);
@@ -1653,11 +1574,11 @@ static void sdap_get_initgr_done(struct tevent_context *ev,
tevent_req_error(req, ENOMEM);
return;
}
+ tevent_req_set_callback(subreq, sdap_get_initgr_save_done, req);
/* attach reply to subreq,
* will not be needed anymore once subreq is done */
talloc_steal(subreq, reply);
- tevent_req_set_callback(subreq, sdap_get_initgr_save_done, req);
break;
case LDAP_RES_SEARCH_RESULT:
@@ -1691,18 +1612,10 @@ static void sdap_get_initgr_done(struct tevent_context *ev,
}
}
-static void sdap_get_initgr_fake_done(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt);
-
static void sdap_get_initgr_save_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
- struct sdap_get_initgr_state *state = tevent_req_data(req,
- struct sdap_get_initgr_state);
- struct timeval tv = { 0, 0 };
- struct tevent_timer *te;
int ret;
ret = sdap_save_group_recv(subreq);
@@ -1711,32 +1624,8 @@ static void sdap_get_initgr_save_done(struct tevent_req *subreq)
tevent_req_error(req, ret);
return;
}
-
- /* unfortunately LDAP libraries consume everything sitting on the wire but
- * do not give us a way to know if there is anything waiting to be read or
- * or not. So schedule a fake fde event and wake up ourselves again. If we
- * get a SDAP_RETRY it is fine. */
-
- te = tevent_add_timer(state->ev, state, tv,
- sdap_get_initgr_fake_done, req);
- if (!te) {
- tevent_req_error(req, ENOMEM);
- return;
- }
-}
-
-static void sdap_get_initgr_fake_done(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt)
-{
- struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
- struct sdap_get_initgr_state *state = tevent_req_data(req,
- struct sdap_get_initgr_state);
-
- sdap_get_initgr_done(state->ev, state->fde, 0, pvt);
}
-
int sdap_get_initgr_recv(struct tevent_req *req)
{
enum tevent_req_state tstate;