]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy/LDAP_Auth.pm
Initial external authentication support via proxy
[working/Evergreen.git] / Open-ILS / src / perlmods / lib / OpenILS / Application / AuthProxy / LDAP_Auth.pm
1 package OpenILS::Application::AuthProxy::LDAP_Auth;
2 use strict;
3 use warnings;
4 use base 'OpenILS::Application::AuthProxy::AuthBase';
5 use OpenILS::Event;
6 use Net::LDAP;
7 use OpenSRF::Utils::SettingsClient;
8 use OpenSRF::Utils::Logger qw(:logger);
9
10 # default config var (override in configuration xml)
11 my $id_attr = 'uid';
12
13 sub authenticate {
14     my ( $self, $args ) = @_;
15     my $username = $args->{'username'};
16     my $password = $args->{'password'};
17
18     if (!$username) {
19         $logger->debug("User login failed: No username provided");
20         return OpenILS::Event->new( 'LOGIN_FAILED' );
21     }
22     if (!$password) {
23         $logger->debug("User login failed: No password provided");
24         return OpenILS::Event->new( 'LOGIN_FAILED' );
25     }
26
27     my $hostname_is_ldap = 0;
28     my $reached_ldap     = 0;
29     my $user_in_ldap     = 0;
30     my $login_succeeded  = 0;
31
32     my $hostname    = $self->{'hostname'};
33     my $basedn      = $self->{'basedn'};
34     my $authid      = $self->{'authid'};
35     my $authid_pass = $self->{'password'};
36     $id_attr        = $self->{'id_attr'} || $id_attr;
37
38     my $ldap;
39     if ( $ldap = Net::LDAP->new($hostname) ) {
40         $hostname_is_ldap = 1;
41         if ( $ldap->bind( $authid, password => $authid_pass )->code == 0 ) {
42             $reached_ldap = 1;
43             # verify username
44             if ( $ldap
45                 ->search( base => $basedn, filter => "($id_attr=$username)" )
46                 ->count != 0 ) {
47                 $user_in_ldap = 1;
48
49                 # verify password (bind check)
50                 my $binddn = "$id_attr=$username,$basedn";
51                 if ( $ldap->bind( $binddn, password => $password )
52                     ->code == 0 ) {
53                     $login_succeeded = 1;
54                 }
55             }
56         }
57     }
58
59     if ( $login_succeeded ) {
60         return OpenILS::Event->new('SUCCESS');
61     } elsif ( !$hostname_is_ldap ) {
62         # TODO: custom failure events?
63         $logger->debug("User login failed: Incorrect LDAP hostname");
64         return OpenILS::Event->new( 'LOGIN_FAILED' );
65     } elsif ( !$reached_ldap ) {
66         $logger->debug("User login failed: The LDAP server is misconfigured or unavailable");
67         return OpenILS::Event->new( 'LOGIN_FAILED' );
68     } elsif ( !$user_in_ldap ) {
69         $logger->debug("User login failed: Username $username not in LDAP");
70         return OpenILS::Event->new( 'LOGIN_FAILED' );
71     } else {
72         $logger->debug("User login failed: Incorrect LDAP password");
73         return OpenILS::Event->new( 'LOGIN_FAILED' );
74     }
75 }
76
77 1;