From ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18 Mon Sep 17 00:00:00 2001 From: eindenbom Date: Fri, 2 Jul 2010 19:01:11 +0400 Subject: Use new LDAP connection framework in LDAP access backend. --- src/providers/ldap/sdap_access.c | 132 ++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 59 deletions(-) diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c index 8a156bc3f..7d7832ad4 100644 --- a/src/providers/ldap/sdap_access.c +++ b/src/providers/ldap/sdap_access.c @@ -90,6 +90,7 @@ struct sdap_access_req_ctx { struct tevent_context *ev; struct sdap_access_ctx *access_ctx; struct sdap_id_ctx *sdap_ctx; + struct sdap_id_op *sdap_op; struct sysdb_handle *handle; struct be_ctx *be_ctx; const char **attrs; @@ -98,6 +99,8 @@ struct sdap_access_req_ctx { char *basedn; }; +static int sdap_access_decide_offline(struct tevent_req *req); +static int sdap_access_retry(struct tevent_req *req); static void sdap_access_connect_done(struct tevent_req *subreq); static void sdap_access_get_access_done(struct tevent_req *req); static struct tevent_req *sdap_access_send(TALLOC_CTX *mem_ctx, @@ -109,7 +112,6 @@ static struct tevent_req *sdap_access_send(TALLOC_CTX *mem_ctx, errno_t ret; struct sdap_access_req_ctx *state; struct tevent_req *req; - struct tevent_req *subreq; struct ldb_result *res; const char *basedn; @@ -180,17 +182,7 @@ static struct tevent_req *sdap_access_send(TALLOC_CTX *mem_ctx, /* Ok, we have one result, check if we are online or offline */ if (be_is_offline(state->be_ctx)) { /* Ok, we're offline. Return from the cache */ - if (state->cached_access) { - DEBUG(6, ("Access granted by cached credentials\n")); - ret = EOK; - state->pam_status = PAM_SUCCESS; - goto finished; - } - - /* Access denied */ - DEBUG(6, ("Access denied by cached credentials\n")); - ret = EOK; - state->pam_status = PAM_PERM_DENIED; + ret = sdap_access_decide_offline(req); goto finished; } @@ -226,37 +218,17 @@ static struct tevent_req *sdap_access_send(TALLOC_CTX *mem_ctx, DEBUG(6, ("Checking filter against LDAP\n")); - /* Check whether we have an active LDAP connection */ - if (state->sdap_ctx->gsh == NULL || ! state->sdap_ctx->gsh->connected) { - subreq = sdap_cli_connect_send(state, state->ev, - state->sdap_ctx->opts, - state->sdap_ctx->be, - state->sdap_ctx->service, - NULL); - if (!subreq) { - DEBUG(1, ("sdap_cli_connect_send failed.\n")); - goto failed; - } - - tevent_req_set_callback(subreq, sdap_access_connect_done, req); - return req; + state->sdap_op = sdap_id_op_create(state, state->sdap_ctx->conn_cache); + if (!state->sdap_op) { + DEBUG(2, ("sdap_id_op_create failed\n")); + goto failed; } - /* Make the LDAP request */ - subreq = sdap_get_generic_send(state, - state->ev, - state->sdap_ctx->opts, - state->sdap_ctx->gsh, - state->basedn, LDAP_SCOPE_BASE, - state->filter, NULL, - NULL, 0); - if (subreq == NULL) { - DEBUG(1, ("Could not start LDAP communication\n")); + ret = sdap_access_retry(req); + if (ret != EOK) { goto failed; } - tevent_req_set_callback(subreq, sdap_access_get_access_done, req); - return req; failed: @@ -269,33 +241,61 @@ finished: return req; } +static int sdap_access_decide_offline(struct tevent_req *req) +{ + struct sdap_access_req_ctx *state = + tevent_req_data(req, struct sdap_access_req_ctx); + + if (state->cached_access) { + DEBUG(6, ("Access granted by cached credentials\n")); + state->pam_status = PAM_SUCCESS; + } else { + DEBUG(6, ("Access denied by cached credentials\n")); + state->pam_status = PAM_PERM_DENIED; + } + + return EOK; +} + +static int sdap_access_retry(struct tevent_req *req) +{ + struct sdap_access_req_ctx *state = + tevent_req_data(req, struct sdap_access_req_ctx); + struct tevent_req *subreq; + int ret; + + subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); + if (!subreq) { + DEBUG(2, ("sdap_id_op_connect_send failed: %d (%s)\n", ret, strerror(ret))); + return ret; + } + + tevent_req_set_callback(subreq, sdap_access_connect_done, req); + return EOK; +} + static void sdap_access_connect_done(struct tevent_req *subreq) { - errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_access_req_ctx *state = tevent_req_data(req, struct sdap_access_req_ctx); + int ret, dp_error; - ret = sdap_cli_connect_recv(subreq, state->sdap_ctx, - &state->sdap_ctx->gsh, NULL); + ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); + if (ret != EOK) { - /* Could not connect to LDAP. Mark as offline and return - * from cache. - */ - be_mark_offline(state->be_ctx); - if (state->cached_access) { - DEBUG(6, ("Access granted by cached credentials\n")); - state->pam_status = PAM_SUCCESS; - tevent_req_done(req); - return; + if (dp_error == DP_ERR_OFFLINE) { + ret = sdap_access_decide_offline(req); + if (ret == EOK) { + tevent_req_done(req); + return; + } } - /* Access denied */ - DEBUG(6, ("Access denied by cached credentials\n")); - state->pam_status = PAM_PERM_DENIED; - tevent_req_done(req); + tevent_req_error(req, ret); + return; } /* Connection to LDAP succeeded @@ -304,7 +304,7 @@ static void sdap_access_connect_done(struct tevent_req *subreq) subreq = sdap_get_generic_send(state, state->ev, state->sdap_ctx->opts, - state->sdap_ctx->gsh, + sdap_id_op_handle(state->sdap_op), state->basedn, LDAP_SCOPE_BASE, state->filter, NULL, @@ -321,7 +321,7 @@ static void sdap_access_connect_done(struct tevent_req *subreq) static void sdap_access_get_access_done(struct tevent_req *subreq) { - errno_t ret; + int ret, dp_error; size_t num_results; bool found = false; struct sysdb_attrs *attrs; @@ -333,10 +333,24 @@ static void sdap_access_get_access_done(struct tevent_req *subreq) ret = sdap_get_generic_recv(subreq, state, &num_results, &results); talloc_zfree(subreq); + + ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); if (ret != EOK) { - DEBUG(1, ("sdap_get_generic_send() returned error [%d][%s]", - ret, strerror(ret))); - state->pam_status = PAM_SYSTEM_ERR; + if (dp_error == DP_ERR_OK) { + /* retry */ + ret = sdap_access_retry(req); + if (ret == EOK) { + return; + } + state->pam_status = PAM_SYSTEM_ERR; + } else if (dp_error == DP_ERR_OFFLINE) { + ret = sdap_access_decide_offline(req); + } else { + DEBUG(1, ("sdap_get_generic_send() returned error [%d][%s]\n", + ret, strerror(ret))); + state->pam_status = PAM_SYSTEM_ERR; + } + goto done; } -- cgit