From 2d54b2a56b83315b3f89e082f8bf89fe8132a685 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 28 Apr 2010 19:26:04 +0200 Subject: Use all available servers in LDAP provider --- src/providers/ldap/ldap_auth.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'src/providers/ldap/ldap_auth.c') diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c index 95931ac9..231ae2e9 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; -- cgit