From 0e353d4d421ee5620ba83736d84143b8fcfaeee0 Mon Sep 17 00:00:00 2001 From: Robin Sheat Date: Thu, 29 Nov 2012 14:25:30 +1300 Subject: [PATCH] Bug 9165 - Prevent LDAP passwords being stored locally This adds a configuration option to LDAP that prevents it from storing user's passwords in the local database. This is useful when users of hosted Koha wish to prevent any form of offsite password storage for security reasons. Notes: * if the option is not included in the koha-conf.xml file, then the current default behaviour of saving the password locally is retained. * this has no impact on passwords that are already in the database. They will not be erased. To use: * edit the koha-conf.xml for a system that uses LDAP for authentication. * in the configuration, add: 0 * feel a greater sense of security. To test: 1) have a Koha system that authenticates using LDAP. 2) note that when a user logs in, their password is saved (hashed) in the database. 2.5) it is important to note that, for whatever reason, a user's password is not stored on a login where their account is created, only when they log in after being created. Thus perhaps log in and log out a couple of times to be sure. 3) add the 0 option to the section of koha-conf.xml. 4) login with a new user (or erase the password from the database for an existing user) and note that the password field is not populated. 5) log out and log back in just to be sure, check the password field again. --- C4/Auth_with_ldap.pm | 71 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/C4/Auth_with_ldap.pm b/C4/Auth_with_ldap.pm index f3c1f7f..6171ff7 100644 --- a/C4/Auth_with_ldap.pm +++ b/C4/Auth_with_ldap.pm @@ -261,21 +261,54 @@ sub exists_local { return 0; } +# This function performs a password update, given the userid, borrowerid, +# and digested password. It will verify that things are correct and return the +# borrowers cardnumber. The idea is that it is used to keep the local +# passwords in sync with the LDAP passwords. +# +# $cardnum = _do_changepassword($userid, $borrowerid, $digest) +# +# Note: if the LDAP config has the update_password tag set to a false value, +# then this will not update the password, it will simply return the cardnumber. sub _do_changepassword { - my ($userid, $borrowerid, $digest) = @_; - $debug and print STDERR "changing local password for borrowernumber=$borrowerid to '$digest'\n"; - changepassword($userid, $borrowerid, $digest); - - # Confirm changes - my $sth = C4::Context->dbh->prepare("SELECT password,cardnumber FROM borrowers WHERE borrowernumber=? "); - $sth->execute($borrowerid); - if ($sth->rows) { - my ($md5password, $cardnum) = $sth->fetchrow; - ($digest eq $md5password) and return $cardnum; - warn "Password mismatch after update to cardnumber=$cardnum (borrowernumber=$borrowerid)"; - return; - } - die "Unexpected error after password update to userid/borrowernumber: $userid / $borrowerid."; + my ( $userid, $borrowerid, $digest ) = @_; + + if ( exists( $ldap->{update_password} ) && !$ldap->{update_password} ) { + + # This path doesn't update the password, just returns the + # card number + my $sth = C4::Context->dbh->prepare( + 'SELECT cardnumber FROM borrowers WHERE borrowernumber=?' ); + $sth->execute($borrowerid); + die +"Unable to access borrowernumber with userid=$userid, borrowernumber=$borrowerid" + if !$sth->rows; + my ($cardnum) = $sth->fetchrow; + return $cardnum; + } + else { + + # This path updates the password in the database + print STDERR +"changing local password for borrowernumber=$borrowerid to '$digest'\n" + if $debug; + changepassword( $userid, $borrowerid, $digest ); + + # Confirm changes + my $sth = C4::Context->dbh->prepare( + "SELECT password,cardnumber FROM borrowers WHERE borrowernumber=? " + ); + $sth->execute($borrowerid); + if ( $sth->rows ) { + my ( $md5password, $cardnum ) = $sth->fetchrow; + ( $digest eq $md5password ) and return $cardnum; + warn +"Password mismatch after update to cardnumber=$cardnum (borrowernumber=$borrowerid)"; + return; + } + die +"Unexpected error after password update to userid/borrowernumber: $userid / $borrowerid."; + } } sub update_local { @@ -421,6 +454,8 @@ Example XML stanza for LDAP configuration in KOHA_CONF. password comparison, e.g., to use Active Directory --> %s@my_domain.com + 1 @@ -478,6 +513,14 @@ attribute that the server allows to be used for binding could be used. Currently, principal_name only operates when auth_by_bind is enabled. +=head2 update_password + +If this tag is left out or set to a true value, then the user's LDAP password +will be stored (hashed) in the local Koha database. If you don't want this +to happen, then set the value of this to '0'. Note that if passwords are not +stored locally, and the connection to the LDAP system fails, then the users +will not be able to log in at all. + =head2 Active Directory The auth_by_bind and principal_name settings are recommended for Active Directory. -- 1.7.9.5