From 520bf2852ee92763db7bf5f9cd9865953f23795a Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Jun 21 2018 16:51:37 +0000 Subject: Ticket 49751 - passwordMustChange attribute is not honored by a RO consumer if using "Chain on Update" Bug Description: For a chained bind request we do not check password policy, in particular if the password must be reset. Fix Description: For a chained bind request check if the password must be reset. This is the only password policy setting that must be applied on the connection itself. All other password policy is still enforced correctly. https://pagure.io/389-ds-base/issue/49751 Reviewed by: spichugi, tbordaz, and lkrispen(Thanks!!!) (cherry picked from commit d2c26d89baef6156901868c70f80333a40cd030a) --- diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c index a34a21a..b3fe273 100644 --- a/ldap/servers/slapd/bind.c +++ b/ldap/servers/slapd/bind.c @@ -768,6 +768,12 @@ do_bind(Slapi_PBlock *pb) 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, bind_target_entry, pw_response_requested); + } else { + /* We still need to check if we need to enforce "user MUST reset password" */ + if (!bind_target_entry) { + bind_target_entry = get_entry(pb, slapi_sdn_get_ndn(sdn)); + } + check_must_change_pw(pb, bind_target_entry); } } if (auth_response_requested) { diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index f54bc6b..9900fac 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -952,6 +952,7 @@ int plugin_call_mmr_plugin_postop ( Slapi_PBlock *pb, Slapi_Entry *e, int flags) * pw_mgmt.c */ void pw_init(void); +void check_must_change_pw(Slapi_PBlock *pb, Slapi_Entry *e); 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); diff --git a/ldap/servers/slapd/pw_mgmt.c b/ldap/servers/slapd/pw_mgmt.c index 6028684..befac50 100644 --- a/ldap/servers/slapd/pw_mgmt.c +++ b/ldap/servers/slapd/pw_mgmt.c @@ -23,6 +23,39 @@ /****************************************************************************/ /* + * For chaining, particularly chain-on-update, we still need to check if the user's + * password MUST be reset before proceeding. + */ +void +check_must_change_pw(Slapi_PBlock *pb, Slapi_Entry *e) +{ + passwdPolicy *pwpolicy = NULL; + Connection *pb_conn = NULL; + time_t pw_exp_date; + char *passwordExpirationTime = NULL; + + if ((passwordExpirationTime = slapi_entry_attr_get_charptr(e, "passwordExpirationTime"))) { + pw_exp_date = parse_genTime(passwordExpirationTime); + slapi_ch_free_string(&passwordExpirationTime); + + /* Check if password has been reset */ + if (pw_exp_date == NO_TIME) { + pwpolicy = new_passwdPolicy(pb, slapi_entry_get_ndn(e)); + + /* check if changing password is required */ + if (pwpolicy->pw_must_change) { + /* set c_needpw for this connection to be true. this client + now can only change its own password */ + slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); + if (pb_conn) { + pb_conn->c_needpw = 1; + } + } + } + } +} + +/* * need_new_pw() is called when non rootdn bind operation succeeds with authentication * * Return 0 - password is okay