summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Cholasta <jcholast@redhat.com>2012-11-22 12:21:52 +0100
committerJakub Hrozek <jhrozek@redhat.com>2013-03-21 17:58:05 +0100
commit4709ff46db0dbe073aef061b796d2fd7adeaf18f (patch)
tree941e507ffdf6e6d0fef31a043a808c6a00d70029
parent6b0a7c72bb841d6885a620c68bd51d55109b66c7 (diff)
downloadsssd-4709ff46db0dbe073aef061b796d2fd7adeaf18f.tar.gz
sssd-4709ff46db0dbe073aef061b796d2fd7adeaf18f.tar.bz2
sssd-4709ff46db0dbe073aef061b796d2fd7adeaf18f.zip
LDAP: If deref search fails, try again without deref
https://fedorahosted.org/sssd/ticket/1660
-rw-r--r--src/providers/ipa/ipa_hosts.c6
-rw-r--r--src/providers/ldap/sdap.h1
-rw-r--r--src/providers/ldap/sdap_async.c21
-rw-r--r--src/providers/ldap/sdap_async_groups.c14
-rw-r--r--src/providers/ldap/sdap_async_initgroups.c12
5 files changed, 50 insertions, 4 deletions
diff --git a/src/providers/ipa/ipa_hosts.c b/src/providers/ipa/ipa_hosts.c
index 286e5e9a..1323cac6 100644
--- a/src/providers/ipa/ipa_hosts.c
+++ b/src/providers/ipa/ipa_hosts.c
@@ -254,6 +254,12 @@ ipa_host_info_done(struct tevent_req *subreq)
return;
}
+ if (!sdap_has_deref_support(state->sh, state->opts)) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Server does not support deref\n"));
+ tevent_req_error(req, EIO);
+ return;
+ }
+
subreq = sdap_deref_search_send(state, state->ev, state->opts, state->sh,
host_dn,
state->hostgroup_map[IPA_AT_HOSTGROUP_MEMBER_OF].name,
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 1235d1df..8dbf3849 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -78,6 +78,7 @@ struct sdap_handle {
/* Authentication ticket expiration time (if any) */
time_t expire_time;
ber_int_t page_size;
+ bool disable_deref;
struct sdap_fd_events *sdap_fd_events;
diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c
index 7ac32b95..afa2904f 100644
--- a/src/providers/ldap/sdap_async.c
+++ b/src/providers/ldap/sdap_async.c
@@ -1384,6 +1384,10 @@ static void sdap_get_generic_ext_done(struct sdap_op *op,
ldap_memfree(errmsg);
tevent_req_error(req, EIO);
return;
+ } else if (result == LDAP_UNAVAILABLE_CRITICAL_EXTENSION) {
+ ldap_memfree(errmsg);
+ tevent_req_error(req, ENOTSUP);
+ return;
} else if (result != LDAP_SUCCESS && result != LDAP_NO_SUCH_OBJECT) {
DEBUG(SSSDBG_OP_FAILURE,
("Unexpected result from ldap: %s(%d), %s\n",
@@ -2054,6 +2058,7 @@ enum sdap_deref_type {
};
struct sdap_deref_search_state {
+ struct sdap_handle *sh;
size_t reply_count;
struct sdap_deref_attrs **reply;
enum sdap_deref_type deref_type;
@@ -2080,6 +2085,7 @@ sdap_deref_search_send(TALLOC_CTX *memctx,
req = tevent_req_create(memctx, &state, struct sdap_deref_search_state);
if (!req) return NULL;
+ state->sh = sh;
state->reply_count = 0;
state->reply = NULL;
@@ -2144,7 +2150,16 @@ static void sdap_deref_search_done(struct tevent_req *subreq)
talloc_zfree(subreq);
if (ret != EOK) {
DEBUG(2, ("dereference processing failed [%d]: %s\n", ret, strerror(ret)));
- sss_log(SSS_LOG_WARNING, "dereference processing failed : %s", strerror(ret));
+ if (ret == ENOTSUP) {
+ sss_log(SSS_LOG_WARNING,
+ "LDAP server claims to support deref, but deref search failed. "
+ "Disabling deref for further requests. You can permanently "
+ "disable deref by setting ldap_deref_threshold to 0 in domain "
+ "configuration.");
+ state->sh->disable_deref = true;
+ } else {
+ sss_log(SSS_LOG_WARNING, "dereference processing failed : %s", strerror(ret));
+ }
tevent_req_error(req, ret);
return;
}
@@ -2176,6 +2191,10 @@ bool sdap_has_deref_support(struct sdap_handle *sh, struct sdap_options *opts)
int i;
int deref_threshold;
+ if (sh->disable_deref) {
+ return false;
+ }
+
deref_threshold = dp_opt_get_int(opts->basic, SDAP_DEREF_THRESHOLD);
if (deref_threshold == 0) {
return false;
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index 5bfa3549..4d1ece84 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -2268,7 +2268,7 @@ sdap_nested_get_user_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
goto immediate;
} else {
DEBUG(SSSDBG_MINOR_FAILURE, ("Couldn't parse out user information "
- "based on DN %s, falling back to an LDAP lookup\n"));
+ "based on DN %s, falling back to an LDAP lookup\n", user_dn));
}
}
@@ -3646,7 +3646,17 @@ static void sdap_nested_group_process_deref(struct tevent_req *subreq)
&state->derefctx->num_results,
&state->derefctx->deref_result);
talloc_zfree(subreq);
- if (ret != EOK && ret != ENOENT) {
+ if (ret == ENOTSUP) {
+ ret = sdap_nested_group_process_noderef(req);
+ if (ret != EAGAIN) {
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_error(req, ret);
+ }
+ }
+ return;
+ } else if (ret != EOK && ret != ENOENT) {
tevent_req_error(req, ret);
return;
} else if (ret == ENOENT || state->derefctx->deref_result == NULL) {
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 23be22fd..5a6ba028 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -880,7 +880,17 @@ static void sdap_initgr_nested_deref_done(struct tevent_req *subreq)
&num_results,
&deref_result);
talloc_zfree(subreq);
- if (ret != EOK && ret != ENOENT) {
+ if (ret == ENOTSUP) {
+ ret = sdap_initgr_nested_noderef_search(req);
+ if (ret != EAGAIN) {
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_error(req, ret);
+ }
+ }
+ return;
+ } else if (ret != EOK && ret != ENOENT) {
tevent_req_error(req, ret);
return;
} else if (ret == ENOENT || deref_result == NULL) {