[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[EP-tech] Re: With LDAP user_login.pl script local users can’t login



This is my implementation using LDAP and Kerberos. As you can see I
validate Admin separately, but definitively it can be modify to suit Brian
workflow.
I hope this helps,

Denis

PS: do not hesitate in suggesting improvements! :D

$c->{check_user_password} = sub {
   my( $session, $username, $password ) = @_;

   # Kerberos authentication for "user", "editor" and "admin" types (roles)

   use Net::LDAP; # IO::Socket::SSL also required
   use Authen::Krb5::Simple;
   use Authen::SASL;

   # LDAP tunables
   my $ldap_host = ?ldap.xxx.xxx";
   my $base      = ?OU=xx,DC=xx,DC=xx,DC=xx,DC=xx";
   my $proxy_user ="ad_read";
   my $dn        = "CN=$proxy_user,$base";

   # Kerberos tunables
   my $krb_host = ?xxx.xxx.xxx";

   my $krb       = Authen::Krb5::Simple->new(realm => $krb_host);
   unless ( $krb )
   {
    print STDERR "Kerberos error: $@\n";
    return 0;
   }

   my $ldap      = Net::LDAP->new ( $ldap_host );
   unless( $ldap )
   {
       print STDERR "LDAP error: $@\n";
       return 0;
   }

   my $sasl = Authen::SASL->new(
          mechanism => 'GSSAPI',
          callback => { user => 'ad_read' }
        ) or die "$@";

   my $mesg = $ldap->bind(sasl => $sasl);# dn => $dn, password=>$ldappass );

   if( $mesg->code() )
   {
       print STDERR "LDAP Bind error: " . $mesg->error() . "\n";
       return 0;
   }

   # Distinguished name (and attribues needed later on) for this user
   my $result = $ldap->search (
       base    => "$base",
       filter  => "(&(sAMAccountName=$username))",
       attrs   =>  ['1.1', 'uid', 'sn', 'givenname', 'mail'],
       sizelimit=>1
   );

   my $entr = $result->pop_entry;
   unless( defined $entr )
   {
       # Allow local EPrints authentication for admins (accounts not found
in LDAP)
       my $user = EPrints::DataObj::User::user_with_username( $session,
$username );
       return 0 unless $user;

       my $user_type = $user->get_type;
       if( $user_type eq "admin" )
       {
           # internal authentication for "admin" type
           return $session->get_database->valid_login( $username, $password
);
       }
       return 0;
   }


   # Check password
   if( !$krb->authenticate( $username, $password ) )
   {
    print STDERR "$username authentication failed: ", $krb->errstr(), "\n";
       return 0;
   }

   # Does account already exist?
   my $user = EPrints::DataObj::User::user_with_username( $session,
$username );
   if( !defined $user )
   {
       # New account
       $user = EPrints::DataObj::User::create( $session, "user" );
       $user->set_value( "username", $username );
   }

   # Set metadata
   my $name = {};
   $name->{family} = $entr->get_value( "sn" );
   $name->{given} = $entr->get_value( "givenName" );
   $user->set_value( "name", $name );
   $user->set_value( "username", $username );
   $user->set_value( "email", $entr->get_value( "mail" ) );
   $user->commit();

   $ldap->unbind if $ldap;

   return 1;
}


On Thu, Dec 3, 2015 at 4:52 PM, Brian D. Gregg <bdgregg at pitt.edu> wrote:

> Our logic flow for LDAP and local logins is as follows and we had to
> pretty much write (re-write) our eprints_login.pl from scratch, but we
> had to do that for other reasons here as well due to the LDAP connection we
> needed to use to our central authentication system.  Our flow assumes that
> everyone logging in has a LDAP account first then tries the local DB if
> LDAP logon fails.
>
>
>
> Hope this helps.
>
> -Brian.
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.ecs.soton.ac.uk/pipermail/eprints-tech/attachments/20151203/5206befa/attachment-0001.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.png
Type: image/png
Size: 25180 bytes
Desc: not available
Url : http://mailman.ecs.soton.ac.uk/pipermail/eprints-tech/attachments/20151203/5206befa/attachment-0001.png