summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2012-04-20 11:08:39 +0200
committerStephen Gallagher <sgallagh@redhat.com>2012-04-20 12:29:03 -0400
commit7070641527c4bf94f77a3756ba24824cf664b959 (patch)
tree6044777f95949644b391b900467c6f1540cf6b0a
parent2b7349575770521243a34611e97d73790946a961 (diff)
downloadsssd-7070641527c4bf94f77a3756ba24824cf664b959.tar.gz
sssd-7070641527c4bf94f77a3756ba24824cf664b959.tar.xz
sssd-7070641527c4bf94f77a3756ba24824cf664b959.zip
Get the RootDSE after binding if not successfull before
https://fedorahosted.org/sssd/ticket/1258
-rw-r--r--src/providers/ldap/sdap_async_connection.c130
1 files changed, 104 insertions, 26 deletions
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index fac078c33..9e4d86aab 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -1149,6 +1149,7 @@ struct sdap_cli_connect_state {
struct be_ctx *be;
bool use_rootdse;
+ struct sysdb_attrs *rootdse;
struct sdap_handle *sh;
@@ -1165,10 +1166,12 @@ 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);
+static errno_t sdap_cli_use_rootdse(struct sdap_cli_connect_state *state);
static void sdap_cli_kinit_step(struct tevent_req *req);
static void sdap_cli_kinit_done(struct tevent_req *subreq);
static void sdap_cli_auth_step(struct tevent_req *req);
static void sdap_cli_auth_done(struct tevent_req *subreq);
+static void sdap_cli_rootdse_auth_done(struct tevent_req *subreq);
struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
@@ -1357,11 +1360,10 @@ static void sdap_cli_rootdse_done(struct tevent_req *subreq)
struct tevent_req);
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
- struct sysdb_attrs *rootdse;
const char *sasl_mech;
int ret;
- ret = sdap_get_rootdse_recv(subreq, state, &rootdse);
+ ret = sdap_get_rootdse_recv(subreq, state, &state->rootdse);
talloc_zfree(subreq);
if (ret) {
if (ret == ETIMEDOUT) { /* retry another server */
@@ -1379,39 +1381,20 @@ static void sdap_cli_rootdse_done(struct tevent_req *subreq)
* features requested by the config
* work properly.
*/
- state->use_rootdse = false;
- rootdse = NULL;
+ state->rootdse = NULL;
}
- if (state->use_rootdse) {
- /* save rootdse data about supported features */
- ret = sdap_set_rootdse_supported_lists(rootdse, state->sh);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- ret = sdap_set_config_options_with_rootdse(rootdse, state->opts);
- if (ret) {
- DEBUG(1, ("sdap_set_config_options_with_rootdse failed.\n"));
- tevent_req_error(req, ret);
- return;
- }
-
- }
- ret = sdap_get_server_opts_from_rootdse(state,
- state->service->uri, rootdse,
- state->opts, &state->srv_opts);
- if (ret) {
- DEBUG(1, ("sdap_get_server_opts_from_rootdse failed.\n"));
+ ret = sdap_cli_use_rootdse(state);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sdap_cli_use_rootdse failed\n"));
tevent_req_error(req, ret);
return;
}
sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH);
- if (state->do_auth && sasl_mech && state->use_rootdse) {
+ if (state->do_auth && sasl_mech && state->rootdse) {
/* check if server claims to support GSSAPI */
if (!sdap_is_sasl_mech_supported(state->sh, sasl_mech)) {
tevent_req_error(req, ENOTSUP);
@@ -1429,6 +1412,41 @@ static void sdap_cli_rootdse_done(struct tevent_req *subreq)
sdap_cli_auth_step(req);
}
+static errno_t sdap_cli_use_rootdse(struct sdap_cli_connect_state *state)
+{
+ errno_t ret;
+
+ if (state->rootdse) {
+ /* save rootdse data about supported features */
+ ret = sdap_set_rootdse_supported_lists(state->rootdse, state->sh);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("sdap_set_rootdse_supported_lists failed\n"));
+ return ret;
+ }
+
+ ret = sdap_set_config_options_with_rootdse(state->rootdse, state->opts);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("sdap_set_config_options_with_rootdse failed.\n"));
+ return ret;
+ }
+
+ }
+
+ ret = sdap_get_server_opts_from_rootdse(state,
+ state->service->uri,
+ state->rootdse,
+ state->opts, &state->srv_opts);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("sdap_get_server_opts_from_rootdse failed.\n"));
+ return ret;
+ }
+
+ return EOK;
+}
+
static void sdap_cli_kinit_step(struct tevent_req *req)
{
struct sdap_cli_connect_state *state = tevent_req_data(req,
@@ -1549,6 +1567,8 @@ static void sdap_cli_auth_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);
enum sdap_result result;
int ret;
@@ -1563,6 +1583,64 @@ static void sdap_cli_auth_done(struct tevent_req *subreq)
return;
}
+ if (state->use_rootdse && !state->rootdse) {
+ /* We weren't able to read rootDSE during unauthenticated bind.
+ * Let's try again now that we are authenticated */
+ subreq = sdap_get_rootdse_send(state, state->ev,
+ state->opts, state->sh);
+ if (!subreq) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+ tevent_req_set_callback(subreq, sdap_cli_rootdse_auth_done, req);
+ return;
+ }
+
+ tevent_req_done(req);
+}
+
+static void sdap_cli_rootdse_auth_done(struct tevent_req *subreq)
+{
+ errno_t ret;
+ 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);
+
+ ret = sdap_get_rootdse_recv(subreq, state, &state->rootdse);
+ talloc_zfree(subreq);
+ if (ret) {
+ if (ret == ETIMEDOUT) {
+ /* The server we authenticated against went down. Retry another
+ * one */
+ be_fo_set_port_status(state->be, state->srv, PORT_NOT_WORKING);
+ ret = sdap_cli_resolve_next(req);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ }
+ return;
+ }
+
+ /* RootDSE was not available on
+ * the server.
+ * Continue, and just assume that the
+ * features requested by the config
+ * work properly.
+ */
+ state->use_rootdse = false;
+ state->rootdse = NULL;
+ tevent_req_done(req);
+ return;
+ }
+
+ /* We were able to get rootDSE after authentication */
+ ret = sdap_cli_use_rootdse(state);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sdap_cli_use_rootdse failed\n"));
+ tevent_req_error(req, ret);
+ return;
+ }
+
tevent_req_done(req);
}