ldap/servers/slapd/libglobs.c | 30 ++++++++++++++++++++++++++++++
ldap/servers/slapd/proto-slap.h | 1 +
ldap/servers/slapd/pw.h | 2 +-
ldap/servers/slapd/pw_retry.c | 38 +++++++++++++++++++++++---------------
ldap/servers/slapd/result.c | 10 +++++++++-
ldap/servers/slapd/slap.h | 2 ++
6 files changed, 66 insertions(+), 17 deletions(-)
New commits:
commit 396c9320f51c751e040da97ba8396c0f36de88f1
Author: Mark Reynolds <mareynol(a)redhat.com>
Date: Thu Apr 5 22:40:01 2012 -0400
Ticket #183 - passwordMaxFailure should lockout password one sooner - and should be
configurable to avoid regressions
Bug Description: DS doesn't return error LDAP_CONSTRAINT_VIOLATION until after
the retry limit is exceeded
Fix Description: DS has essentially locked the account, but we didn't log the
error until
the next bind. Added a new config option
"passwordLegacyPolicy: on|off"
that will trigger the error LDAP_CONSTRAINT_VIOLATION, if
"legacy" is off,
when the limit is actually reached. The default is to continue to
do
things the "old" way, or legacy "on".
https://fedorahosted.org/389/ticket/183
reviewed by: Noriko (Thanks!)
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 8bcd544..d5b8faf 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -373,6 +373,9 @@ static struct config_get_and_set {
{CONFIG_PW_ISGLOBAL_ATTRIBUTE, config_set_pw_is_global_policy,
NULL, 0,
(void**)&global_slapdFrontendConfig.pw_is_global_policy, CONFIG_ON_OFF, NULL},
+ {CONFIG_PW_IS_LEGACY, config_set_pw_is_legacy_policy,
+ NULL, 0,
+ (void**)&global_slapdFrontendConfig.pw_policy.pw_is_legacy, CONFIG_ON_OFF, NULL},
{CONFIG_AUDITLOG_MAXNUMOFLOGSPERDIR_ATTRIBUTE, NULL,
log_set_numlogsperdir, SLAPD_AUDIT_LOG,
(void**)&global_slapdFrontendConfig.auditlog_maxnumlogs, CONFIG_INT, NULL},
@@ -1017,6 +1020,7 @@ FrontendConfig_init () {
cfg->pw_policy.pw_lockduration = 3600; /* 60 minutes */
cfg->pw_policy.pw_resetfailurecount = 600; /* 10 minutes */
cfg->pw_policy.pw_gracelimit = 0;
+ cfg->pw_policy.pw_is_legacy = LDAP_ON;
cfg->pw_is_global_policy = LDAP_OFF;
cfg->accesslog_logging_enabled = LDAP_ON;
@@ -2417,6 +2421,20 @@ config_set_pw_is_global_policy( const char *attrname, char *value,
char *errorbu
}
int
+config_set_pw_is_legacy_policy( const char *attrname, char *value, char *errorbuf, int
apply ) {
+ int retVal = LDAP_SUCCESS;
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+ retVal = config_set_onoff ( attrname,
+ value,
+ &(slapdFrontendConfig->pw_policy.pw_is_legacy),
+ errorbuf,
+ apply);
+
+ return retVal;
+}
+
+int
config_set_pw_exp( const char *attrname, char *value, char *errorbuf, int apply ) {
int retVal = LDAP_SUCCESS;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -4235,6 +4253,18 @@ config_get_pw_is_global_policy() {
}
int
+config_get_pw_is_legacy_policy() {
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ int retVal;
+
+ CFG_LOCK_READ(slapdFrontendConfig);
+ retVal = slapdFrontendConfig->pw_policy.pw_is_legacy;
+ CFG_UNLOCK_READ(slapdFrontendConfig);
+
+ return retVal;
+}
+
+int
config_get_pw_exp() {
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
int retVal;
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 9bbcf53..d291be3 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -340,6 +340,7 @@ int config_set_pw_unlock(const char *attrname, char *value, char
*errorbuf, int
int config_set_pw_lockduration(const char *attrname, char *value, char *errorbuf, int
apply );
int config_set_pw_resetfailurecount(const char *attrname, char *value, char *errorbuf,
int apply );
int config_set_pw_is_global_policy(const char *attrname, char *value, char *errorbuf,
int apply );
+int config_set_pw_is_legacy_policy(const char *attrname, char *value, char *errorbuf,
int apply );
int config_set_pw_gracelimit(const char *attrname, char *value, char *errorbuf, int
apply );
int config_set_useroc(const char *attrname, char *value, char *errorbuf, int apply );
int config_set_return_exact_case(const char *attrname, char *value, char *errorbuf, int
apply );
diff --git a/ldap/servers/slapd/pw.h b/ldap/servers/slapd/pw.h
index 83f0003..a470fdd 100644
--- a/ldap/servers/slapd/pw.h
+++ b/ldap/servers/slapd/pw.h
@@ -96,6 +96,6 @@ int check_pw_storagescheme_value( const char *attr_name, char *value,
long minva
* Public functions from pw_retry.c:
*/
Slapi_Entry *get_entry ( Slapi_PBlock *pb, const char *dn );
-void set_retry_cnt_mods ( Slapi_PBlock *pb, Slapi_Mods *smods, int count);
+int set_retry_cnt_mods ( Slapi_PBlock *pb, Slapi_Mods *smods, int count);
#endif /* _SLAPD_PW_H_ */
diff --git a/ldap/servers/slapd/pw_retry.c b/ldap/servers/slapd/pw_retry.c
index 5244622..09d0ed0 100644
--- a/ldap/servers/slapd/pw_retry.c
+++ b/ldap/servers/slapd/pw_retry.c
@@ -50,8 +50,8 @@
/* prototypes */
/****************************************************************************/
/* Slapi_Entry *get_entry ( Slapi_PBlock *pb, const char *dn ); */
-static void set_retry_cnt ( Slapi_PBlock *pb, int count);
-static void set_retry_cnt_and_time ( Slapi_PBlock *pb, int count, time_t cur_time);
+static int set_retry_cnt ( Slapi_PBlock *pb, int count);
+static int set_retry_cnt_and_time ( Slapi_PBlock *pb, int count, time_t cur_time);
/*
* update_pw_retry() is called when bind operation fails
@@ -72,6 +72,7 @@ int update_pw_retry ( Slapi_PBlock *pb )
char *cur_time_str = NULL;
char *retryCountResetTime;
int passwordRetryCount;
+ int rc = 0;
/* get the entry */
e = get_entry ( pb, NULL );
@@ -93,18 +94,18 @@ int update_pw_retry ( Slapi_PBlock *pb )
{
/* set passwordRetryCount to 1 */
/* reset retryCountResetTime */
- set_retry_cnt_and_time ( pb, 1, cur_time );
+ rc = set_retry_cnt_and_time ( pb, 1, cur_time );
slapi_ch_free((void **) &cur_time_str );
slapi_entry_free( e );
- return ( 0 ); /* success */
+ return ( rc ); /* success */
} else {
slapi_ch_free((void **) &cur_time_str );
}
} else {
/* initialize passwordRetryCount and retryCountResetTime */
- set_retry_cnt_and_time ( pb, 1, cur_time );
+ rc = set_retry_cnt_and_time ( pb, 1, cur_time );
slapi_entry_free( e );
- return ( 0 ); /* success */
+ return ( rc ); /* success */
}
passwordRetryCount = slapi_entry_attr_get_int(e, "passwordRetryCount");
if (passwordRetryCount >= 0)
@@ -112,24 +113,25 @@ int update_pw_retry ( Slapi_PBlock *pb )
retry_cnt = passwordRetryCount + 1;
if ( retry_cnt == 1 ) {
/* set retryCountResetTime */
- set_retry_cnt_and_time ( pb, retry_cnt, cur_time );
+ rc = set_retry_cnt_and_time ( pb, retry_cnt, cur_time );
} else {
/* set passwordRetryCount to retry_cnt */
- set_retry_cnt ( pb, retry_cnt );
+ rc = set_retry_cnt ( pb, retry_cnt );
}
}
slapi_entry_free( e );
- return 0; /* success */
+ return rc; /* success */
}
static
-void set_retry_cnt_and_time ( Slapi_PBlock *pb, int count, time_t cur_time ) {
+int set_retry_cnt_and_time ( Slapi_PBlock *pb, int count, time_t cur_time ) {
const char *dn = NULL;
Slapi_DN *sdn = NULL;
Slapi_Mods smods;
time_t reset_time;
char *timestr;
passwdPolicy *pwpolicy = NULL;
+ int rc = 0;
slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
dn = slapi_sdn_get_dn(sdn);
@@ -144,14 +146,16 @@ void set_retry_cnt_and_time ( Slapi_PBlock *pb, int count, time_t
cur_time ) {
slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "retryCountResetTime",
timestr);
slapi_ch_free((void **)×tr);
- set_retry_cnt_mods(pb, &smods, count);
+ rc = set_retry_cnt_mods(pb, &smods, count);
pw_apply_mods(sdn, &smods);
slapi_mods_done(&smods);
delete_passwdPolicy(&pwpolicy);
+
+ return rc;
}
-void set_retry_cnt_mods(Slapi_PBlock *pb, Slapi_Mods *smods, int count)
+int set_retry_cnt_mods(Slapi_PBlock *pb, Slapi_Mods *smods, int count)
{
char *timestr;
time_t unlock_time;
@@ -159,6 +163,7 @@ void set_retry_cnt_mods(Slapi_PBlock *pb, Slapi_Mods *smods, int
count)
const char *dn = NULL;
Slapi_DN *sdn = NULL;
passwdPolicy *pwpolicy = NULL;
+ int rc = 0;
slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
dn = slapi_sdn_get_dn(sdn);
@@ -182,23 +187,26 @@ void set_retry_cnt_mods(Slapi_PBlock *pb, Slapi_Mods *smods, int
count)
timestr= format_genTime ( unlock_time );
slapi_mods_add_string(smods, LDAP_MOD_REPLACE, "accountUnlockTime",
timestr);
slapi_ch_free((void **)×tr);
+ rc = LDAP_CONSTRAINT_VIOLATION;
}
}
delete_passwdPolicy(&pwpolicy);
- return;
+ return rc;
}
static
-void set_retry_cnt ( Slapi_PBlock *pb, int count)
+int set_retry_cnt ( Slapi_PBlock *pb, int count)
{
Slapi_DN *sdn = NULL;
Slapi_Mods smods;
+ int rc = 0;
slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
slapi_mods_init(&smods, 0);
- set_retry_cnt_mods(pb, &smods, count);
+ rc = set_retry_cnt_mods(pb, &smods, count);
pw_apply_mods(sdn, &smods);
slapi_mods_done(&smods);
+ return rc;
}
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
index 6f36a60..4712ea1 100644
--- a/ldap/servers/slapd/result.c
+++ b/ldap/servers/slapd/result.c
@@ -377,7 +377,15 @@ send_ldap_result_ext(
dn = slapi_sdn_get_dn(sdn);
pwpolicy = new_passwdPolicy(pb, dn);
if (pwpolicy && (pwpolicy->pw_lockout == 1)) {
- update_pw_retry ( pb );
+ if(update_pw_retry( pb ) == LDAP_CONSTRAINT_VIOLATION &&
!pwpolicy->pw_is_legacy){
+ /*
+ * If we are not using the legacy pw policy behavior,
+ * convert the error 49 to 19 (constraint violation)
+ * and log a message
+ */
+ err = LDAP_CONSTRAINT_VIOLATION;
+ text = "Invalid credentials, you now have exceeded the password retry
limit.";
+ }
}
}
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index f7c0bf2..669e304 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1952,6 +1952,7 @@ typedef struct _slapdEntryPoints {
#define CONFIG_PW_RESETFAILURECOUNT_ATTRIBUTE "passwordResetFailureCount"
#define CONFIG_PW_ISGLOBAL_ATTRIBUTE "passwordIsGlobalPolicy"
#define CONFIG_PW_GRACELIMIT_ATTRIBUTE "passwordGraceLimit"
+#define CONFIG_PW_IS_LEGACY "passwordLegacyPolicy"
#define CONFIG_ACCESSLOG_BUFFERING_ATTRIBUTE "nsslapd-accesslog-logbuffering"
#define CONFIG_CSNLOGGING_ATTRIBUTE "nsslapd-csnlogging"
#define CONFIG_RETURN_EXACT_CASE_ATTRIBUTE "nsslapd-return-exact-case"
@@ -2039,6 +2040,7 @@ typedef struct passwordpolicyarray {
long pw_lockduration;
long pw_resetfailurecount;
int pw_gracelimit;
+ int pw_is_legacy;
struct pw_scheme *pw_storagescheme;
} passwdPolicy;