From 01fb3bde5c72d2e51182808b2ac606d76ad4f0e9 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 14 Sep 2017 15:47:53 -0400 Subject: [PATCH] Ticket 49327 - password expired control not sent during grace logins Bug Description: When a password is expired, but within the grace login limit, we should still send the expired control even though we allowed the bind. Fix Description: new_new_passwd() returned a variety of result codes that required the caller to set the response controls. This was hard to read and process. Instead I added all the controls inside the function, and return success or failure to the caller. https://pagure.io/389-ds-base/issue/49327 Reviewed by: ? --- ldap/servers/slapd/bind.c | 16 ++-------------- ldap/servers/slapd/proto-slap.h | 2 +- ldap/servers/slapd/pw_mgmt.c | 29 +++++++++++++++++------------ ldap/servers/slapd/saslbind.c | 20 ++------------------ 4 files changed, 22 insertions(+), 45 deletions(-) diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c index 91f7211..4a8e4de 100644 --- a/ldap/servers/slapd/bind.c +++ b/ldap/servers/slapd/bind.c @@ -673,7 +673,6 @@ do_bind(Slapi_PBlock *pb) slapi_entry_free(referral); goto free_and_return; } else if (auto_bind || rc == SLAPI_BIND_SUCCESS || rc == SLAPI_BIND_ANONYMOUS) { - long t; char *authtype = NULL; /* rc is SLAPI_BIND_SUCCESS or SLAPI_BIND_ANONYMOUS */ if (auto_bind) { @@ -761,19 +760,8 @@ do_bind(Slapi_PBlock *pb) slapi_ch_strdup(slapi_sdn_get_ndn(sdn)), NULL, NULL, NULL, bind_target_entry); if (!slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) { - /* check if need new password before sending - the bind success result */ - myrc = need_new_pw(pb, &t, bind_target_entry, pw_response_requested); - switch (myrc) { - case 1: - (void)slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0); - break; - case 2: - (void)slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t); - break; - default: - break; - } + /* check if need new password before sending the bind success result */ + myrc = need_new_pw(pb, bind_target_entry, pw_response_requested); } } if (auth_response_requested) { diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index cff7b43..4a30def 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -950,7 +950,7 @@ int plugin_call_mmr_plugin_postop ( Slapi_PBlock *pb, Slapi_Entry *e, int flags) * pw_mgmt.c */ void pw_init(void); -int need_new_pw(Slapi_PBlock *pb, long *t, Slapi_Entry *e, int pwresponse_req); +int need_new_pw(Slapi_PBlock *pb, Slapi_Entry *e, int pwresponse_req); int update_pw_info(Slapi_PBlock *pb, char *old_pw); int check_pw_syntax(Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, char **old_pw, Slapi_Entry *e, int mod_op); int check_pw_syntax_ext(Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, char **old_pw, Slapi_Entry *e, int mod_op, Slapi_Mods *smods); diff --git a/ldap/servers/slapd/pw_mgmt.c b/ldap/servers/slapd/pw_mgmt.c index fef1fcb..50bcbde 100644 --- a/ldap/servers/slapd/pw_mgmt.c +++ b/ldap/servers/slapd/pw_mgmt.c @@ -22,9 +22,14 @@ /* prototypes */ /****************************************************************************/ -/* need_new_pw() is called when non rootdn bind operation succeeds with authentication */ +/* + * need_new_pw() is called when non rootdn bind operation succeeds with authentication + * + * Return 0 - password is okay + * Return -1 - password is expired, abort bind + */ int -need_new_pw(Slapi_PBlock *pb, long *t, Slapi_Entry *e, int pwresponse_req) +need_new_pw(Slapi_PBlock *pb, Slapi_Entry *e, int pwresponse_req) { time_t cur_time, pw_exp_date; Slapi_Mods smods; @@ -38,6 +43,7 @@ need_new_pw(Slapi_PBlock *pb, long *t, Slapi_Entry *e, int pwresponse_req) int pwdGraceUserTime = 0; char graceUserTime[16] = {0}; Connection *pb_conn = NULL; + long t; if (NULL == e) { return (-1); @@ -94,7 +100,7 @@ need_new_pw(Slapi_PBlock *pb, long *t, Slapi_Entry *e, int pwresponse_req) /* set c_needpw for this connection to be true. this client now can only change its own password */ pb_conn->c_needpw = 1; - *t = 0; + t = 0; /* We need to include "changeafterreset" error in * passwordpolicy response control. So, we will not be * done here. We remember this scenario by (c_needpw=1) @@ -154,10 +160,7 @@ skip: -1); } } - - if (pb_conn->c_needpw == 1) { - slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0); - } + slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0); return (0); } @@ -214,10 +217,10 @@ skip: slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpWarned", "1"); - *t = pwpolicy->pw_warning; + t = pwpolicy->pw_warning; } else { - *t = (long)diff_t; /* jcm: had to cast double to long */ + t = (long)diff_t; /* jcm: had to cast double to long */ } pw_apply_mods(sdn, &smods); @@ -225,16 +228,18 @@ skip: if (pwresponse_req) { /* check for "changeafterreset" condition */ if (pb_conn->c_needpw == 1) { - slapi_pwpolicy_make_response_control(pb, *t, -1, LDAP_PWPOLICY_CHGAFTERRESET); + slapi_pwpolicy_make_response_control(pb, t, -1, LDAP_PWPOLICY_CHGAFTERRESET); } else { - slapi_pwpolicy_make_response_control(pb, *t, -1, -1); + slapi_pwpolicy_make_response_control(pb, t, -1, -1); } } if (pb_conn->c_needpw == 1) { slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0); + } else { + slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t); } - return (2); + return (0); } else { if (pwresponse_req && pwpolicy->pw_send_expiring) { slapi_pwpolicy_make_response_control(pb, diff_t, -1, -1); diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c index 55c147c..32433bb 100644 --- a/ldap/servers/slapd/saslbind.c +++ b/ldap/servers/slapd/saslbind.c @@ -887,7 +887,6 @@ void ids_sasl_check_bind(Slapi_PBlock *pb) { int rc, isroot; - long t; sasl_conn_t *sasl_conn; struct propctx *propctx; sasl_ssf_t *ssfp; @@ -1126,23 +1125,8 @@ sasl_check_result: set_db_default_result_handlers(pb); /* check password expiry */ - if (!isroot) { - int pwrc; - - pwrc = need_new_pw(pb, &t, bind_target_entry, pwresponse_requested); - - switch (pwrc) { - case 1: - slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0); - break; - case 2: - slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t); - break; - case -1: - goto out; - default: - break; - } + if (!isroot && need_new_pw(pb, bind_target_entry, pwresponse_requested) == -1) { + goto out; } /* attach the sasl data */ -- 2.9.5