Apache-AuthenLDAP
view release on metacpan or search on metacpan
AuthenLDAP.pm view on Meta::CPAN
###############################################################################
# handler: hook into Apache/mod_perl API
###############################################################################
###############################################################################
sub handler {
my $r = shift;
return OK unless $r->is_initial_req; # only the first internal request
my ($res, $sent_pwd) = $r->get_basic_auth_pw;
return $res if $res;
my $name = $r->connection->user;
unless ($name) {
$r->note_basic_auth_failure;
$r->log_reason("no username supplied", $r->uri);
return AUTH_REQUIRED;
}
my $cache_result = $r->notes('AuthenCache');
if ($cache_result eq 'hit') {
$r->log->debug("handler: upstream cache hit for username=$name");
return OK;
}
my $basedn = $r->dir_config('AuthenBaseDN') || '';
my $ldapserver = $r->dir_config('AuthenLDAPServer') || "localhost";
my $ldapport = $r->dir_config('AuthenLDAPPort') || 389;
my $uidattrtype = $r->dir_config('AuthenUidAttrType') || "uid";
my $expire = lc($r->dir_config('AuthenExpire')) || 'false';
my $exp_attrtype = $r->dir_config('AuthenExpireAttrType') ||
'passwordIsExpired';
my $exp_lastmodattrtype =
$r->dir_config('AuthenExpireLastModAttrType') ||
'passwordModifyTimestamp';
my $exp_time = $r->dir_config('AuthenExpireTime') ||
186;
my $exp_redirect = $r->dir_config('AuthenExpireRedirect') || '';
$r->log->debug("handler: ",
"AuthenBaseDN - $basedn; LDAPServer - $ldapserver; ",
"LDAPPort - $ldapport; UiaDttrType - $uidattrtype; ",
"Expire - $expire; ExireAttrType - $exp_attrtype; ",
"ExpireLastModAttrType - $exp_lastmodattrtype; ",
"ExpireTime - $exp_time; ExpireRedirect - $exp_redirect");
if ($sent_pwd eq "") {
$r->note_basic_auth_failure;
$r->log_reason("user $name: no password supplied", $r->uri);
return AUTH_REQUIRED;
}
# Connect to the server
my $ld;
unless ($ld = new Net::LDAP($ldapserver, port => $ldapport)) {
$r->note_basic_auth_failure;
$r->log_reason("user $name: LDAP Connection Failed", $r->uri);
return SERVER_ERROR;
}
# Bind anonymously
my $msg = $ld->bind;
unless ($msg->code == LDAP_SUCCESS) {
$r->note_basic_auth_failure;
$r->log_reason("user $name: LDAP Initial Bind Failed: " . $msg->code .
" " . $msg->error, $r->uri);
return SERVER_ERROR;
}
# Create the filter and search
my $filter = "($uidattrtype=$name)";
$r->log->debug("handler: Using filter: $filter");
$msg = $ld->search(base => $basedn, filter => $filter);
unless ($msg->code == LDAP_SUCCESS) {
$r->note_basic_auth_failure;
$r->log_reason("user $name: ldap search operation failed: " .
$msg->code . " " . $msg->error, $r->uri);
return SERVER_ERROR;
}
# Did we receive any entries
unless ($msg->count) {
$r->note_basic_auth_failure;
$r->log_reason("user $name: username not found",$r->uri);
return AUTH_REQUIRED;
}
# Only want the first if we've received more than one
my $entry = $msg->first_entry;
my $dn = $entry->dn;
# Bind as the user we're authenticating
$msg = $ld->bind($dn, password => $sent_pwd);
unless ($msg->code == LDAP_SUCCESS) {
$r->note_basic_auth_failure;
$r->log_reason("user $name: password mismatch", $r->uri);
return AUTH_REQUIRED;
}
$ld->unbind;
if ($expire eq 'true') {
# Is the password set to expired in LDAP?
if (($entry->get($exp_attrtype))[0] eq 'true') {
$r->log->debug("handler: password flag expired");
$r->custom_response(FORBIDDEN, "$exp_redirect");
return FORBIDDEN;
}
# Has the password passed the age limit?
my ($modyear, $modmonth, $modday) =
(($entry->get($exp_lastmodattrtype))[0] =~ /(\d{4})(\d{2})(\d{2})/);
my ($year, $month, $day) = Today([time]);
if (Date_to_Days($year, $month, $day) -
Date_to_Days($modyear, $modmonth, $modday) > $exp_time) {
$r->log->debug("handler: password age expired");
$r->custom_response(FORBIDDEN, "$exp_redirect");
return FORBIDDEN;
}
}
# Everything's A-OK
return OK;
}
1;
__END__
# Documentation - try 'pod2text AuthenLDAP'
=head1 NAME
Apache::AuthenLDAP - mod_perl LDAP Authentication Module
=head1 SYNOPSIS
<Directory /foo/bar>
# Authentication Realm and Type (only Basic supported)
AuthName "Foo Bar Authentication"
AuthType Basic
# Any of the following variables can be set.
# Defaults are listed to the right.
PerlSetVar AuthenBaseDN o=Foo,c=Bar # Default: Empty String ("")
PerlSetVar AuthenLDAPServer ldap.foo.com # Default: localhost
PerlSetVar AuthenLDAPPort 389 # Default: 389 (standard LDAP port)
PerlSetVar AuthenUidattrType userid # Default: uid
PerlAuthenHandler Apache::AuthenLDAP
require valid-user # Any Valid LDAP User
# Matching Attribute and Value
</Directory>
=head1 DESCRIPTION
B<Apache::AuthenLDAP> is designed to work with mod_perl and
Net::LDAP. This module authenticates a user against an LDAP
backend. It can be combined with Apache::AuthzLDAP to provide
( run in 2.145 seconds using v1.01-cache-2.11-cpan-2398b32b56e )