summaryrefslogtreecommitdiffstats
path: root/src/providers/ldap/ldap_auth.c
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2010-04-28 19:26:04 +0200
committerStephen Gallagher <sgallagh@redhat.com>2010-05-07 17:14:31 -0400
commit2d54b2a56b83315b3f89e082f8bf89fe8132a685 (patch)
tree2ce345f2fa83aa96ee9022316ad8e9503dd2cb5c /src/providers/ldap/ldap_auth.c
parenta4d8856edae99049133925610ae87c41e8a9c695 (diff)
downloadsssd-2d54b2a56b83315b3f89e082f8bf89fe8132a685.tar.gz
sssd-2d54b2a56b83315b3f89e082f8bf89fe8132a685.tar.xz
sssd-2d54b2a56b83315b3f89e082f8bf89fe8132a685.zip
Use all available servers in LDAP provider
Diffstat (limited to 'src/providers/ldap/ldap_auth.c')
-rw-r--r--src/providers/ldap/ldap_auth.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
index 95931ac9d..231ae2e97 100644
--- a/src/providers/ldap/ldap_auth.c
+++ b/src/providers/ldap/ldap_auth.c
@@ -433,6 +433,7 @@ struct auth_state {
struct fo_server *srv;
};
+static struct tevent_req *auth_get_server(struct tevent_req *req);
static void auth_resolve_done(struct tevent_req *subreq);
static void auth_connect_done(struct tevent_req *subreq);
static void auth_bind_user_done(struct tevent_req *subreq);
@@ -443,7 +444,7 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx,
const char *username,
struct dp_opt_blob password)
{
- struct tevent_req *req, *subreq;
+ struct tevent_req *req;
struct auth_state *state;
req = tevent_req_create(memctx, &state, struct auth_state);
@@ -455,10 +456,7 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx,
state->password = password;
state->srv = NULL;
- subreq = be_resolve_server_send(state, ev, ctx->be, ctx->service->name);
- if (!subreq) goto fail;
-
- tevent_req_set_callback(subreq, auth_resolve_done, req);
+ if (!auth_get_server(req)) goto fail;
return req;
@@ -467,6 +465,27 @@ fail:
return NULL;
}
+static struct tevent_req *auth_get_server(struct tevent_req *req)
+{
+ struct tevent_req *next_req;
+ struct auth_state *state = tevent_req_data(req,
+ struct auth_state);
+
+ /* NOTE: this call may cause service->uri to be refreshed
+ * with a new valid server. Do not use service->uri before */
+ next_req = be_resolve_server_send(state,
+ state->ev,
+ state->ctx->be,
+ state->ctx->service->name);
+ if (!next_req) {
+ DEBUG(1, ("be_resolve_server_send failed.\n"));
+ return NULL;
+ }
+
+ tevent_req_set_callback(next_req, auth_resolve_done, req);
+ return next_req;
+}
+
static void auth_resolve_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
@@ -478,7 +497,9 @@ static void auth_resolve_done(struct tevent_req *subreq)
ret = be_resolve_server_recv(subreq, &state->srv);
talloc_zfree(subreq);
if (ret) {
- tevent_req_error(req, ret);
+ /* all servers have been tried and none
+ * was found good, go offline */
+ tevent_req_error(req, EIO);
return;
}
@@ -507,6 +528,12 @@ static void auth_connect_done(struct tevent_req *subreq)
/* mark this server as bad if connection failed */
fo_set_port_status(state->srv, PORT_NOT_WORKING);
}
+ if (ret == ETIMEDOUT) {
+ if (auth_get_server(req) == NULL) {
+ tevent_req_error(req, ENOMEM);
+ }
+ return;
+ }
tevent_req_error(req, ret);
return;