Login with the expired password displays a login error “Abnormal error from LDAP server” instead of showing Password Form (openldap).
Concerned version
Version: 2.0.15-1 (container alpine built from the source)
Platform: Nginx
Summary
Login with the expired password displays a login error “Abnormal error from LDAP server” instead of showing Password Form.
Logs
2023-03-14 13:53:22 | LLNG[6364]: [error] Error when binding to LDAP server: Invalid credentials | extended ppolicy control response error: password expired
2023-03-14 13:53:22 | LLNG[6364]: [error] Invalid credentials
2023-03-14 13:53:22 | LLNG[6364]: [debug] Returned error: 7 (PE_LDAPERROR)
2023-03-14 13:53:22 | LLNG[6364]: [debug] Display type standardform
2023-03-14 13:53:22 | LLNG[6364]: [debug] Skin returned: login
2023-03-14 13:53:22 | LLNG[6364]: [debug] Calling sendHtml with template login
Backends used
OPENLDAP : 2.6.3
Openldp Password Policy
objectClass: organizationalUnit
dn: cn=passwordDefault,ou=Policies,dc=example,dc=com
objectClass: pwdPolicy
objectClass: person
objectClass: top
cn: passwordDefault
sn: passwordDefault
pwdAttribute: userPassword
pwdCheckQuality: 1
pwdMinAge: 0
pwdMaxAge: 1578000
pwdMinLength: 8
pwdInHistory: 5
pwdMaxFailure: 3
pwdFailureCountInterval: 0
pwdLockout: TRUE
pwdLockoutDuration: 0
pwdAllowUserChange: TRUE
pwdExpireWarning: 0
pwdGraceAuthNLimit: 5
pwdExpireWarning: 60000
pwdMustChange: TRUE
pwdSafeModify: FALSE
LLNG Password Configuration
Details
According to the log (debug), I tried to troubleshooting the problem as follows
the bind to ldap receives error code = 49 (Invalid Credentials) and pp_error = 0 (extended ppolicy control response error: password expired”). It returns “undef” to getUser that ends up with PE_LDAPERROR(7).
The display subroutine receives PE_LDAPERROR and displays “ Abnormal error from LDAP server”
However, in order to be able to show the Password Form, it should receive PE_PP_PASSWORD_EXPIRED.
Consequently, the Password Form is never shown up. Why getUser sends PE_LDAPERROR instead of another appropriate error code like PE_PP_PASSWORD_EXPIRED?
Could you please advice how to unblock this situation and have the Password Form shown up when the password is expired? Thanks in advance.
A similar problem #4444 has been reported but I think it is different
/usr/local/share/perl5/site_perl/Lemonldap/NG/Portal/Lib/LDAP.pm
# RUNNING METHODS
sub getUser {
my ( $self, $req, %args ) = @_;
$self->validateLdap;
return PE_LDAPCONNECTFAILED unless $self->ldap;
return **PE_LDAPERROR** unless $self→bind();
...
# Bind
sub bind {
my $msg = $self->ldap->bind(@_);
if ( $msg->code ) {
$self->logger->error( $msg->error );
return undef;
}
return 1;
/usr/local/share/perl5/site_perl/Lemonldap/NG/Portal/Lib/Net/LDAP.pm
# @return Net::LDAP::Message
sub bind {
my ( $self, $dn, %args ) = @_;
my $mesg;
if ( $mesg->code ) {
$self->{portal}
->logger->error( "Error when binding to LDAP server: "
. $mesg->error
. " | extended ppolicy control response error: $ppolicy_error"
);
return $mesg;
}
/usr/local/share/perl5/site_perl/Lemonldap/NG/Portal/Main/Display.pm
# Call portal process and set template parameters
# @return template name and template parameters
sub display {
...
# Show password form if password policy error
if (
$req->{error} == PE_PP_CHANGE_AFTER_RESET
or $req->{error} == PE_PP_MUST_SUPPLY_OLD_PASSWORD
or $req->{error} == PE_PP_INSUFFICIENT_PASSWORD_QUALITY
or $req->{error} == PE_PP_PASSWORD_TOO_SHORT
or $req->{error} == PE_PP_PASSWORD_TOO_YOUNG
or $req->{error} == PE_PP_PASSWORD_IN_HISTORY
or $req->{error} == PE_PASSWORD_MISMATCH
or $req->{error} == PE_BADOLDPASSWORD
or $req->{error} == PE_PASSWORDFORMEMPTY
or ( $req->{error} == PE_PP_PASSWORD_EXPIRED
and $self->conf->{ldapAllowResetExpiredPassword} )
)
{
%
…