diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/LDAP.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/LDAP.pm index 78178ca3f..b60789ca9 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/LDAP.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/LDAP.pm @@ -24,14 +24,12 @@ sub authenticate { } my $res = - $self->ldap->userBind( $req->datas->{dn}, - password => $req->datas->{password} ); + $self->userBind( $req->datas->{dn}, password => $req->datas->{password} ); # Remember password if password reset needed $req->datas->{oldpassword} = $self->{password} if ( $res == PE_PP_CHANGE_AFTER_RESET ); - $self->ldap->unbind; return $res; } @@ -44,4 +42,15 @@ sub authForce { PE_OK; } +# Test LDAP connection before trying to bind +sub userBind { + my $self = shift; + unless ($self->ldap + and $self->ldap->root_dse( attrs => ['supportedLDAPVersion'] ) ) + { + $self->ldap( $self->newLdap ); + } + return $self->ldap ? $self->ldap->userBind(@_) : undef; +} + 1; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/LDAP.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/LDAP.pm index b79f3babc..d597062ec 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/LDAP.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/LDAP.pm @@ -9,6 +9,7 @@ use base qw(Net::LDAP); use Lemonldap::NG::Portal::Main::Constants; use Encode; use Unicode::String qw(utf8); +use Scalar::Util 'weaken'; our $VERSION = '2.0.0'; our $ppLoaded = 0; @@ -66,6 +67,7 @@ sub new { } $self->{portal} = $portal; $self->{conf} = $conf; + weaken $self->{portal}; # Setting default LDAP password storage encoding to utf-8 $self->{conf}->{ldapPwdEnc} ||= 'utf-8'; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/LDAP.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/LDAP.pm index af287e331..12c8a52ec 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/LDAP.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDB/LDAP.pm @@ -12,36 +12,35 @@ our $VERSION = '2.0.0'; has ldap => ( is => 'rw', lazy => 1, - builder => sub { - my $self = $_[0]; - my $ldap; + builder => 'newLdap'; +); - # Build object and test LDAP connexion - if ( - $ldap = Lemonldap::NG::Portal::Lib::LDAP->new( - { p => $self->{p}, conf => $self->{conf} } - ) - and my $msg = $ldap->bind - ) - { - if ( $msg->code != 0 ) { - $self->lmLog( "LDAP error: " . $msg->error, 'error' ); - } - else { - if ( $self->{conf}->{ldapPpolicyControl} - and not $ldap->loadPP() ) - { - $self->lmLog( "LDAP password policy error", 'error' ); - } - } +sub newLdap { + my $self = $_[0]; + my $ldap; + + # Build object and test LDAP connexion + if ( + $ldap = Lemonldap::NG::Portal::Lib::LDAP->new( + { p => $self->{p}, conf => $self->{conf} } + ) + and my $msg = $ldap->bind + ) + { + if ( $msg->code != 0 ) { + $self->lmLog( "LDAP error: " . $msg->error, 'error' ); } else { - $self->lmLog( "LDAP error: $@", 'error' ); + if ( $self->{conf}->{ldapPpolicyControl} and not $ldap->loadPP() ) { + $self->lmLog( "LDAP password policy error", 'error' ); + } } - $ldap->unbind; - return $ldap; } -); + else { + $self->lmLog( "LDAP error: $@", 'error' ); + } + return $ldap; +} has ldapGroupAttributeNameSearch => ( is => 'rw', @@ -101,9 +100,20 @@ sub init { $self->ldap and $self->filter; } +# Test LDAP connection before trying to bind +sub bind { + my $self = shift; + unless ($self->ldap + and $self->ldap->root_dse( attrs => ['supportedLDAPVersion'] ) ) + { + $self->ldap( $self->newLdap ); + } + return $self->ldap ? $self->ldap->bind(@_) : undef; +} + sub getUser { my ( $self, $req ) = @_; - return PE_LDAPCONNECTFAILED unless $self->ldap and $self->ldap->bind(); + return PE_LDAPCONNECTFAILED unless $self->ldap and $self->bind(); my $mesg = $self->ldap->search( base => $self->conf->{ldapBase}, scope => 'sub', @@ -113,19 +123,16 @@ sub getUser { ); if ( $mesg->code() != 0 ) { $self->lmLog( 'LDAP Search error: ' . $mesg->error, 'error' ); - $self->ldap->unbind; return PE_LDAPERROR; } if ( $mesg->count() > 1 ) { $self->lmLog( 'More than one entry returned by LDAP directory', 'error' ); - $self->ldap->unbind; return PE_BADCREDENTIALS; } unless ( $req->datas->entry( $mesg->entry(0) ) ) { my $user = $req->{mail} || $req->{user}; $self->_sub( 'userError', "$user was not found in LDAP directory" ); - $self->ldap->unbind; return PE_BADCREDENTIALS; } $req->datas->{dn} = $req->datas->{entry}->dn(); @@ -193,7 +200,6 @@ sub setGroups { } $self->{sessionInfo}->{groups} = $groups; - $self->ldap->unbind; PE_OK; }