X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FAuth_with_ldap.pm;h=6143c9f4aa4e4b89432a9a2423073e0469b85112;hb=6fcb6712fe5411b182b6f0d23c40d3ce6d44f3eb;hp=3613acfe8c30f8d29d19c333baae9029354a6a5b;hpb=322a5ef4819960c5ba5b65ce07150ce873aa6a3d;p=koha.git diff --git a/C4/Auth_with_ldap.pm b/C4/Auth_with_ldap.pm index 3613acfe8c..6143c9f4aa 100644 --- a/C4/Auth_with_ldap.pm +++ b/C4/Auth_with_ldap.pm @@ -35,7 +35,7 @@ use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug); BEGIN { require Exporter; - $VERSION = 3.10; # set the version for version checking + $VERSION = 3.07.00.049; # set the version for version checking @ISA = qw(Exporter); @EXPORT = qw( checkpw_ldap ); } @@ -47,7 +47,7 @@ BEGIN { # ~ then gets the LDAP entry # ~ and calls the memberadd if necessary -sub ldapserver_error ($) { +sub ldapserver_error { return sprintf('No ldapserver "%s" defined in KOHA_CONF: ' . $ENV{KOHA_CONF}, shift); } @@ -70,8 +70,8 @@ my %config = ( update => defined($ldap->{update} ) ? $ldap->{update} : 1, # update from LDAP to Koha database for existing user ); -sub description ($) { - my $result = shift or return undef; +sub description { + my $result = shift or return; return "LDAP error #" . $result->code . ": " . $result->error_name . "\n" . "# " . $result->error_text . "\n"; @@ -103,26 +103,34 @@ sub checkpw_ldap { my ($dbh, $userid, $password) = @_; my @hosts = split(',', $prefhost); my $db = Net::LDAP->new(\@hosts); + unless ( $db ) { + warn "LDAP connexion failed"; + return 0; + } + #$debug and $db->debug(5); my $userldapentry; - if ( $ldap->{auth_by_bind} ) { - my $principal_name = $ldap->{principal_name}; - if ($principal_name and $principal_name =~ /\%/) { - $principal_name = sprintf($principal_name,$userid); - } else { - $principal_name = $userid; - } - my $res = $db->bind( $principal_name, password => $password ); - if ( $res->code ) { - $debug and warn "LDAP bind failed as kohauser $principal_name: ". description($res); - return 0; - } - # FIXME dpavlin -- we really need $userldapentry leater on even if using auth_by_bind! - my $search = search_method($db, $userid) or return 0; # warnings are in the sub - $userldapentry = $search->shift_entry; + if ( $ldap->{auth_by_bind} ) { + # Perform an anonymous bind + my $res = $db->bind; + if ( $res->code ) { + $debug and warn "Anonymous LDAP bind failed: ". description($res); + return 0; + } + + # Perform a LDAP search for the given username + my $search = search_method($db, $userid) or return 0; # warnings are in the sub + $userldapentry = $search->shift_entry; - } else { + # Perform a LDAP bind for the given username using the matched DN + $res = $db->bind( $userldapentry->dn, password => $password ); + if ( $res->code ) { + $debug and warn "LDAP bind failed as kohauser $userid: ". description($res); + return 0; + } + + } else { 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); @@ -155,7 +163,7 @@ sub checkpw_ldap { ($cardnumber eq $c2) or warn "update_local returned cardnumber '$c2' instead of '$cardnumber'"; } else { # C1, D1 # maybe update just the password? - return(1, $cardnumber); # FIXME dpavlin -- don't destroy ExtendedPatronAttributes + return(1, $cardnumber, $local_userid); } } elsif ($config{replicate}) { # A2, C2 $borrowernumber = AddMember(%borrower) or die "AddMember failed"; @@ -163,10 +171,13 @@ sub checkpw_ldap { return 0; # B2, D2 } if (C4::Context->preference('ExtendedPatronAttributes') && $borrowernumber && ($config{update} ||$config{replicate})) { - my @types = C4::Members::AttributeTypes::GetAttributeTypes(); - my @attributes = grep{my $key=$_; any{$_ eq $key}@types;} keys %borrower; - my $extended_patron_attributes = map{{code=>$_,value=>$borrower{$_}}}@attributes; - my $extended_patron_attributes = [] unless $extended_patron_attributes; + my $extended_patron_attributes; + foreach my $attribute_type ( C4::Members::AttributeTypes::GetAttributeTypes() ) { + my $code = $attribute_type->{code}; + if ( exists($borrower{$code}) && $borrower{$code} !~ m/^\s*$/ ) { # skip empty values + push @$extended_patron_attributes, { code => $code, value => $borrower{$code} }; + } + } my @errors; #Check before add for (my $i; $i< scalar(@$extended_patron_attributes)-1;$i++) { @@ -182,7 +193,7 @@ sub checkpw_ldap { } C4::Members::Attributes::SetBorrowerAttributes($borrowernumber, $extended_patron_attributes); } -return(1, $cardnumber); +return(1, $cardnumber, $userid); } # Pass LDAP entry object and local cardnumber (userid). @@ -190,7 +201,7 @@ return(1, $cardnumber); # Edit KOHA_CONF so $memberhash{'xxx'} fits your ldap structure. # Ensure that mandatory fields are correctly filled! # -sub ldap_entry_2_hash ($$) { +sub ldap_entry_2_hash { my $userldapentry = shift; my %borrower = ( cardnumber => shift ); my %memberhash; @@ -202,7 +213,7 @@ sub ldap_entry_2_hash ($$) { hashdump("LDAP key: ",$userldapentry->{$_}); } } - my $x = $userldapentry->{attrs} or return undef; + my $x = $userldapentry->{attrs} or return; foreach (keys %$x) { $memberhash{$_} = join ' ', @{$x->{$_}}; $debug and print STDERR sprintf("building \$memberhash{%s} = ", $_, join(' ', @{$x->{$_}})), "\n"; @@ -210,7 +221,7 @@ sub ldap_entry_2_hash ($$) { $debug and print STDERR "Finsihed \%memberhash has ", scalar(keys %memberhash), " keys\n", "Referencing \%mapping with ", scalar(keys %mapping), " keys\n"; foreach my $key (keys %mapping) { - my $data = $memberhash{$mapping{$key}->{is}}; + my $data = $memberhash{ lc($mapping{$key}->{is}) }; # Net::LDAP returns all names in lowercase $debug and printf STDERR "mapping %20s ==> %-20s (%s)\n", $key, $mapping{$key}->{is}, $data; unless (defined $data) { $data = $mapping{$key}->{content} || ''; # default or failsafe '' @@ -221,10 +232,21 @@ sub ldap_entry_2_hash ($$) { ( substr($borrower{'firstname'},0,1) . substr($borrower{ 'surname' },0,1) . " "); + + # check if categorycode exists, if not, fallback to default from koha-conf.xml + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("SELECT categorycode FROM categories WHERE categorycode = ?"); + $sth->execute( uc($borrower{'categorycode'}) ); + unless ( my $row = $sth->fetchrow_hashref ) { + my $default = $mapping{'categorycode'}->{content}; + $debug && warn "Can't find ", $borrower{'categorycode'}, " default to: $default for ", $borrower{userid}; + $borrower{'categorycode'} = $default + } + return %borrower; } -sub exists_local($) { +sub exists_local { my $arg = shift; my $dbh = C4::Context->dbh; my $select = "SELECT borrowernumber,cardnumber,userid,password FROM borrowers "; @@ -253,16 +275,16 @@ sub _do_changepassword { my ($md5password, $cardnum) = $sth->fetchrow; ($digest eq $md5password) and return $cardnum; warn "Password mismatch after update to cardnumber=$cardnum (borrowernumber=$borrowerid)"; - return undef; + return; } die "Unexpected error after password update to userid/borrowernumber: $userid / $borrowerid."; } -sub update_local($$$$) { - my $userid = shift or return undef; - my $digest = md5_base64(shift) or return undef; - my $borrowerid = shift or return undef; - my $borrower = shift or return undef; +sub update_local { + my $userid = shift or return; + my $digest = md5_base64(shift) or return; + my $borrowerid = shift or return; + my $borrower = shift or return; my @keys = keys %$borrower; my $dbh = C4::Context->dbh; my $query = "UPDATE borrowers\nSET " . @@ -349,7 +371,8 @@ C4::Auth - Authenticates Koha users | dateexpiry | date | YES | | NULL | | | gonenoaddress | tinyint(1) | YES | | NULL | | | lost | tinyint(1) | YES | | NULL | | - | debarred | tinyint(1) | YES | | NULL | | + | debarred | date | YES | | NULL | | + | debarredcomment | varchar(255) | YES | | NULL | | | contactname | mediumtext | YES | | NULL | | | contactfirstname | text | YES | | NULL | | | contacttitle | text | YES | | NULL | | @@ -398,8 +421,6 @@ Example XML stanza for LDAP configuration in KOHA_CONF. 1 0 - %s@my_domain.com -