From bfafa12ae83bcdec53bb306f68eff9e6acfbb4a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Fri, 20 Jul 2018 12:15:18 +0200
Subject: [PATCH] sdap: respect passwordGracelimit
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since recent changes in 389-ds two response controls are end when
passwordGracelimit is set and about to expire:
- [1.3.6.1.4.1.42.2.27.8.5.1] for the GraceLimit itself
- [2.16.840.1.113730.3.4.4] for the PasswordExpired
Whenever the former is returned and the GraceLimit is still valid, we
shouldn't report the latter to the users.
Resolves:
https://pagure.io/SSSD/sssd/issue/3597
Signed-off-by: Fabiano FidĂȘncio <fidencio@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 954bf82b60b7cfd93b865a6618f155d042b15729)
DOWNSTREAM:
Resolves: rhbz#1522928 - sssd doesn't allow user with expired password
to login when PasswordgraceLimit set
---
src/providers/ldap/sdap_async_connection.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index a8d4262b52c4b2d2810450d68794f00558ea5c2d..8aacd6705a1f82be8c14f97996786ac9b47396d5 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -734,6 +734,7 @@ static void simple_bind_done(struct sdap_op *op,
ber_int_t pp_expire;
LDAPPasswordPolicyError pp_error;
int result = LDAP_OTHER;
+ bool on_grace_login_limit = false;
if (error) {
tevent_req_error(req, error);
@@ -772,6 +773,7 @@ static void simple_bind_done(struct sdap_op *op,
DEBUG(SSSDBG_TRACE_INTERNAL,
"Server returned control [%s].\n",
response_controls[c]->ldctl_oid);
+
if (strcmp(response_controls[c]->ldctl_oid,
LDAP_CONTROL_PASSWORDPOLICYRESPONSE) == 0) {
lret = ldap_parse_passwordpolicy_control(state->sh->ldap,
@@ -799,13 +801,26 @@ static void simple_bind_done(struct sdap_op *op,
state->ppolicy->grace = pp_grace;
state->ppolicy->expire = pp_expire;
if (result == LDAP_SUCCESS) {
-
+ /* We have to set the on_grace_login_limit as when going
+ * through the response controls 389-ds may return both
+ * an warning and an error (and the order is not ensured)
+ * for the GraceLimit:
+ * - [1.3.6.1.4.1.42.2.27.8.5.1] for the GraceLimit itself
+ * - [2.16.840.1.113730.3.4.4] for the PasswordExpired
+ *
+ * So, in order to avoid bulldozing the GraceLimit, let's
+ * set it to true when pp_grace >= 0 and, in the end of
+ * this function, just return EOK when LDAP returns the
+ * PasswordExpired error but the GraceLimit is still valid.
+ */
+ on_grace_login_limit = false;
if (pp_error == PP_changeAfterReset) {
DEBUG(SSSDBG_TRACE_LIBS,
"Password was reset. "
"User must set a new password.\n");
ret = ERR_PASSWORD_EXPIRED;
} else if (pp_grace >= 0) {
+ on_grace_login_limit = true;
DEBUG(SSSDBG_TRACE_LIBS,
"Password expired. "
"[%d] grace logins remaining.\n",
@@ -875,6 +890,10 @@ static void simple_bind_done(struct sdap_op *op,
ret = ERR_AUTH_FAILED;
}
+ if (ret == ERR_PASSWORD_EXPIRED && on_grace_login_limit) {
+ ret = EOK;
+ }
+
done:
ldap_controls_free(response_controls);
ldap_memfree(errmsg);
--
2.14.4