|
|
71e593 |
From 57fc60c9dc77698cf824813c36eb0f90d767b315 Mon Sep 17 00:00:00 2001
|
|
|
71e593 |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
71e593 |
Date: Thu, 22 Nov 2018 12:17:51 +0100
|
|
|
71e593 |
Subject: [PATCH 79/80] LDAP: Only authenticate the auth connection if we need
|
|
|
71e593 |
to look up user information
|
|
|
71e593 |
|
|
|
71e593 |
Related:
|
|
|
71e593 |
https://pagure.io/SSSD/sssd/issue/3451
|
|
|
71e593 |
|
|
|
71e593 |
Commit add72860c7a7a2c418f4d8b6790b5caeaf7dfb7b initially addressed #3451 by
|
|
|
71e593 |
using the full sdap_cli_connect() request during LDAP authentication. This
|
|
|
71e593 |
was a good idea as it addressed the case where the authentication connection
|
|
|
71e593 |
must also look up some user information (typically with id_provider=proxy
|
|
|
71e593 |
where you don't know the DN to bind as during authentication), but this
|
|
|
71e593 |
approach also broke the use-case of id_provider=ldap and auth_provider=ldap
|
|
|
71e593 |
with ldap_sasl_auth=gssapi.
|
|
|
71e593 |
|
|
|
71e593 |
This is because (for reason I don't know) AD doesn't like if you use
|
|
|
71e593 |
both GSSAPI and startTLS on the same connection. But the code would
|
|
|
71e593 |
force TLS during the authentication as a general measure to not transmit
|
|
|
71e593 |
passwords in the clear, but then, the connection would also see that
|
|
|
71e593 |
ldap_sasl_auth=gssapi is set and also bind with GSSAPI.
|
|
|
71e593 |
|
|
|
71e593 |
This patch checks if the user DN is already known and if yes, then
|
|
|
71e593 |
doesn't authenticate the connection as the connection will then only be
|
|
|
71e593 |
used for the user simple bind.
|
|
|
71e593 |
|
|
|
71e593 |
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
|
|
71e593 |
---
|
|
|
71e593 |
src/providers/ldap/ldap_auth.c | 53 +++++++++++++++++++++++++++-------
|
|
|
71e593 |
1 file changed, 42 insertions(+), 11 deletions(-)
|
|
|
71e593 |
|
|
|
71e593 |
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
|
|
|
71e593 |
index c409353d9..b4d045a65 100644
|
|
|
71e593 |
--- a/src/providers/ldap/ldap_auth.c
|
|
|
71e593 |
+++ b/src/providers/ldap/ldap_auth.c
|
|
|
71e593 |
@@ -664,6 +664,18 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx,
|
|
|
71e593 |
state->sdap_service = ctx->service;
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
+ ret = get_user_dn(state, state->ctx->be->domain,
|
|
|
71e593 |
+ state->ctx->opts, state->username, &state->dn,
|
|
|
71e593 |
+ &state->pw_expire_type, &state->pw_expire_data);
|
|
|
71e593 |
+ if (ret == EAGAIN) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_TRACE_FUNC,
|
|
|
71e593 |
+ "Need to look up the DN of %s later\n", state->username);
|
|
|
71e593 |
+ } else if (ret != EOK) {
|
|
|
71e593 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
71e593 |
+ "Cannot get user DN [%d]: %s\n", ret, sss_strerror(ret));
|
|
|
71e593 |
+ goto fail;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
if (auth_connect_send(req) == NULL) {
|
|
|
71e593 |
ret = ENOMEM;
|
|
|
71e593 |
goto fail;
|
|
|
71e593 |
@@ -683,6 +695,8 @@ static struct tevent_req *auth_connect_send(struct tevent_req *req)
|
|
|
71e593 |
struct auth_state *state = tevent_req_data(req,
|
|
|
71e593 |
struct auth_state);
|
|
|
71e593 |
bool use_tls;
|
|
|
71e593 |
+ bool skip_conn_auth = false;
|
|
|
71e593 |
+ const char *sasl_mech;
|
|
|
71e593 |
|
|
|
71e593 |
/* Check for undocumented debugging feature to disable TLS
|
|
|
71e593 |
* for authentication. This should never be used in production
|
|
|
71e593 |
@@ -695,10 +709,33 @@ static struct tevent_req *auth_connect_send(struct tevent_req *req)
|
|
|
71e593 |
"for debugging purposes only.");
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
+ if (state->dn != NULL) {
|
|
|
71e593 |
+ /* In case the user's DN is known, the connection will only be used
|
|
|
71e593 |
+ * to bind as the user to perform the authentication. In that case,
|
|
|
71e593 |
+ * we don't need to authenticate the connection, because we're not
|
|
|
71e593 |
+ * looking up any information using the connection. This might be
|
|
|
71e593 |
+ * needed e.g. in case both ID and AUTH providers are set to LDAP
|
|
|
71e593 |
+ * and the server is AD, because otherwise the connection would
|
|
|
71e593 |
+ * both do a startTLS and later bind using GSSAPI which doesn't work
|
|
|
71e593 |
+ * well with AD.
|
|
|
71e593 |
+ */
|
|
|
71e593 |
+ skip_conn_auth = true;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
+ if (skip_conn_auth == false) {
|
|
|
71e593 |
+ sasl_mech = dp_opt_get_string(state->ctx->opts->basic,
|
|
|
71e593 |
+ SDAP_SASL_MECH);
|
|
|
71e593 |
+ if (sasl_mech && strcasecmp(sasl_mech, "GSSAPI") == 0) {
|
|
|
71e593 |
+ /* Don't force TLS on if we're told to use GSSAPI */
|
|
|
71e593 |
+ use_tls = false;
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+ }
|
|
|
71e593 |
+
|
|
|
71e593 |
subreq = sdap_cli_connect_send(state, state->ev, state->ctx->opts,
|
|
|
71e593 |
state->ctx->be,
|
|
|
71e593 |
state->sdap_service, false,
|
|
|
71e593 |
- use_tls ? CON_TLS_ON : CON_TLS_OFF, false);
|
|
|
71e593 |
+ use_tls ? CON_TLS_ON : CON_TLS_OFF,
|
|
|
71e593 |
+ skip_conn_auth);
|
|
|
71e593 |
|
|
|
71e593 |
if (subreq == NULL) {
|
|
|
71e593 |
tevent_req_error(req, ENOMEM);
|
|
|
71e593 |
@@ -739,15 +776,7 @@ static void auth_connect_done(struct tevent_req *subreq)
|
|
|
71e593 |
return;
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
- ret = get_user_dn(state, state->ctx->be->domain,
|
|
|
71e593 |
- state->ctx->opts, state->username, &state->dn,
|
|
|
71e593 |
- &state->pw_expire_type, &state->pw_expire_data);
|
|
|
71e593 |
- if (ret == EOK) {
|
|
|
71e593 |
- /* All required user data was pre-cached during an identity lookup.
|
|
|
71e593 |
- * We can proceed with the bind */
|
|
|
71e593 |
- auth_do_bind(req);
|
|
|
71e593 |
- return;
|
|
|
71e593 |
- } else if (ret == EAGAIN) {
|
|
|
71e593 |
+ if (state->dn == NULL) {
|
|
|
71e593 |
/* The cached user entry was missing the bind DN. Need to look
|
|
|
71e593 |
* it up based on user name in order to perform the bind */
|
|
|
71e593 |
subreq = get_user_dn_send(req, state->ev, state->ctx->be->domain,
|
|
|
71e593 |
@@ -760,7 +789,9 @@ static void auth_connect_done(struct tevent_req *subreq)
|
|
|
71e593 |
return;
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
- tevent_req_error(req, ret);
|
|
|
71e593 |
+ /* All required user data was pre-cached during an identity lookup.
|
|
|
71e593 |
+ * We can proceed with the bind */
|
|
|
71e593 |
+ auth_do_bind(req);
|
|
|
71e593 |
return;
|
|
|
71e593 |
}
|
|
|
71e593 |
|
|
|
71e593 |
--
|
|
|
71e593 |
2.19.1
|
|
|
71e593 |
|