Apache-AuthLDAPBind

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

Apache-AuthLDAPBind

This is an authentication module for Apache 1.3 (and mod_perl) that
authenticates a user to an LDAP server by binding as that user (with
his supplied password).  If the bind succeeds, the user is
authenticated.  If not, authentication fails.

This is much more secure than the usual method of checking the
password against a hash, since there's no possibility that the hash
will be viewed while in transit (or worse, simply pulled out of the
LDAP database by an attacker), or that the client somehow miscomputes
the hash (since there are a variety of algorithms for password
hashes).  

Since passwords are being sent to the LDAP server over the network,
the server is required to support SSL.  Authentications will fail if
the server doesn't support StartTLS.  Cutting corners is not an option
when dealing with passwords!

INSTALLATION

To install this module, run the following commands:

    perl Makefile.PL
    make
    make test
    make install

lib/Apache/AuthLDAPBind.pm  view on Meta::CPAN

Version 0.02

=cut

our $VERSION = '0.02';

=head1 SYNOPSIS

This is an authentication module for Apache 1.3 (and mod_perl) that
authenticates a user to an LDAP server by binding as that user (with
his supplied password).  If the bind succeeds, the user is
authenticated.  If not, authentication fails.

This is much more secure than the usual method of checking the
password against a hash, since there's no possibility that the hash
will be viewed while in transit (or worse, simply pulled out of the
LDAP database by an attacker), or that the client somehow miscomputes
the hash (since there are a variety of algorithms for password
hashes).  

Since passwords are being sent to the LDAP server over the network,
the server is required to support SSL.  Authentications will fail if
the server doesn't support StartTLS.  Cutting corners is not an option
when dealing with passwords!

Example Apache 1.3 configuration:

    <Directory /foo/bar>
        # Authentication Realm and Type (only Basic supported)
        AuthName "Foo Bar Authentication"
        AuthType Basic  # use SSL, or your passwords will be sent cleartext!!

        # Any of the following variables can be set.  Defaults are listed
        # to the right.
        PerlSetVar ldap_base_dn o=Foo,c=Bar    # Default: Empty String ("")
        PerlSetVar ldap_server ldap.foo.com    # Default: localhost
        PerlSetVar ldap_server_port 389        # Default: (standard port)
        PerlSetVar ldap_uid_attr uid           # Default: uid

        PerlAuthenHandler Apache::AuthLDAPBind

lib/Apache/AuthLDAPBind.pm  view on Meta::CPAN

=head1 FUNCTIONS

All of these functions are standard for Apache mod_perl auth modules.

=head2 handler

=cut

sub handler {
    my $r = shift;
    my ($res, $sent_password) = $r->get_basic_auth_pw;
    return $res if $res;
    
    my $username = $r->connection->user;

    my ($ldap_server, $ldap_port, $base_dn, $uid_attr) = _get_ldap_vars($r);

    if (!$sent_password && $sent_password != 0) { # no need to lock out users
	                                          # whose password is 000000
                                                  # or 0e0, or something.
	$r->note_basic_auth_failure;
	$r->log_reason("user $username: no password supplied",$r->uri);
	return AUTH_REQUIRED;
    }

    my $ok;
    eval {
	$ok = _bind_ldap($ldap_server, $ldap_port, $base_dn, $uid_attr,
			 $username, $sent_password);
    };
    $ok = 0 if $@;
    
    if(!$ok){
	$r->note_basic_auth_failure;
	if (!$@) {
	    $r->log_reason("user $username: ".
			   "password incorrect or user not in LDAP",
			   $r->uri);
	}
	  else {
	      r->log_reason("user $username: LDAP error: $@", $r->uri);
	}
	return AUTH_REQUIRED;
    }
    
    # password was acceptable
    $r->push_handlers(PerlAuthzHandler => \&_authz);
    return OK;

}

sub _authz {
   my $r = shift;
   my $requires = $r->requires;
   return OK unless $requires;
   

lib/Apache/AuthLDAPBind.pm  view on Meta::CPAN

    return ($ldap_server, $ldap_port, $base_dn, $uid_attr);
}

# returns false if login fails, true if login succeeds.  dies on errors.
sub _bind_ldap {
    my $ldap_server = shift;
    my $ldap_port   = shift;
    my $base_dn     = shift;
    my $uid_attr    = shift;
    my $username    = shift;
    my $password    = shift;

    # prevent anonymous binds!
    if(!defined $username || !defined $password){
	die "null username/password passed to _bind_ldap!";
    }
    
    my $ldap = Net::LDAP->new("$ldap_server". 
			      ((defined $ldap_port) ? ":$ldap_port" : ""));
    
    my $mesg = $ldap->start_tls();
    
    $mesg = $ldap->bind("$uid_attr=$username,$base_dn",
                        password=>$password);
    $ldap->unbind;   # take down session
    
    $mesg->code && return 0; # failed
    return 1; # passed
}

=head1 AUTHOR

Jonathan T. Rockway, C<< <jon-cpan@jrock.us> >>



( run in 1.106 second using v1.01-cache-2.11-cpan-49f99fa48dc )