#include "portable.h"
/* This file implements "Password Policy for LDAP Directories",
- * based on draft behera-ldap-password-policy-07
+ * based on draft behera-ldap-password-policy-08
*/
#ifdef SLAPD_OVER_PPOLICY
int pwdMinLength; /* minimum number of chars in password */
int pwdExpireWarning; /* number of seconds that warning controls are
sent before a password expires */
- int pwdGraceLoginLimit; /* number of times you can log in with an
+ int pwdGraceAuthNLimit; /* number of times you can log in with an
expired password */
int pwdLockout; /* 0 = do not lockout passwords, 1 = lock them out */
int pwdLockoutDuration; /* time in seconds a password is locked out for */
/* Operational attributes */
static AttributeDescription *ad_pwdChangedTime, *ad_pwdAccountLockedTime,
- *ad_pwdExpirationWarned, *ad_pwdFailureTime, *ad_pwdHistory,
- *ad_pwdGraceUseTime, *ad_pwdReset, *ad_pwdPolicySubentry;
+ *ad_pwdFailureTime, *ad_pwdHistory, *ad_pwdGraceUseTime, *ad_pwdReset,
+ *ad_pwdPolicySubentry;
static struct schema_info {
char *def;
"EQUALITY generalizedTimeMatch "
"ORDERING generalizedTimeOrderingMatch "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
- "SINGLE-VALUE USAGE directoryOperation )",
+ "SINGLE-VALUE USAGE directoryOperation NO-USER-MODIFICATION )",
&ad_pwdChangedTime },
{ "( 1.3.6.1.4.1.42.2.27.8.1.17 "
"NAME ( 'pwdAccountLockedTime' ) "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
"SINGLE-VALUE USAGE directoryOperation )",
&ad_pwdAccountLockedTime },
- { "( 1.3.6.1.4.1.42.2.27.8.1.18 "
- "NAME ( 'pwdExpirationWarned' ) "
- "DESC 'The time the user was first warned about the coming expiration of the password' "
- "EQUALITY generalizedTimeMatch "
- "ORDERING generalizedTimeOrderingMatch "
- "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
- "SINGLE-VALUE USAGE directoryOperation )",
- &ad_pwdExpirationWarned },
{ "( 1.3.6.1.4.1.42.2.27.8.1.19 "
"NAME ( 'pwdFailureTime' ) "
"DESC 'The timestamps of the last consecutive authentication failures' "
"DESC 'The history of users passwords' "
"EQUALITY octetStringMatch "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 "
- "USAGE directoryOperation )",
+ "USAGE directoryOperation NO-USER-MODIFICATION )",
&ad_pwdHistory },
{ "( 1.3.6.1.4.1.42.2.27.8.1.21 "
"NAME ( 'pwdGraceUseTime' ) "
"DESC 'The timestamps of the grace login once the password has expired' "
"EQUALITY generalizedTimeMatch "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "
- "USAGE directoryOperation )",
+ "USAGE directoryOperation NO-USER-MODIFICATION )",
&ad_pwdGraceUseTime },
{ "( 1.3.6.1.4.1.42.2.27.8.1.22 "
"NAME ( 'pwdReset' ) "
/* User attributes */
static AttributeDescription *ad_pwdMinAge, *ad_pwdMaxAge, *ad_pwdInHistory,
*ad_pwdCheckQuality, *ad_pwdMinLength, *ad_pwdMaxFailure,
- *ad_pwdGraceLoginLimit, *ad_pwdExpireWarning, *ad_pwdLockoutDuration,
+ *ad_pwdGraceAuthNLimit, *ad_pwdExpireWarning, *ad_pwdLockoutDuration,
*ad_pwdFailureCountInterval, *ad_pwdCheckModule, *ad_pwdLockout,
*ad_pwdMustChange, *ad_pwdAllowUserChange, *ad_pwdSafeModify,
*ad_pwdAttribute;
TAB(pwdCheckQuality),
TAB(pwdMinLength),
TAB(pwdMaxFailure),
- TAB(pwdGraceLoginLimit),
+ TAB(pwdGraceAuthNLimit),
TAB(pwdExpireWarning),
TAB(pwdLockout),
TAB(pwdLockoutDuration),
pp->pwdMinLength = atoi(a->a_vals[0].bv_val );
if ((a = attr_find( pe->e_attrs, ad_pwdMaxFailure )))
pp->pwdMaxFailure = atoi(a->a_vals[0].bv_val );
- if ((a = attr_find( pe->e_attrs, ad_pwdGraceLoginLimit )))
- pp->pwdGraceLoginLimit = atoi(a->a_vals[0].bv_val );
+ if ((a = attr_find( pe->e_attrs, ad_pwdGraceAuthNLimit )))
+ pp->pwdGraceAuthNLimit = atoi(a->a_vals[0].bv_val );
if ((a = attr_find( pe->e_attrs, ad_pwdExpireWarning )))
pp->pwdExpireWarning = atoi(a->a_vals[0].bv_val );
if ((a = attr_find( pe->e_attrs, ad_pwdFailureCountInterval )))
if (!pwExpired) goto check_expiring_password;
if ((a = attr_find( e->e_attrs, ad_pwdGraceUseTime )) == NULL)
- ngut = ppb->pp.pwdGraceLoginLimit;
+ ngut = ppb->pp.pwdGraceAuthNLimit;
else {
for(ngut=0; a->a_nvals[ngut].bv_val; ngut++);
- ngut = ppb->pp.pwdGraceLoginLimit - ngut;
+ ngut = ppb->pp.pwdGraceAuthNLimit - ngut;
}
/*
*/
if (ppb->pp.pwdMaxAge - age < ppb->pp.pwdExpireWarning ) {
/*
- * Set the warning value, add expiration warned timestamp to the entry.
+ * Set the warning value.
*/
- if ((a = attr_find( e->e_attrs, ad_pwdExpirationWarned )) == NULL) {
- m = ch_calloc( sizeof(Modifications), 1 );
- m->sml_op = LDAP_MOD_ADD;
- m->sml_type = ad_pwdExpirationWarned->ad_cname;
- m->sml_desc = ad_pwdExpirationWarned;
- m->sml_values = ch_calloc( sizeof(struct berval), 2 );
- ber_str2bv( nowstr, 0, 1, &m->sml_values[0] );
- m->sml_next = mod;
- mod = m;
- }
-
warn = ppb->pp.pwdMaxAge - age; /* seconds left until expiry */
if (warn < 0) warn = 0; /* something weird here - why is pwExpired not set? */
rs->sr_ctrls = ctrls;
}
op->o_bd->bd_info = (BackendInfo *)on->on_info;
- send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
+ send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS,
"Operations are restricted to bind/unbind/abandon/StartTLS/modify password" );
return rs->sr_err;
}
if (pwcons[op->o_conn->c_conn_idx].restrict && !mod_pw_only) {
Debug( LDAP_DEBUG_TRACE,
"connection restricted to password changing only\n", 0, 0, 0 );
- rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
rs->sr_text = "Operations are restricted to bind/unbind/abandon/StartTLS/modify password";
pErr = PP_changeAfterReset;
goto return_results;
Debug( LDAP_DEBUG_TRACE,
"change password must use DELETE followed by ADD/REPLACE\n",
0, 0, 0 );
- rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
rs->sr_text = "Must supply old password to be changed as well as new one";
pErr = PP_mustSupplyOldPassword;
goto return_results;
}
if (!pp.pwdAllowUserChange) {
- rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
rs->sr_text = "User alteration of password is not allowed";
pErr = PP_passwordModNotAllowed;
goto return_results;
now = slap_get_time();
age = (int)(now - pwtime);
if ((pwtime != (time_t)-1) && (age < pp.pwdMinAge)) {
- rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
rs->sr_text = "Password is too young to change";
pErr = PP_passwordTooYoung;
goto return_results;
modtail = mods;
}
- if (attr_find(e->e_attrs, ad_pwdExpirationWarned )) {
- mods = (Modifications *) ch_malloc( sizeof( Modifications ) );
- mods->sml_op = LDAP_MOD_DELETE;
- mods->sml_type.bv_val = NULL;
- mods->sml_desc = ad_pwdExpirationWarned;
- mods->sml_values = NULL;
- mods->sml_nvalues = NULL;
- mods->sml_next = NULL;
- modtail->sml_next = mods;
- modtail = mods;
- }
-
/* Delete the pwdReset attribute, since it's being reset */
if ((zapReset) && (attr_find(e->e_attrs, ad_pwdReset ))) {
mods = (Modifications *) ch_malloc( sizeof( Modifications ) );
return 0;
}
+static int
+ppolicy_db_open(
+ BackendDB *be
+)
+{
+ return overlay_register_control( be, LDAP_CONTROL_PASSWORDPOLICYREQUEST );
+}
+
static int
ppolicy_close(
BackendDB *be
ldap_scherr2str(code), err );
return code;
}
- code = at_add( at, &err );
+ code = at_add( at, 0, NULL, &err );
if ( !code ) {
slap_str2ad( at->at_names[0], pwd_OpSchema[i].ad, &err );
}
ppolicy.on_bi.bi_type = "ppolicy";
ppolicy.on_bi.bi_db_init = ppolicy_db_init;
+ ppolicy.on_bi.bi_db_open = ppolicy_db_open;
ppolicy.on_bi.bi_db_config = ppolicy_config;
ppolicy.on_bi.bi_db_close = ppolicy_close;