Bug 18947: LDAP - do not assume anonymous bind if no user or password

To test:
Ideally tested on a working ldap server with bind by auth and no
anonymous bind
1  - Define an LDAP config with bind by auth
2  - Don't define user/pass
3  - Define anonymous_bind = 0
4  - Attempt bind by auth
5  - Error is something like:
LDAP search failed to return object : XXXXXXXXX: LdapErr: XXXX-XXXXXX,
     comment: In order to perform this operation a successful bind must
     be completed on the connection., data 0, v2580 at
     /usr/share/koha/lib/C4/Auth_with_ldap.pm line 102.
6  - Define user/pass
7  - Now bind by auth should work
8  - remove user/pass
9  - Apply patch
10 - Attempt again
11 - Bind by auth shoudl succeed

prove -v t/db_dependent/Auth_with_ldap.t

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Signed-off-by: Brendan A Gallagher <brendan@bywatersolutions.com>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
(cherry picked from commit 8eed046638)
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
This commit is contained in:
Nick Clemens 2017-12-13 13:27:36 +00:00 committed by Martin Renvoize
parent 63b6ef7cb7
commit 2cb4bbd8ba
No known key found for this signature in database
GPG Key ID: 422B469130441A0F
2 changed files with 25 additions and 9 deletions

View File

@ -60,7 +60,6 @@ my $prefhost = $ldap->{hostname} or die ldapserver_error('hostname');
my $base = $ldap->{base} or die ldapserver_error('base');
$ldapname = $ldap->{user} ;
$ldappassword = $ldap->{pass} ;
$ldap->{anonymous_bind} = 1 unless $ldapname && $ldappassword;
our %mapping = %{$ldap->{mapping}}; # FIXME dpavlin -- don't die because of || (); from 6eaf8511c70eb82d797c941ef528f4310a15e9f9
my @mapkeys = keys %mapping;
$debug and print STDERR "Got ", scalar(@mapkeys), " ldap mapkeys ( total ): ", join ' ', @mapkeys, "\n";
@ -77,7 +76,7 @@ if(defined $ldap->{categorycode_mapping}) {
}
my %config = (
anonymous => ($ldapname and $ldappassword) ? 0 : 1,
anonymous => defined ($ldap->{anonymous_bind}) ? $ldap->{anonymous_bind} : 1,
replicate => defined($ldap->{replicate}) ? $ldap->{replicate} : 1, # add from LDAP to Koha database for new user
update => defined($ldap->{update} ) ? $ldap->{update} : 1, # update from LDAP to Koha database for existing user
);
@ -128,7 +127,7 @@ sub checkpw_ldap {
# first, LDAP authentication
if ( $ldap->{auth_by_bind} ) {
my $principal_name;
if ( $ldap->{anonymous_bind} ) {
if ( $config{anonymous} ) {
# Perform an anonymous bind
my $res = $db->bind;
@ -156,7 +155,7 @@ sub checkpw_ldap {
# Perform a LDAP bind for the given username using the matched DN
my $res = $db->bind( $principal_name, password => $password );
if ( $res->code ) {
if ( $ldap->{anonymous_bind} ) {
if ( $config{anonymous} ) {
# With anonymous_bind approach we can be sure we have found the correct user
# and that any 'code' response indicates a 'bad' user (be that blocked, banned
# or password changed). We should not fall back to local accounts in this case.
@ -177,7 +176,7 @@ sub checkpw_ldap {
$userldapentry = $search->shift_entry;
}
} else {
my $res = ($ldap->{anonymous_bind}) ? $db->bind : $db->bind($ldapname, password=>$ldappassword);
my $res = ($config{anonymous}) ? $db->bind : $db->bind($ldapname, password=>$ldappassword);
if ($res->code) { # connection refused
warn "LDAP bind failed as ldapuser " . ($ldapname || '[ANONYMOUS]') . ": " . description($res);
return 0;

View File

@ -41,6 +41,8 @@ my $update = 0;
my $replicate = 0;
my $auth_by_bind = 1;
my $anonymous_bind = 1;
my $user = 'cn=Manager,dc=metavore,dc=com';
my $pass = 'metavore';
# Variables controlling LDAP behaviour
my $desired_authentication_result = 'success';
@ -143,7 +145,7 @@ subtest 'checkpw_ldap tests' => sub {
subtest 'auth_by_bind = 1 tests' => sub {
plan tests => 9;
plan tests => 11;
$auth_by_bind = 1;
@ -161,6 +163,19 @@ subtest 'checkpw_ldap tests' => sub {
'checkpw_ldap prints correct warning if LDAP anonymous bind fails';
is( $ret, 0, 'checkpw_ldap returns 0 if LDAP anonymous bind fails' );
$anonymous_bind = 0;
$user = undef;
$pass = undef;
reload_ldap_module();
warning_like {
$ret = C4::Auth_with_ldap::checkpw_ldap( $dbh, 'hola',
password => 'hey' );
}
qr/LDAP bind failed as kohauser hola: LDAP error #1: error_name/,
'checkpw_ldap prints correct warning if LDAP bind_by_auth fails';
is( $ret, 0, 'checkpw_ldap returns 0 if LDAP bind_by_auth fails' );
$desired_authentication_result = 'success';
$anonymous_bind = 1;
$desired_admin_bind_result = 'success';
@ -251,8 +266,10 @@ subtest 'checkpw_ldap tests' => sub {
# Anonymous bind
$anonymous_bind = 1;
$user = 'cn=Manager,dc=metavore,dc=com';
$pass = 'metavore';
$desired_admin_bind_result = 'error';
$desired_bind_result = 'error';
$desired_bind_result = 'error';
reload_ldap_module();
warning_like {
@ -361,11 +378,11 @@ sub mockedC4Config {
base => 'dc=metavore,dc=com',
hostname => 'localhost',
mapping => \%ldap_mapping,
pass => 'metavore',
pass => $pass,
principal_name => '%s@my_domain.com',
replicate => $replicate,
update => $update,
user => 'cn=Manager,dc=metavore,dc=com',
user => $user,
);
return \%ldap_config;
}