Apache-DBI
view release on metacpan or search on metacpan
lib/Apache/AuthDBI.pm view on Meta::CPAN
else {
# password not cached or changed
debug (2, "$prefix passwd not found in cache");
# connect to database, use all data_sources until the connect succeeds
for (my $j = 0; $j <= $#data_sources; $j++) {
last if (
$dbh = DBI->connect(
$data_sources[$j],
$usernames[$j],
$passwords[$j]
)
);
}
unless ($dbh) {
$r->log_reason(
"$prefix db connect error with data_source " .
">$Attr->{data_source}<: $DBI::errstr",
$r->uri
);
return MP2 ? Apache2::Const::SERVER_ERROR() :
Apache::Constants::SERVER_ERROR();
}
# generate statement
my $user_sent_quoted = $dbh->quote($user_sent);
my $select = "SELECT $Attr->{pwd_field}";
my $from = "FROM $Attr->{pwd_table}";
my $where = ($Attr->{uidcasesensitive} eq "off") ?
"WHERE lower($Attr->{uid_field}) =" :
"WHERE $Attr->{uid_field} =";
my $compare = ($Attr->{placeholder} eq "on") ?
"?" : "$user_sent_quoted";
my $statement = "$select $from $where $compare";
$statement .= " AND $Attr->{pwd_whereclause}"
if $Attr->{pwd_whereclause};
debug(2, "$prefix statement: $statement");
# prepare statement
my $sth;
unless ($sth = $dbh->prepare($statement)) {
$r->log_reason("$prefix can not prepare statement: $DBI::errstr", $r->uri);
$dbh->disconnect;
return MP2 ? Apache2::Const::SERVER_ERROR() :
Apache::Constants::SERVER_ERROR();
}
# execute statement
my $rv;
unless ($rv = ($Attr->{placeholder} eq "on") ?
$sth->execute($user_sent) : $sth->execute) {
$r->log_reason("$prefix can not execute statement: $DBI::errstr", $r->uri);
$dbh->disconnect;
return MP2 ? Apache2::Const::SERVER_ERROR() :
Apache::Constants::SERVER_ERROR();
}
my $password;
$sth->execute();
$sth->bind_columns(\$password);
my $cnt = 0;
while ($sth->fetch()) {
$password =~ s/ +$// if $password;
$passwd .= "$password$;";
$cnt++;
}
chop $passwd if $passwd;
# so we can distinguish later on between no password and empty password
undef $passwd if 0 == $cnt;
if ($sth->err) {
$dbh->disconnect;
return MP2 ? Apache2::Const::SERVER_ERROR() :
Apache::Constants::SERVER_ERROR();
}
$sth->finish;
# re-use dbh for logging option below
$dbh->disconnect unless $Attr->{log_field} && $Attr->{log_string};
}
$r->subprocess_env(REMOTE_PASSWORDS => $passwd);
debug(2, "$prefix passwd = >$passwd<");
# check if password is needed
unless ($passwd) { # not found in database
# if authoritative insist that user is in database
if ($Attr->{authoritative} eq 'on') {
$r->log_reason("$prefix password for user $user_sent not found", $r->uri);
$r->note_basic_auth_failure;
return MP2 ? Apache2::Const::AUTH_REQUIRED() :
Apache::Constants::AUTH_REQUIRED();
}
else {
# else pass control to the next authentication module
return MP2 ? Apache2::Const::DECLINED() :
Apache::Constants::DECLINED();
}
}
# allow any password if nopasswd = on and the retrieved password is empty
if ($Attr->{nopasswd} eq 'on' && !$passwd) {
return MP2 ? Apache2::Const::OK() : Apache::Constants::OK();
}
# if nopasswd is off, reject user
unless ($passwd_sent && $passwd) {
$r->log_reason("$prefix user $user_sent: empty password(s) rejected", $r->uri);
$r->note_basic_auth_failure;
return MP2 ? Apache2::Const::AUTH_REQUIRED() :
Apache::Constants::AUTH_REQUIRED();
}
# compare passwords
my $found = 0;
foreach my $password (split /$;/, $passwd) {
# compare all the passwords using as many encryption methods
# in fallback as needed
my @passwds_to_check =
( run in 0.686 second using v1.01-cache-2.11-cpan-2398b32b56e )