summaryrefslogtreecommitdiffstats
path: root/server/providers/ldap/sdap_async_connection.c
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2009-11-20 12:11:28 -0500
committerStephen Gallagher <sgallagh@redhat.com>2009-11-20 16:55:16 -0500
commite115c25af2df3549fb44b260e516d8c93d2adc8a (patch)
treeddae338c26e8fd39b29f4fb106fd831280ca23d5 /server/providers/ldap/sdap_async_connection.c
parent74bd0f69d2ff2da63949e7660aa2f48f06734b90 (diff)
downloadsssd-e115c25af2df3549fb44b260e516d8c93d2adc8a.tar.gz
sssd-e115c25af2df3549fb44b260e516d8c93d2adc8a.tar.xz
sssd-e115c25af2df3549fb44b260e516d8c93d2adc8a.zip
Add initial failover support for ldap and ipa
The retun values are still not directly used with ldap libraries that still do their own name resolution, but this patch introduces a very basic framework to have a multiple providers in one domain use and share a single failover service if they want to.
Diffstat (limited to 'server/providers/ldap/sdap_async_connection.c')
-rw-r--r--server/providers/ldap/sdap_async_connection.c67
1 files changed, 59 insertions, 8 deletions
diff --git a/server/providers/ldap/sdap_async_connection.c b/server/providers/ldap/sdap_async_connection.c
index 9f53ad6f0..a5e6ccfa9 100644
--- a/server/providers/ldap/sdap_async_connection.c
+++ b/server/providers/ldap/sdap_async_connection.c
@@ -46,6 +46,7 @@ static void sdap_connect_done(struct sdap_op *op,
struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
struct sdap_options *opts,
+ const char *uri,
bool use_start_tls)
{
struct tevent_req *req;
@@ -73,10 +74,9 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
return NULL;
}
/* Initialize LDAP handler */
- lret = ldap_initialize(&state->sh->ldap,
- dp_opt_get_string(opts->basic, SDAP_URI));
+ lret = ldap_initialize(&state->sh->ldap, uri);
if (lret != LDAP_SUCCESS) {
- DEBUG(1, ("ldap_initialize failed: %s\n", ldap_err2string(ret)));
+ DEBUG(1, ("ldap_initialize failed: %s\n", ldap_err2string(lret)));
goto fail;
}
@@ -871,12 +871,17 @@ int sdap_auth_recv(struct tevent_req *req, enum sdap_result *result)
struct sdap_cli_connect_state {
struct tevent_context *ev;
struct sdap_options *opts;
+ struct sdap_service *service;
- struct sysdb_attrs *rootdse;
bool use_rootdse;
+ struct sysdb_attrs *rootdse;
+
struct sdap_handle *sh;
+
+ struct fo_server *srv;
};
+static void sdap_cli_resolve_done(struct tevent_req *subreq);
static void sdap_cli_connect_done(struct tevent_req *subreq);
static void sdap_cli_rootdse_step(struct tevent_req *req);
static void sdap_cli_rootdse_done(struct tevent_req *subreq);
@@ -888,6 +893,8 @@ static void sdap_cli_auth_done(struct tevent_req *subreq);
struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
struct sdap_options *opts,
+ struct be_ctx *be,
+ struct sdap_service *service,
struct sysdb_attrs **rootdse)
{
struct tevent_req *req, *subreq;
@@ -898,6 +905,9 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
state->ev = ev;
state->opts = opts;
+ state->service = service;
+ state->srv = NULL;
+
if (rootdse) {
state->use_rootdse = true;
state->rootdse = *rootdse;
@@ -906,17 +916,46 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
state->rootdse = NULL;
}
- subreq = sdap_connect_send(state, ev, opts,
- dp_opt_get_bool(opts->basic, SDAP_ID_TLS));
+ /* NOTE: this call may cause service->uri to be refreshed
+ * with a new valid server. Do not use service->uri before */
+ subreq = be_resolve_server_send(state, ev, be, service->name);
if (!subreq) {
talloc_zfree(req);
return NULL;
}
- tevent_req_set_callback(subreq, sdap_cli_connect_done, req);
+ tevent_req_set_callback(subreq, sdap_cli_resolve_done, req);
return req;
}
+static void sdap_cli_resolve_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct sdap_cli_connect_state *state = tevent_req_data(req,
+ struct sdap_cli_connect_state);
+ int ret;
+
+ ret = be_resolve_server_recv(subreq, &state->srv);
+ talloc_zfree(subreq);
+ if (ret) {
+ /* all servers have been tried and none
+ * was found good, go offline */
+ tevent_req_error(req, EIO);
+ return;
+ }
+
+ subreq = sdap_connect_send(state, state->ev, state->opts,
+ state->service->uri,
+ dp_opt_get_bool(state->opts->basic,
+ SDAP_ID_TLS));
+ if (!subreq) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+ tevent_req_set_callback(subreq, sdap_cli_connect_done, req);
+}
+
static void sdap_cli_connect_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
@@ -1118,8 +1157,20 @@ int sdap_cli_connect_recv(struct tevent_req *req,
{
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
+ enum tevent_req_state tstate;
+ uint64_t err;
- TEVENT_REQ_RETURN_ON_ERROR(req);
+ if (tevent_req_is_error(req, &tstate, &err)) {
+ /* mark the server as bad if connection failed */
+ if (state->srv) {
+ fo_set_server_status(state->srv, SERVER_NOT_WORKING);
+ }
+
+ if (tstate == TEVENT_REQ_USER_ERROR) {
+ return err;
+ }
+ return EIO;
+ }
if (gsh) {
*gsh = talloc_steal(memctx, state->sh);