diff options
-rw-r--r-- | src/providers/ldap/ldap_common.h | 2 | ||||
-rw-r--r-- | src/providers/ldap/ldap_id.c | 127 |
2 files changed, 91 insertions, 38 deletions
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h index 54cc7fe81..fd3bb7b91 100644 --- a/src/providers/ldap/ldap_common.h +++ b/src/providers/ldap/ldap_common.h @@ -108,7 +108,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, const char *name, int filter_type, int attrs_type); -int users_get_recv(struct tevent_req *req); +int users_get_recv(struct tevent_req *req, int *dp_error_out); struct tevent_req *groups_get_send(TALLOC_CTX *memctx, struct tevent_context *ev, diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index 84483da4f..962fc195e 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -36,6 +36,7 @@ struct users_get_state { struct tevent_context *ev; struct sdap_id_ctx *ctx; + struct sdap_id_op *op; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; @@ -44,8 +45,11 @@ struct users_get_state { char *filter; const char **attrs; + + int dp_error; }; +static int users_get_retry(struct tevent_req *req); static void users_get_connect_done(struct tevent_req *subreq); static void users_get_done(struct tevent_req *subreq); @@ -56,7 +60,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, int filter_type, int attrs_type) { - struct tevent_req *req, *subreq; + struct tevent_req *req; struct users_get_state *state; const char *attr_name; int ret; @@ -66,6 +70,15 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, state->ev = ev; state->ctx = ctx; + state->dp_error = DP_ERR_FATAL; + + state->op = sdap_id_op_create(state, state->ctx->conn_cache); + if (!state->op) { + DEBUG(2, ("sdap_id_op_create failed\n")); + ret = ENOMEM; + goto fail; + } + state->sysdb = ctx->be->sysdb; state->domain = state->ctx->be->domain; state->name = name; @@ -97,32 +110,10 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, SDAP_OPTS_USER, &state->attrs); if (ret != EOK) goto fail; - if (!sdap_connected(ctx)) { - - /* FIXME: add option to decide if tls should be used - * or SASL/GSSAPI, etc ... */ - subreq = sdap_cli_connect_send(state, ev, ctx->opts, - ctx->be, ctx->service, - &ctx->rootDSE); - if (!subreq) { - ret = ENOMEM; - goto fail; - } - - tevent_req_set_callback(subreq, users_get_connect_done, req); - - return req; - } - - subreq = sdap_get_users_send(state, state->ev, - state->domain, state->sysdb, - state->ctx->opts, state->ctx->gsh, - state->attrs, state->filter); - if (!subreq) { - ret = ENOMEM; + ret = users_get_retry(req); + if (ret != EOK) { goto fail; } - tevent_req_set_callback(subreq, users_get_done, req); return req; @@ -132,28 +123,44 @@ fail: return req; } +static int users_get_retry(struct tevent_req *req) +{ + struct users_get_state *state = tevent_req_data(req, + struct users_get_state); + struct tevent_req *subreq; + int ret = EOK; + + subreq = sdap_id_op_connect_send(state->op, state, &ret); + if (!subreq) { + return ret; + } + + tevent_req_set_callback(subreq, users_get_connect_done, req); + return EOK; +} + static void users_get_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct users_get_state *state = tevent_req_data(req, struct users_get_state); + int dp_error = DP_ERR_FATAL; int ret; - ret = sdap_cli_connect_recv(subreq, state->ctx, - &state->ctx->gsh, &state->ctx->rootDSE); + ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); - if (ret) { - if (ret == ENOTSUP) { - DEBUG(0, ("Authentication mechanism not Supported by server")); - } + + if (ret != EOK) { + state->dp_error = dp_error; tevent_req_error(req, ret); return; } subreq = sdap_get_users_send(state, state->ev, state->domain, state->sysdb, - state->ctx->opts, state->ctx->gsh, + state->ctx->opts, + sdap_id_op_handle(state->op), state->attrs, state->filter); if (!subreq) { tevent_req_error(req, ENOMEM); @@ -170,11 +177,26 @@ static void users_get_done(struct tevent_req *subreq) struct users_get_state); char *endptr; uid_t uid; + int dp_error = DP_ERR_FATAL; int ret; ret = sdap_get_users_recv(subreq, NULL, NULL); talloc_zfree(subreq); + + ret = sdap_id_op_done(state->op, ret, &dp_error); + if (dp_error == DP_ERR_OK && ret != EOK) { + /* retry */ + ret = users_get_retry(req); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + return; + } + if (ret && ret != ENOENT) { + state->dp_error = dp_error; tevent_req_error(req, ret); return; } @@ -218,17 +240,24 @@ static void users_get_done(struct tevent_req *subreq) } } + state->dp_error = DP_ERR_OK; tevent_req_done(req); } -int users_get_recv(struct tevent_req *req) +int users_get_recv(struct tevent_req *req, int *dp_error_out) { + struct users_get_state *state = tevent_req_data(req, + struct users_get_state); + + if (dp_error_out) { + *dp_error_out = state->dp_error; + } + TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } - /* =Groups-Related-Functions-(by-name,by-uid)============================= */ struct groups_get_state { @@ -718,15 +747,39 @@ static void sdap_account_info_common_done(int ret, struct be_req *breq, sdap_handler_done(breq, dp_err, ret, errstr); } +static void sdap_account_info_complete(struct be_req *breq, int dp_error, + int ret, const char *default_error_text) +{ + const char* error_text; + + if (dp_error == DP_ERR_OK) { + if (ret == EOK) { + error_text = NULL; + } else { + DEBUG(1, ("Bug: dp_error is OK on failed request")); + dp_error = DP_ERR_FATAL; + error_text = default_error_text; + } + } else if (dp_error == DP_ERR_OFFLINE) { + error_text = "Offline"; + } else if (dp_error == DP_ERR_FATAL && ret == ENOMEM) { + error_text = "Out of memory"; + } else { + error_text = default_error_text; + } + + sdap_handler_done(breq, dp_error, ret, error_text); +} + static void sdap_account_info_users_done(struct tevent_req *req) { struct be_req *breq = tevent_req_callback_data(req, struct be_req); - int ret; + int ret, dp_error; - ret = users_get_recv(req); + ret = users_get_recv(req, &dp_error); talloc_zfree(req); - sdap_account_info_common_done(ret, breq, "User lookup failed"); + sdap_account_info_complete(breq, dp_error, ret, "User lookup failed"); } static void sdap_account_info_groups_done(struct tevent_req *req) |