|
|
b69e47 |
From 3ab8a78cd27cc8d2ad7a2b322a4fe73c43a3db08 Mon Sep 17 00:00:00 2001
|
|
|
b69e47 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
b69e47 |
Date: Thu, 14 Sep 2017 15:47:53 -0400
|
|
|
b69e47 |
Subject: [PATCH] Ticket 49327 - password expired control not sent during grace
|
|
|
b69e47 |
logins
|
|
|
b69e47 |
|
|
|
b69e47 |
Bug Description: When a password is expired, but within the grace login limit,
|
|
|
b69e47 |
we should still send the expired control even though we allowed
|
|
|
b69e47 |
the bind.
|
|
|
b69e47 |
|
|
|
b69e47 |
Fix Description: new_new_passwd() returned a variety of result codes that required
|
|
|
b69e47 |
the caller to set the response controls. This was hard to read and
|
|
|
b69e47 |
process. Instead I added all the controls inside the function, and
|
|
|
b69e47 |
return success or failure to the caller.
|
|
|
b69e47 |
|
|
|
b69e47 |
https://pagure.io/389-ds-base/issue/49327
|
|
|
b69e47 |
|
|
|
b69e47 |
Reviewed by: gparente & tbordaz (Thanks!!)
|
|
|
b69e47 |
|
|
|
b69e47 |
(cherry picked from commit fbd32c4e27af9f331ee3a42dec944895a6efe2ad)
|
|
|
b69e47 |
---
|
|
|
b69e47 |
ldap/servers/plugins/replication/repl_extop.c | 5 +-
|
|
|
b69e47 |
ldap/servers/slapd/bind.c | 18 +-
|
|
|
b69e47 |
ldap/servers/slapd/proto-slap.h | 3 +-
|
|
|
b69e47 |
ldap/servers/slapd/pw_mgmt.c | 453 +++++++++++++-------------
|
|
|
b69e47 |
ldap/servers/slapd/saslbind.c | 20 +-
|
|
|
b69e47 |
5 files changed, 238 insertions(+), 261 deletions(-)
|
|
|
b69e47 |
|
|
|
b69e47 |
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
|
|
|
b69e47 |
index a39d918..96ad7dd 100644
|
|
|
b69e47 |
--- a/ldap/servers/plugins/replication/repl_extop.c
|
|
|
b69e47 |
+++ b/ldap/servers/plugins/replication/repl_extop.c
|
|
|
b69e47 |
@@ -1173,8 +1173,9 @@ send_response:
|
|
|
b69e47 |
* On the supplier, we need to close the connection so
|
|
|
b69e47 |
* that the RA will restart a new session in a clear state
|
|
|
b69e47 |
*/
|
|
|
b69e47 |
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multimaster_extop_StartNSDS50ReplicationRequest - "
|
|
|
b69e47 |
- "already acquired replica: disconnect conn=%d\n", connid);
|
|
|
b69e47 |
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
|
|
|
b69e47 |
+ "multimaster_extop_StartNSDS50ReplicationRequest - "
|
|
|
b69e47 |
+ "already acquired replica: disconnect conn=%" PRIu64 "\n", connid);
|
|
|
b69e47 |
slapi_disconnect_server(conn);
|
|
|
b69e47 |
|
|
|
b69e47 |
}
|
|
|
b69e47 |
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
|
|
|
b69e47 |
index d6c7668..e6cad7f 100644
|
|
|
b69e47 |
--- a/ldap/servers/slapd/bind.c
|
|
|
b69e47 |
+++ b/ldap/servers/slapd/bind.c
|
|
|
b69e47 |
@@ -673,8 +673,7 @@ do_bind( Slapi_PBlock *pb )
|
|
|
b69e47 |
slapi_entry_free(referral);
|
|
|
b69e47 |
goto free_and_return;
|
|
|
b69e47 |
} else if (auto_bind || rc == SLAPI_BIND_SUCCESS || rc == SLAPI_BIND_ANONYMOUS) {
|
|
|
b69e47 |
- long t;
|
|
|
b69e47 |
- char* authtype = NULL;
|
|
|
b69e47 |
+ char *authtype = NULL;
|
|
|
b69e47 |
/* rc is SLAPI_BIND_SUCCESS or SLAPI_BIND_ANONYMOUS */
|
|
|
b69e47 |
if(auto_bind) {
|
|
|
b69e47 |
rc = SLAPI_BIND_SUCCESS;
|
|
|
b69e47 |
@@ -761,19 +760,8 @@ do_bind( Slapi_PBlock *pb )
|
|
|
b69e47 |
slapi_ch_strdup(slapi_sdn_get_ndn(sdn)),
|
|
|
b69e47 |
NULL, NULL, NULL, bind_target_entry);
|
|
|
b69e47 |
if (!slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) {
|
|
|
b69e47 |
- /* check if need new password before sending
|
|
|
b69e47 |
- the bind success result */
|
|
|
b69e47 |
- myrc = need_new_pw(pb, &t, bind_target_entry, pw_response_requested);
|
|
|
b69e47 |
- switch (myrc) {
|
|
|
b69e47 |
- case 1:
|
|
|
b69e47 |
- (void)slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
b69e47 |
- break;
|
|
|
b69e47 |
- case 2:
|
|
|
b69e47 |
- (void)slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t);
|
|
|
b69e47 |
- break;
|
|
|
b69e47 |
- default:
|
|
|
b69e47 |
- break;
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
+ /* check if need new password before sending the bind success result */
|
|
|
b69e47 |
+ myrc = need_new_pw(pb, bind_target_entry, pw_response_requested);
|
|
|
b69e47 |
}
|
|
|
b69e47 |
}
|
|
|
b69e47 |
if (auth_response_requested) {
|
|
|
b69e47 |
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
|
|
b69e47 |
index 9696ead..0ba61d7 100644
|
|
|
b69e47 |
--- a/ldap/servers/slapd/proto-slap.h
|
|
|
b69e47 |
+++ b/ldap/servers/slapd/proto-slap.h
|
|
|
b69e47 |
@@ -972,7 +972,7 @@ int plugin_call_acl_verify_syntax ( Slapi_PBlock *pb, Slapi_Entry *e, char **err
|
|
|
b69e47 |
* pw_mgmt.c
|
|
|
b69e47 |
*/
|
|
|
b69e47 |
void pw_init( void );
|
|
|
b69e47 |
-int need_new_pw( Slapi_PBlock *pb, long *t, Slapi_Entry *e, int pwresponse_req );
|
|
|
b69e47 |
+int need_new_pw(Slapi_PBlock *pb, Slapi_Entry *e, int pwresponse_req);
|
|
|
b69e47 |
int update_pw_info( Slapi_PBlock *pb , char *old_pw );
|
|
|
b69e47 |
int check_pw_syntax( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals,
|
|
|
b69e47 |
char **old_pw, Slapi_Entry *e, int mod_op );
|
|
|
b69e47 |
@@ -982,7 +982,6 @@ void get_old_pw( Slapi_PBlock *pb, const Slapi_DN *sdn, char **old_pw);
|
|
|
b69e47 |
int check_account_lock( Slapi_PBlock *pb, Slapi_Entry * bind_target_entry, int pwresponse_req, int account_inactivation_only /*no wire/no pw policy*/);
|
|
|
b69e47 |
int check_pw_minage( Slapi_PBlock *pb, const Slapi_DN *sdn, struct berval **vals) ;
|
|
|
b69e47 |
void add_password_attrs( Slapi_PBlock *pb, Operation *op, Slapi_Entry *e );
|
|
|
b69e47 |
-
|
|
|
b69e47 |
int add_shadow_ext_password_attrs(Slapi_PBlock *pb, Slapi_Entry **e);
|
|
|
b69e47 |
|
|
|
b69e47 |
/*
|
|
|
b69e47 |
diff --git a/ldap/servers/slapd/pw_mgmt.c b/ldap/servers/slapd/pw_mgmt.c
|
|
|
b69e47 |
index 7252c08..b06e3f1 100644
|
|
|
b69e47 |
--- a/ldap/servers/slapd/pw_mgmt.c
|
|
|
b69e47 |
+++ b/ldap/servers/slapd/pw_mgmt.c
|
|
|
b69e47 |
@@ -22,234 +22,239 @@
|
|
|
b69e47 |
/* prototypes */
|
|
|
b69e47 |
/****************************************************************************/
|
|
|
b69e47 |
|
|
|
b69e47 |
-/* need_new_pw() is called when non rootdn bind operation succeeds with authentication */
|
|
|
b69e47 |
+/*
|
|
|
b69e47 |
+ * need_new_pw() is called when non rootdn bind operation succeeds with authentication
|
|
|
b69e47 |
+ *
|
|
|
b69e47 |
+ * Return 0 - password is okay
|
|
|
b69e47 |
+ * Return -1 - password is expired, abort bind
|
|
|
b69e47 |
+ */
|
|
|
b69e47 |
int
|
|
|
b69e47 |
-need_new_pw( Slapi_PBlock *pb, long *t, Slapi_Entry *e, int pwresponse_req )
|
|
|
b69e47 |
+need_new_pw(Slapi_PBlock *pb, Slapi_Entry *e, int pwresponse_req)
|
|
|
b69e47 |
{
|
|
|
b69e47 |
- time_t cur_time, pw_exp_date;
|
|
|
b69e47 |
- Slapi_Mods smods;
|
|
|
b69e47 |
- double diff_t = 0;
|
|
|
b69e47 |
- char *cur_time_str = NULL;
|
|
|
b69e47 |
- char *passwordExpirationTime = NULL;
|
|
|
b69e47 |
- char *timestring;
|
|
|
b69e47 |
- char *dn;
|
|
|
b69e47 |
- const Slapi_DN *sdn;
|
|
|
b69e47 |
- passwdPolicy *pwpolicy = NULL;
|
|
|
b69e47 |
- int pwdGraceUserTime = 0;
|
|
|
b69e47 |
- char graceUserTime[8];
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- if (NULL == e) {
|
|
|
b69e47 |
- return (-1);
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- slapi_mods_init (&smods, 0);
|
|
|
b69e47 |
- sdn = slapi_entry_get_sdn_const( e );
|
|
|
b69e47 |
- dn = slapi_entry_get_ndn( e );
|
|
|
b69e47 |
- pwpolicy = new_passwdPolicy(pb, dn);
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- /* after the user binds with authentication, clear the retry count */
|
|
|
b69e47 |
- if ( pwpolicy->pw_lockout == 1)
|
|
|
b69e47 |
- {
|
|
|
b69e47 |
- if(slapi_entry_attr_get_int( e, "passwordRetryCount") > 0)
|
|
|
b69e47 |
- {
|
|
|
b69e47 |
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordRetryCount", "0");
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- cur_time = current_time();
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- /* get passwordExpirationTime attribute */
|
|
|
b69e47 |
- passwordExpirationTime= slapi_entry_attr_get_charptr(e, "passwordExpirationTime");
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- if (passwordExpirationTime == NULL)
|
|
|
b69e47 |
- {
|
|
|
b69e47 |
- /* password expiration date is not set.
|
|
|
b69e47 |
- * This is ok for data that has been loaded via ldif2ldbm
|
|
|
b69e47 |
- * Set expiration time if needed,
|
|
|
b69e47 |
- * don't do further checking and return 0 */
|
|
|
b69e47 |
- if (pwpolicy->pw_exp == 1) {
|
|
|
b69e47 |
- pw_exp_date = time_plus_sec(cur_time, pwpolicy->pw_maxage);
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- timestring = format_genTime (pw_exp_date);
|
|
|
b69e47 |
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
|
|
b69e47 |
- slapi_ch_free_string(×tring);
|
|
|
b69e47 |
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpWarned", "0");
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
- } else if (pwpolicy->pw_lockout == 1) {
|
|
|
b69e47 |
- pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- slapi_mods_done(&smods);
|
|
|
b69e47 |
- return ( 0 );
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- pw_exp_date = parse_genTime(passwordExpirationTime);
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- slapi_ch_free_string(&passwordExpirationTime);
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- /* Check if password has been reset */
|
|
|
b69e47 |
- if ( pw_exp_date == NO_TIME ) {
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- /* check if changing password is required */
|
|
|
b69e47 |
- if ( pwpolicy->pw_must_change ) {
|
|
|
b69e47 |
- /* set c_needpw for this connection to be true. this client
|
|
|
b69e47 |
- now can only change its own password */
|
|
|
b69e47 |
- pb->pb_conn->c_needpw = 1;
|
|
|
b69e47 |
- *t=0;
|
|
|
b69e47 |
- /* We need to include "changeafterreset" error in
|
|
|
b69e47 |
- * passwordpolicy response control. So, we will not be
|
|
|
b69e47 |
- * done here. We remember this scenario by (c_needpw=1)
|
|
|
b69e47 |
- * and check it before sending the control from various
|
|
|
b69e47 |
- * places. We will also add LDAP_CONTROL_PWEXPIRED control
|
|
|
b69e47 |
- * as the return value used to be (1).
|
|
|
b69e47 |
- */
|
|
|
b69e47 |
- goto skip;
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- /* Mark that first login occured */
|
|
|
b69e47 |
- pw_exp_date = NOT_FIRST_TIME;
|
|
|
b69e47 |
- timestring = format_genTime(pw_exp_date);
|
|
|
b69e47 |
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
|
|
b69e47 |
- slapi_ch_free_string(×tring);
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
+ time_t cur_time, pw_exp_date;
|
|
|
b69e47 |
+ Slapi_Mods smods;
|
|
|
b69e47 |
+ double diff_t = 0;
|
|
|
b69e47 |
+ char *cur_time_str = NULL;
|
|
|
b69e47 |
+ char *passwordExpirationTime = NULL;
|
|
|
b69e47 |
+ char *timestring;
|
|
|
b69e47 |
+ char *dn;
|
|
|
b69e47 |
+ const Slapi_DN *sdn;
|
|
|
b69e47 |
+ passwdPolicy *pwpolicy = NULL;
|
|
|
b69e47 |
+ int pwdGraceUserTime = 0;
|
|
|
b69e47 |
+ char graceUserTime[16] = {0};
|
|
|
b69e47 |
+ Connection *pb_conn = NULL;
|
|
|
b69e47 |
+ long t;
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ if (NULL == e) {
|
|
|
b69e47 |
+ return (-1);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ slapi_mods_init(&smods, 0);
|
|
|
b69e47 |
+ sdn = slapi_entry_get_sdn_const(e);
|
|
|
b69e47 |
+ dn = slapi_entry_get_ndn(e);
|
|
|
b69e47 |
+ pwpolicy = new_passwdPolicy(pb, dn);
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ /* after the user binds with authentication, clear the retry count */
|
|
|
b69e47 |
+ if (pwpolicy->pw_lockout == 1) {
|
|
|
b69e47 |
+ if (slapi_entry_attr_get_int(e, "passwordRetryCount") > 0) {
|
|
|
b69e47 |
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordRetryCount", "0");
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ cur_time = current_time();
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ /* get passwordExpirationTime attribute */
|
|
|
b69e47 |
+ passwordExpirationTime = slapi_entry_attr_get_charptr(e, "passwordExpirationTime");
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ if (passwordExpirationTime == NULL) {
|
|
|
b69e47 |
+ /* password expiration date is not set.
|
|
|
b69e47 |
+ * This is ok for data that has been loaded via ldif2ldbm
|
|
|
b69e47 |
+ * Set expiration time if needed,
|
|
|
b69e47 |
+ * don't do further checking and return 0 */
|
|
|
b69e47 |
+ if (pwpolicy->pw_exp == 1) {
|
|
|
b69e47 |
+ pw_exp_date = time_plus_sec(cur_time, pwpolicy->pw_maxage);
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ timestring = format_genTime(pw_exp_date);
|
|
|
b69e47 |
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
|
|
b69e47 |
+ slapi_ch_free_string(×tring);
|
|
|
b69e47 |
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpWarned", "0");
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
+ } else if (pwpolicy->pw_lockout == 1) {
|
|
|
b69e47 |
+ pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ slapi_mods_done(&smods);
|
|
|
b69e47 |
+ return (0);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ pw_exp_date = parse_genTime(passwordExpirationTime);
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ slapi_ch_free_string(&passwordExpirationTime);
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ /* Check if password has been reset */
|
|
|
b69e47 |
+ if (pw_exp_date == NO_TIME) {
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ /* check if changing password is required */
|
|
|
b69e47 |
+ if (pwpolicy->pw_must_change) {
|
|
|
b69e47 |
+ /* set c_needpw for this connection to be true. this client
|
|
|
b69e47 |
+ now can only change its own password */
|
|
|
b69e47 |
+ pb_conn->c_needpw = 1;
|
|
|
b69e47 |
+ t = 0;
|
|
|
b69e47 |
+ /* We need to include "changeafterreset" error in
|
|
|
b69e47 |
+ * passwordpolicy response control. So, we will not be
|
|
|
b69e47 |
+ * done here. We remember this scenario by (c_needpw=1)
|
|
|
b69e47 |
+ * and check it before sending the control from various
|
|
|
b69e47 |
+ * places. We will also add LDAP_CONTROL_PWEXPIRED control
|
|
|
b69e47 |
+ * as the return value used to be (1).
|
|
|
b69e47 |
+ */
|
|
|
b69e47 |
+ goto skip;
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ /* Mark that first login occured */
|
|
|
b69e47 |
+ pw_exp_date = NOT_FIRST_TIME;
|
|
|
b69e47 |
+ timestring = format_genTime(pw_exp_date);
|
|
|
b69e47 |
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
|
|
b69e47 |
+ slapi_ch_free_string(×tring);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
|
|
|
b69e47 |
skip:
|
|
|
b69e47 |
- /* if password never expires, don't need to go on; return 0 */
|
|
|
b69e47 |
- if ( pwpolicy->pw_exp == 0 ) {
|
|
|
b69e47 |
- /* check for "changeafterreset" condition */
|
|
|
b69e47 |
- if (pb->pb_conn->c_needpw == 1) {
|
|
|
b69e47 |
- if (pwresponse_req) {
|
|
|
b69e47 |
- slapi_pwpolicy_make_response_control ( pb, -1, -1, LDAP_PWPOLICY_CHGAFTERRESET );
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
- slapi_mods_done(&smods);
|
|
|
b69e47 |
- return ( 0 );
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- /* check if password expired. If so, abort bind. */
|
|
|
b69e47 |
- cur_time_str = format_genTime ( cur_time );
|
|
|
b69e47 |
- if ((pw_exp_date != NO_TIME) && (pw_exp_date != NOT_FIRST_TIME) &&
|
|
|
b69e47 |
- (diff_t = difftime(pw_exp_date, parse_genTime(cur_time_str))) <= 0) {
|
|
|
b69e47 |
- slapi_ch_free_string(&cur_time_str); /* only need this above */
|
|
|
b69e47 |
- /* password has expired. Check the value of
|
|
|
b69e47 |
- * passwordGraceUserTime and compare it
|
|
|
b69e47 |
- * against the value of passwordGraceLimit */
|
|
|
b69e47 |
- pwdGraceUserTime = slapi_entry_attr_get_int( e, "passwordGraceUserTime");
|
|
|
b69e47 |
- if ( pwpolicy->pw_gracelimit > pwdGraceUserTime ) {
|
|
|
b69e47 |
- pwdGraceUserTime++;
|
|
|
b69e47 |
- sprintf ( graceUserTime, "%d", pwdGraceUserTime );
|
|
|
b69e47 |
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE,
|
|
|
b69e47 |
- "passwordGraceUserTime", graceUserTime);
|
|
|
b69e47 |
- pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
- slapi_mods_done(&smods);
|
|
|
b69e47 |
- if (pwresponse_req) {
|
|
|
b69e47 |
- /* check for "changeafterreset" condition */
|
|
|
b69e47 |
- if (pb->pb_conn->c_needpw == 1) {
|
|
|
b69e47 |
- slapi_pwpolicy_make_response_control( pb, -1,
|
|
|
b69e47 |
- ((pwpolicy->pw_gracelimit) - pwdGraceUserTime),
|
|
|
b69e47 |
- LDAP_PWPOLICY_CHGAFTERRESET);
|
|
|
b69e47 |
- } else {
|
|
|
b69e47 |
- slapi_pwpolicy_make_response_control( pb, -1,
|
|
|
b69e47 |
- ((pwpolicy->pw_gracelimit) - pwdGraceUserTime),
|
|
|
b69e47 |
- -1);
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- if (pb->pb_conn->c_needpw == 1) {
|
|
|
b69e47 |
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- return ( 0 );
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- /* password expired and user exceeded limit of grace attemps.
|
|
|
b69e47 |
- * Send result and also the control */
|
|
|
b69e47 |
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
b69e47 |
- if (pwresponse_req) {
|
|
|
b69e47 |
- slapi_pwpolicy_make_response_control ( pb, -1, -1, LDAP_PWPOLICY_PWDEXPIRED );
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- slapi_send_ldap_result ( pb, LDAP_INVALID_CREDENTIALS, NULL,
|
|
|
b69e47 |
- "password expired!", 0, NULL );
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- /* abort bind */
|
|
|
b69e47 |
- /* pass pb to do_unbind(). pb->pb_op->o_opid and
|
|
|
b69e47 |
- pb->pb_op->o_tag are not right but I don't see
|
|
|
b69e47 |
- do_unbind() checking for those. We might need to
|
|
|
b69e47 |
- create a pb for unbind operation. Also do_unbind calls
|
|
|
b69e47 |
- pre and post ops. Maybe we don't want to call them */
|
|
|
b69e47 |
- if (pb->pb_conn && (LDAP_VERSION2 == pb->pb_conn->c_ldapversion)) {
|
|
|
b69e47 |
- /* We close the connection only with LDAPv2 connections */
|
|
|
b69e47 |
- disconnect_server( pb->pb_conn, pb->pb_op->o_connid,
|
|
|
b69e47 |
- pb->pb_op->o_opid, SLAPD_DISCONNECT_UNBIND, 0);
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- /* Apply current modifications */
|
|
|
b69e47 |
- pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
- slapi_mods_done(&smods);
|
|
|
b69e47 |
- return (-1);
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- slapi_ch_free((void **) &cur_time_str );
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- /* check if password is going to expire within "passwordWarning" */
|
|
|
b69e47 |
- /* Note that if pw_exp_date is NO_TIME or NOT_FIRST_TIME,
|
|
|
b69e47 |
- * we must send warning first and this changes the expiration time.
|
|
|
b69e47 |
- * This is done just below since diff_t is 0
|
|
|
b69e47 |
- */
|
|
|
b69e47 |
- if ( diff_t <= pwpolicy->pw_warning ) {
|
|
|
b69e47 |
- int pw_exp_warned = 0;
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- pw_exp_warned = slapi_entry_attr_get_int( e, "passwordExpWarned");
|
|
|
b69e47 |
- if ( !pw_exp_warned ){
|
|
|
b69e47 |
- /* first time send out a warning */
|
|
|
b69e47 |
- /* reset the expiration time to current + warning time
|
|
|
b69e47 |
- * and set passwordExpWarned to true
|
|
|
b69e47 |
- */
|
|
|
b69e47 |
- if (pb->pb_conn->c_needpw != 1) {
|
|
|
b69e47 |
- pw_exp_date = time_plus_sec(cur_time, pwpolicy->pw_warning);
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- timestring = format_genTime(pw_exp_date);
|
|
|
b69e47 |
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
|
|
b69e47 |
- slapi_ch_free_string(×tring);
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpWarned", "1");
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- *t = pwpolicy->pw_warning;
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- } else {
|
|
|
b69e47 |
- *t = (long)diff_t; /* jcm: had to cast double to long */
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
- slapi_mods_done(&smods);
|
|
|
b69e47 |
- if (pwresponse_req) {
|
|
|
b69e47 |
- /* check for "changeafterreset" condition */
|
|
|
b69e47 |
- if (pb->pb_conn->c_needpw == 1) {
|
|
|
b69e47 |
- slapi_pwpolicy_make_response_control( pb, *t, -1,
|
|
|
b69e47 |
- LDAP_PWPOLICY_CHGAFTERRESET);
|
|
|
b69e47 |
- } else {
|
|
|
b69e47 |
- slapi_pwpolicy_make_response_control( pb, *t, -1,
|
|
|
b69e47 |
- -1);
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- if (pb->pb_conn->c_needpw == 1) {
|
|
|
b69e47 |
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- return (2);
|
|
|
b69e47 |
- } else {
|
|
|
b69e47 |
- if (pwresponse_req && pwpolicy->pw_send_expiring) {
|
|
|
b69e47 |
- slapi_pwpolicy_make_response_control( pb, diff_t, -1, -1);
|
|
|
b69e47 |
- slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, diff_t);
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
- slapi_mods_done(&smods);
|
|
|
b69e47 |
- /* Leftover from "changeafterreset" condition */
|
|
|
b69e47 |
- if (pb->pb_conn->c_needpw == 1) {
|
|
|
b69e47 |
- slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
- /* passes checking, return 0 */
|
|
|
b69e47 |
- return( 0 );
|
|
|
b69e47 |
+ /* if password never expires, don't need to go on; return 0 */
|
|
|
b69e47 |
+ if (pwpolicy->pw_exp == 0) {
|
|
|
b69e47 |
+ /* check for "changeafterreset" condition */
|
|
|
b69e47 |
+ if (pb_conn->c_needpw == 1) {
|
|
|
b69e47 |
+ if (pwresponse_req) {
|
|
|
b69e47 |
+ slapi_pwpolicy_make_response_control(pb, -1, -1, LDAP_PWPOLICY_CHGAFTERRESET);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
+ slapi_mods_done(&smods);
|
|
|
b69e47 |
+ return (0);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ /* check if password expired. If so, abort bind. */
|
|
|
b69e47 |
+ cur_time_str = format_genTime(cur_time);
|
|
|
b69e47 |
+ if ((pw_exp_date != NO_TIME) && (pw_exp_date != NOT_FIRST_TIME) &&
|
|
|
b69e47 |
+ (diff_t = difftime(pw_exp_date, parse_genTime(cur_time_str))) <= 0) {
|
|
|
b69e47 |
+ slapi_ch_free_string(&cur_time_str); /* only need this above */
|
|
|
b69e47 |
+ /* password has expired. Check the value of
|
|
|
b69e47 |
+ * passwordGraceUserTime and compare it
|
|
|
b69e47 |
+ * against the value of passwordGraceLimit */
|
|
|
b69e47 |
+ pwdGraceUserTime = slapi_entry_attr_get_int(e, "passwordGraceUserTime");
|
|
|
b69e47 |
+ if (pwpolicy->pw_gracelimit > pwdGraceUserTime) {
|
|
|
b69e47 |
+ pwdGraceUserTime++;
|
|
|
b69e47 |
+ sprintf(graceUserTime, "%d", pwdGraceUserTime);
|
|
|
b69e47 |
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE,
|
|
|
b69e47 |
+ "passwordGraceUserTime", graceUserTime);
|
|
|
b69e47 |
+ pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
+ slapi_mods_done(&smods);
|
|
|
b69e47 |
+ if (pwresponse_req) {
|
|
|
b69e47 |
+ /* check for "changeafterreset" condition */
|
|
|
b69e47 |
+ if (pb_conn->c_needpw == 1) {
|
|
|
b69e47 |
+ slapi_pwpolicy_make_response_control(pb, -1,
|
|
|
b69e47 |
+ ((pwpolicy->pw_gracelimit) - pwdGraceUserTime),
|
|
|
b69e47 |
+ LDAP_PWPOLICY_CHGAFTERRESET);
|
|
|
b69e47 |
+ } else {
|
|
|
b69e47 |
+ slapi_pwpolicy_make_response_control(pb, -1,
|
|
|
b69e47 |
+ ((pwpolicy->pw_gracelimit) - pwdGraceUserTime),
|
|
|
b69e47 |
+ -1);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
b69e47 |
+ return (0);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ /* password expired and user exceeded limit of grace attemps.
|
|
|
b69e47 |
+ * Send result and also the control */
|
|
|
b69e47 |
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
b69e47 |
+ if (pwresponse_req) {
|
|
|
b69e47 |
+ slapi_pwpolicy_make_response_control(pb, -1, -1, LDAP_PWPOLICY_PWDEXPIRED);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL,
|
|
|
b69e47 |
+ "password expired!", 0, NULL);
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ /* abort bind */
|
|
|
b69e47 |
+ /* pass pb to do_unbind(). pb->pb_op->o_opid and
|
|
|
b69e47 |
+ pb->pb_op->o_tag are not right but I don't see
|
|
|
b69e47 |
+ do_unbind() checking for those. We might need to
|
|
|
b69e47 |
+ create a pb for unbind operation. Also do_unbind calls
|
|
|
b69e47 |
+ pre and post ops. Maybe we don't want to call them */
|
|
|
b69e47 |
+ if (pb_conn && (LDAP_VERSION2 == pb_conn->c_ldapversion)) {
|
|
|
b69e47 |
+ Operation *pb_op = NULL;
|
|
|
b69e47 |
+ slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);
|
|
|
b69e47 |
+ /* We close the connection only with LDAPv2 connections */
|
|
|
b69e47 |
+ disconnect_server(pb_conn, pb_op->o_connid,
|
|
|
b69e47 |
+ pb_op->o_opid, SLAPD_DISCONNECT_UNBIND, 0);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ /* Apply current modifications */
|
|
|
b69e47 |
+ pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
+ slapi_mods_done(&smods);
|
|
|
b69e47 |
+ return (-1);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ slapi_ch_free((void **)&cur_time_str);
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ /* check if password is going to expire within "passwordWarning" */
|
|
|
b69e47 |
+ /* Note that if pw_exp_date is NO_TIME or NOT_FIRST_TIME,
|
|
|
b69e47 |
+ * we must send warning first and this changes the expiration time.
|
|
|
b69e47 |
+ * This is done just below since diff_t is 0
|
|
|
b69e47 |
+ */
|
|
|
b69e47 |
+ if (diff_t <= pwpolicy->pw_warning) {
|
|
|
b69e47 |
+ int pw_exp_warned = 0;
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ pw_exp_warned = slapi_entry_attr_get_int(e, "passwordExpWarned");
|
|
|
b69e47 |
+ if (!pw_exp_warned) {
|
|
|
b69e47 |
+ /* first time send out a warning */
|
|
|
b69e47 |
+ /* reset the expiration time to current + warning time
|
|
|
b69e47 |
+ * and set passwordExpWarned to true
|
|
|
b69e47 |
+ */
|
|
|
b69e47 |
+ if (pb_conn->c_needpw != 1) {
|
|
|
b69e47 |
+ pw_exp_date = time_plus_sec(cur_time, pwpolicy->pw_warning);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ timestring = format_genTime(pw_exp_date);
|
|
|
b69e47 |
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpirationTime", timestring);
|
|
|
b69e47 |
+ slapi_ch_free_string(×tring);
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordExpWarned", "1");
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ t = pwpolicy->pw_warning;
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ } else {
|
|
|
b69e47 |
+ t = (long)diff_t; /* jcm: had to cast double to long */
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
+ slapi_mods_done(&smods);
|
|
|
b69e47 |
+ if (pwresponse_req) {
|
|
|
b69e47 |
+ /* check for "changeafterreset" condition */
|
|
|
b69e47 |
+ if (pb_conn->c_needpw == 1) {
|
|
|
b69e47 |
+ slapi_pwpolicy_make_response_control(pb, t, -1, LDAP_PWPOLICY_CHGAFTERRESET);
|
|
|
b69e47 |
+ } else {
|
|
|
b69e47 |
+ slapi_pwpolicy_make_response_control(pb, t, -1, -1);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ if (pb_conn->c_needpw == 1) {
|
|
|
b69e47 |
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
b69e47 |
+ } else {
|
|
|
b69e47 |
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ return (0);
|
|
|
b69e47 |
+ } else {
|
|
|
b69e47 |
+ if (pwresponse_req && pwpolicy->pw_send_expiring) {
|
|
|
b69e47 |
+ slapi_pwpolicy_make_response_control(pb, diff_t, -1, -1);
|
|
|
b69e47 |
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, diff_t);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+
|
|
|
b69e47 |
+ pw_apply_mods(sdn, &smods);
|
|
|
b69e47 |
+ slapi_mods_done(&smods);
|
|
|
b69e47 |
+ /* Leftover from "changeafterreset" condition */
|
|
|
b69e47 |
+ if (pb_conn->c_needpw == 1) {
|
|
|
b69e47 |
+ slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
b69e47 |
+ }
|
|
|
b69e47 |
+ /* passes checking, return 0 */
|
|
|
b69e47 |
+ return (0);
|
|
|
b69e47 |
}
|
|
|
b69e47 |
|
|
|
b69e47 |
/* Called once from main */
|
|
|
b69e47 |
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
|
|
|
b69e47 |
index dd0c4fb..134f5aa 100644
|
|
|
b69e47 |
--- a/ldap/servers/slapd/saslbind.c
|
|
|
b69e47 |
+++ b/ldap/servers/slapd/saslbind.c
|
|
|
b69e47 |
@@ -859,7 +859,6 @@ ids_sasl_mech_supported(Slapi_PBlock *pb, const char *mech)
|
|
|
b69e47 |
void ids_sasl_check_bind(Slapi_PBlock *pb)
|
|
|
b69e47 |
{
|
|
|
b69e47 |
int rc, isroot;
|
|
|
b69e47 |
- long t;
|
|
|
b69e47 |
sasl_conn_t *sasl_conn;
|
|
|
b69e47 |
struct propctx *propctx;
|
|
|
b69e47 |
sasl_ssf_t *ssfp;
|
|
|
b69e47 |
@@ -1096,23 +1095,8 @@ sasl_check_result:
|
|
|
b69e47 |
set_db_default_result_handlers(pb);
|
|
|
b69e47 |
|
|
|
b69e47 |
/* check password expiry */
|
|
|
b69e47 |
- if (!isroot) {
|
|
|
b69e47 |
- int pwrc;
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- pwrc = need_new_pw(pb, &t, bind_target_entry, pwresponse_requested);
|
|
|
b69e47 |
-
|
|
|
b69e47 |
- switch (pwrc) {
|
|
|
b69e47 |
- case 1:
|
|
|
b69e47 |
- slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
b69e47 |
- break;
|
|
|
b69e47 |
- case 2:
|
|
|
b69e47 |
- slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t);
|
|
|
b69e47 |
- break;
|
|
|
b69e47 |
- case -1:
|
|
|
b69e47 |
- goto out;
|
|
|
b69e47 |
- default:
|
|
|
b69e47 |
- break;
|
|
|
b69e47 |
- }
|
|
|
b69e47 |
+ if (!isroot && need_new_pw(pb, bind_target_entry, pwresponse_requested) == -1) {
|
|
|
b69e47 |
+ goto out;
|
|
|
b69e47 |
}
|
|
|
b69e47 |
|
|
|
b69e47 |
/* attach the sasl data */
|
|
|
b69e47 |
--
|
|
|
b69e47 |
2.9.5
|
|
|
b69e47 |
|