diff --git a/include/ldap.h b/include/ldap.h index 7da3a2f3ee..74385dd0e1 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -2399,6 +2399,7 @@ typedef enum passpolicyerror_enum { PP_passwordTooShort = 6, PP_passwordTooYoung = 7, PP_passwordInHistory = 8, + PP_passwordTooLong = 9, PP_noError = 65535 } LDAPPasswordPolicyError; diff --git a/libraries/libldap/ppolicy.c b/libraries/libldap/ppolicy.c index 041fa850f2..9afbcf3dc8 100644 --- a/libraries/libldap/ppolicy.c +++ b/libraries/libldap/ppolicy.c @@ -206,6 +206,7 @@ ldap_passwordpolicy_err2txt( LDAPPasswordPolicyError err ) case PP_passwordTooShort: return "Password is too short for policy"; case PP_passwordTooYoung: return "Password has been changed too recently"; case PP_passwordInHistory: return "New password is in list of old passwords"; + case PP_passwordTooLong: return "Password is too long for policy"; case PP_noError: return "No error"; default: return "Unknown error code"; } diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c index 8b9e21f7ab..f379c0c4f6 100644 --- a/servers/slapd/overlays/ppolicy.c +++ b/servers/slapd/overlays/ppolicy.c @@ -76,6 +76,7 @@ typedef struct pass_policy { int pwdCheckQuality; /* 0 = don't check quality, 1 = check if possible, 2 = check mandatory; fail if not possible */ int pwdMinLength; /* minimum number of chars in password */ + int pwdMaxLength; /* maximum number of chars in password */ int pwdExpireWarning; /* number of seconds that warning controls are sent before a password expires */ int pwdGraceExpiry; /* number of seconds after expiry grace logins are @@ -715,6 +716,9 @@ ppolicy_get( Operation *op, Entry *e, PassPolicy *pp ) if ( ( a = attr_find( pe->e_attrs, ad_pwdMinLength ) ) && lutil_atoi( &pp->pwdMinLength, a->a_vals[0].bv_val ) != 0 ) goto defaultpol; + if ( ( a = attr_find( pe->e_attrs, ad_pwdMaxLength ) ) + && lutil_atoi( &pp->pwdMaxLength, a->a_vals[0].bv_val ) != 0 ) + goto defaultpol; if ( ( a = attr_find( pe->e_attrs, ad_pwdMaxFailure ) ) && lutil_atoi( &pp->pwdMaxFailure, a->a_vals[0].bv_val ) != 0 ) goto defaultpol; @@ -829,6 +833,12 @@ check_password_quality( struct berval *cred, PassPolicy *pp, LDAPPasswordPolicyE return rc; } + if ( pp->pwdMaxLength && cred->bv_len > pp->pwdMaxLength ) { + rc = LDAP_CONSTRAINT_VIOLATION; + if ( err ) *err = PP_passwordTooLong; + return rc; + } + /* * We need to know if the password is already hashed - if so * what scheme is it. The reason being that the "hash" of