summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/providers/ldap/ldap_common.h2
-rw-r--r--src/providers/ldap/ldap_id.c127
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)