Commit 360c5940 authored by Nigel Kukard's avatar Nigel Kukard
Browse files

* Backported database portability fixes from trunk

parent bf0e1c52
# Author: Nigel Kukard <nkukard@lbsd.net>
# Date: 2007-06-08
# Desc: DBI Lookup Database Type
package cbp::database::dbi;
use strict;
use warnings;
use cbp::logging;
use cbp::modules;
use DBI;
use Data::Dumper;
# User plugin info
our $pluginInfo = {
name => "DBI Lookup Database Type",
type => "dbi",
init => \&init,
new => sub { cbp::database::dbi->new(@_) },
};
# Our config
my %config;
# Initialize
sub init {
my $server = shift;
my $ini = $server->{'inifile'};
return 0;
}
# Constructor
sub new {
my ($class,$server,$name) = @_;
my $ini = $server->{'inifile'};
my $self = {
_dbh => undef,
_dsn => undef,
};
# Database connection info
$self->{'_dsn'} = $ini->val("database $name",'dsn');
my $username = $ini->val("database $name",'username');
my $password = $ini->val("database $name",'password');
# Connect to database
$self->{'_dbh'} = DBI->connect($self->{'_dsn'}, $username, $password, {
'AutoCommit' => 1,
'PrintError' => 0
});
# Check for error
if (!$self->{'_dbh'}) {
logger(LOG_ERR,"[DATABASE/DBI] Failed to connect to '".$self->{'_dsn'}."': $DBI::errstr");
}
bless $self, $class;
return $self;
}
# Close down
sub close {
my $self = shift;
$self->{'_dbh'}->disconnect();
logger(LOG_ERR,"[DATABASE/DBI] Closing '".$self->{'_dsn'}."'");
}
# Function to see if we ok
sub getStatus {
my $self = shift;
return $self->{'_dbh'} ? 0 : -1;
}
# Do a lookup
sub lookup {
my ($self,$query) = @_;
# Prepare statement
my $sth = $self->{'_dbh'}->prepare($query);
if (!$sth) {
logger(LOG_ERR,"[DATABASE/DBI] Failed to prepare statement '$query': ".$self->{'_dbh'}->errstr);
return -1;
}
# Execute
my $res = $sth->execute();
if (!$res) {
logger(LOG_ERR,"[DATABASE/DBI] Failed to execute statement: '$query': ".$self->{'_dbh'}->errstr);
return -1;
}
# Setup results
my @results;
while (my $item = $sth->fetchrow_hashref()) {
push(@results,$item);
}
# Finish off
$sth->finish();
logger(LOG_DEBUG,"[DATABASE/DBI] LOOKUP Results: ".Dumper(\@results));
return \@results;
}
# Store something
sub store {
my ($self,$query) = @_;
# Prepare statement
my $sth = $self->{'_dbh'}->prepare($query);
if (!$sth) {
logger(LOG_ERR,"[DATABASE/DBI] Failed to prepare statement '$query': ".$self->{'_dbh'}->errstr);
return -1;
}
# Execute
my $res = $sth->execute();
if (!$res) {
logger(LOG_ERR,"[DATABASE/DBI] Failed to execute statement: '$query': ".$self->{'_dbh'}->errstr);
return -1;
}
# Finish off
$sth->finish();
logger(LOG_DEBUG,"[DATABASE/DBI] STORE Results: $res");
return $res;
}
# Update something
sub update {
my ($self,$query) = @_;
# Prepare statement
my $sth = $self->{'_dbh'}->prepare($query);
if (!$sth) {
logger(LOG_ERR,"[DATABASE/DBI] Failed to prepare statement '$query': ".$self->{'_dbh'}->errstr);
return -1;
}
# Execute
my $res = $sth->execute();
if (!$res) {
logger(LOG_ERR,"[DATABASE/DBI] Failed to execute statement: '$query': ".$self->{'_dbh'}->errstr);
return -1;
}
# Finish off
$sth->finish();
logger(LOG_DEBUG,"[DATABASE/DBI] UPDATE Results: $res");
return $res;
}
# Remove something
sub remove {
my ($self,$query) = @_;
# Prepare statement
my $sth = $self->{'_dbh'}->prepare($query);
if (!$sth) {
logger(LOG_ERR,"[DATABASE/DBI] Failed to prepare statement '$query': ".$self->{'_dbh'}->errstr);
return -1;
}
# Execute
my $res = $sth->execute();
if (!$res) {
logger(LOG_ERR,"[DATABASE/DBI] Failed to execute statement: '$query': ".$self->{'_dbh'}->errstr);
return -1;
}
# Finish off
$sth->finish();
logger(LOG_DEBUG,"[DATABASE/DBI] REMOVE Results: $res");
return $res;
}
# Quote something
sub quote {
my ($self,$string) = @_;
return $self->{'_dbh'}->quote($string);
}
1;
# vim: ts=4
......@@ -117,7 +117,8 @@ sub connect
$self->{_dbh} = DBI->connect($self->{_dsn}, $self->{_username}, $self->{_password}, {
'AutoCommit' => 1,
'PrintError' => 0
'PrintError' => 0,
'FetchHashKeyName' => 'NAME_lc'
});
# Connect to database if we have to, check if we ok
......
......@@ -39,6 +39,8 @@ our (@ISA,@EXPORT);
DBFreeRes
DBSelectNumResults
hashifyLCtoMC
);
......@@ -245,6 +247,27 @@ sub DBSelectNumResults
}
# Convert a lower case array to mixed case
sub hashifyLCtoMC
{
my ($record,@entries) = @_;
# If we undefined, return
return undef if (!defined($record));
my $res;
# Loop with each item, assign from lowecase database record to our result
foreach my $entry (@entries) {
$res->{$entry} = $record->{lc($entry)};
}
return $res;
}
1;
......
......@@ -106,7 +106,7 @@ sub check {
next if (!$row);
# Setup result
if (!defined($row->{'Verdict'})) {
if (!defined($row->{'verdict'})) {
$server->maillog("module=AccessControl, action=none, host=%s, helo=%s, from=%s, to=%s, reason=no_verdict",
$sessionData->{'ClientAddress'},
$sessionData->{'Helo'},
......@@ -114,48 +114,48 @@ sub check {
$sessionData->{'Recipient'});
next; # No verdict
} elsif ($row->{'Verdict'} =~ /^hold$/i) {
} elsif ($row->{'verdict'} =~ /^hold$/i) {
$server->maillog("module=AccessControl, action=hold, host=%s, helo=%s, from=%s, to=%s, reason=verdict",
$sessionData->{'ClientAddress'},
$sessionData->{'Helo'},
$sessionData->{'Sender'},
$sessionData->{'Recipient'});
return $server->protocol_response(PROTO_HOLD,$row->{'Data'});
return $server->protocol_response(PROTO_HOLD,$row->{'data'});
} elsif ($row->{'Verdict'} =~ /^reject$/i) {
} elsif ($row->{'verdict'} =~ /^reject$/i) {
$server->maillog("module=AccessControl, action=reject, host=%s, helo=%s, from=%s, to=%s, reason=verdict",
$sessionData->{'ClientAddress'},
$sessionData->{'Helo'},
$sessionData->{'Sender'},
$sessionData->{'Recipient'});
return $server->protocol_response(PROTO_REJECT,$row->{'Data'});
return $server->protocol_response(PROTO_REJECT,$row->{'data'});
} elsif ($row->{'Verdict'} =~ /^discard$/i) {
} elsif ($row->{'verdict'} =~ /^discard$/i) {
$server->maillog("module=AccessControl, action=discard, host=%s, helo=%s, from=%s, to=%s, reason=verdict",
$sessionData->{'ClientAddress'},
$sessionData->{'Helo'},
$sessionData->{'Sender'},
$sessionData->{'Recipient'});
return $server->protocol_response(PROTO_DISCARD,$row->{'Data'});
return $server->protocol_response(PROTO_DISCARD,$row->{'data'});
} elsif ($row->{'Verdict'} =~ /^filter$/i) {
} elsif ($row->{'verdict'} =~ /^filter$/i) {
$server->maillog("module=AccessControl, action=filter, host=%s, helo=%s, from=%s, to=%s, reason=verdict",
$sessionData->{'ClientAddress'},
$sessionData->{'Helo'},
$sessionData->{'Sender'},
$sessionData->{'Recipient'});
return $server->protocol_response(PROTO_FILTER,$row->{'Data'});
return $server->protocol_response(PROTO_FILTER,$row->{'data'});
} elsif ($row->{'Verdict'} =~ /^redirect$/i) {
} elsif ($row->{'verdict'} =~ /^redirect$/i) {
$server->maillog("module=AccessControl, action=redirect, host=%s, helo=%s, from=%s, to=%s, reason=verdict",
$sessionData->{'ClientAddress'},
$sessionData->{'Helo'},
$sessionData->{'Sender'},
$sessionData->{'Recipient'});
return $server->protocol_response(PROTO_REDIRECT,$row->{'Data'});
return $server->protocol_response(PROTO_REDIRECT,$row->{'data'});
} else {
$server->log(LOG_ERR,"[ACCESSCONTROL] Unknown Verdict specification in access control '".$row->{'Verdict'}."'");
$server->log(LOG_ERR,"[ACCESSCONTROL] Unknown Verdict specification in access control '".$row->{'verdict'}."'");
$server->maillog("module=AccessControl, action=none, host=%s, helo=%s, from=%s, to=%s, reason=invalid_verdict",
$sessionData->{'ClientAddress'},
$sessionData->{'Helo'},
......
......@@ -113,31 +113,31 @@ sub check {
}
while (my $row = $sth->fetchrow_hashref()) {
# If defined, its to override
if (defined($row->{'UseBlacklist'})) {
$policy{'UseBlacklist'} = $row->{'UseBlacklist'};
if (defined($row->{'useblacklist'})) {
$policy{'UseBlacklist'} = $row->{'useblacklist'};
}
if (defined($row->{'BlacklistPeriod'})) {
$policy{'BlacklistPeriod'} = $row->{'BlacklistPeriod'};
if (defined($row->{'blacklistperiod'})) {
$policy{'BlacklistPeriod'} = $row->{'blacklistperiod'};
}
if (defined($row->{'UseHRP'})) {
$policy{'UseHRP'} = $row->{'UseHRP'};
if (defined($row->{'usehrp'})) {
$policy{'UseHRP'} = $row->{'usehrp'};
}
if (defined($row->{'HRPPeriod'})) {
$policy{'HRPPeriod'} = $row->{'HRPPeriod'};
if (defined($row->{'hrpperiod'})) {
$policy{'HRPPeriod'} = $row->{'hrpperiod'};
}
if (defined($row->{'HRPLimit'})) {
$policy{'HRPLimit'} = $row->{'HRPLimit'};
if (defined($row->{'hrplimit'})) {
$policy{'HRPLimit'} = $row->{'hrplimit'};
}
if (defined($row->{'RejectInvalid'})) {
$policy{'RejectInvalid'} = $row->{'RejectInvalid'};
if (defined($row->{'rejectinvalid'})) {
$policy{'RejectInvalid'} = $row->{'rejectinvalid'};
}
if (defined($row->{'RejectIP'})) {
$policy{'RejectIP'} = $row->{'RejectIP'};
if (defined($row->{'rejectip'})) {
$policy{'RejectIP'} = $row->{'rejectip'};
}
if (defined($row->{'RejectUnresolvable'})) {
$policy{'RejectUnresolvable'} = $row->{'RejectUnresolvable'};
if (defined($row->{'rejectunresolvable'})) {
$policy{'RejectUnresolvable'} = $row->{'rejectunresolvable'};
}
} # while (my $row = $sth->fetchrow_hashref())
} # foreach my $policyID (@{$sessionData->{'Policy'}->{$priority}})
......@@ -204,7 +204,7 @@ sub check {
# Loop with whitelist and calculate
while (my $row = $sth->fetchrow_hashref()) {
# Check format is SenderIP
if ((my $address = $row->{'Source'}) =~ s/^SenderIP://i) {
if ((my $address = $row->{'source'}) =~ s/^SenderIP://i) {
# Parse CIDR into its various peices
my $parsedIP = parseCIDR($address);
......@@ -228,7 +228,7 @@ sub check {
}
} else {
$server->log(LOG_ERR,"[CHECKHELO] Whitelist entry '".$row->{'Source'}."' is invalid.");
$server->log(LOG_ERR,"[CHECKHELO] Whitelist entry '".$row->{'source'}."' is invalid.");
DBFreeRes($sth);
return $server->protocol_response(PROTO_DATA_ERROR);
}
......@@ -368,7 +368,7 @@ sub check {
my $row = $sth->fetchrow_hashref();
# If count > 0 , then its blacklisted
if ($row->{'Count'} > 0) {
if ($row->{'count'} > 0) {
$server->maillog("module=CheckHelo, action=reject, host=%s, helo=%s, from=%s, to=%s, reason=blacklisted",
$sessionData->{'ClientAddress'},
$sessionData->{'Helo'},
......@@ -421,7 +421,7 @@ sub check {
# If count > $limit , reject
if ($row->{'Count'} > $policy{'HRPLimit'}) {
if ($row->{'count'} > $policy{'HRPLimit'}) {
$server->maillog("module=CheckHelo, action=reject, host=%s, helo=%s, from=%s, to=%s, reason=hrp_blacklisted",
$sessionData->{'ClientAddress'},
$sessionData->{'Helo'},
......@@ -486,10 +486,10 @@ sub cleanup
my $row = $sth->fetchrow_hashref();
# Check we have results
return if (!defined($row->{'BlacklistPeriod'}) || !defined($row->{'HRPPeriod'}));
return if (!defined($row->{'blacklistperiod'}) || !defined($row->{'hrpperiod'}));
# Work out which one is largest
my $period = $row->{'BlacklistPeriod'} > $row->{'HRPPeriod'} ? $row->{'BlacklistPeriod'} : $row->{'HRPPeriod'};
my $period = $row->{'blacklistperiod'} > $row->{'hrpperiod'} ? $row->{'blacklistperiod'} : $row->{'hrpperiod'};
# Bork if we didn't find anything of interest
return if (!($period > 0));
......
......@@ -111,16 +111,16 @@ sub check {
}
while (my $row = $sth->fetchrow_hashref()) {
# If defined, its to override
if (defined($row->{'UseSPF'})) {
$policy{'UseSPF'} = $row->{'UseSPF'};
if (defined($row->{'usespf'})) {
$policy{'UseSPF'} = $row->{'usespf'};
}
# If defined, its to override
if (defined($row->{'RejectFailedSPF'})) {
$policy{'RejectFailedSPF'} = $row->{'RejectFailedSPF'};
if (defined($row->{'rejectfailedspf'})) {
$policy{'RejectFailedSPF'} = $row->{'rejectfailedspf'};
}
# If defined, its to override
if (defined($row->{'AddSPFHeader'})) {
$policy{'AddSPFHeader'} = $row->{'AddSPFHeader'};
if (defined($row->{'addspfheader'})) {
$policy{'AddSPFHeader'} = $row->{'addspfheader'};
}
} # while (my $row = $sth->fetchrow_hashref())
} # foreach my $policyID (@{$sessionData->{'Policy'}->{$priority}})
......
......@@ -112,46 +112,46 @@ sub check {
# Loop with rows and build end policy
while (my $row = $sth->fetchrow_hashref()) {
# If defined, its to override
if (defined($row->{'UseGreylisting'})) {
$policy{'UseGreylisting'} = $row->{'UseGreylisting'};
if (defined($row->{'usegreylisting'})) {
$policy{'UseGreylisting'} = $row->{'usegreylisting'};
}
if (defined($row->{'GreylistPeriod'})) {
$policy{'GreylistPeriod'} = $row->{'GreylistPeriod'};
if (defined($row->{'greylistperiod'})) {
$policy{'GreylistPeriod'} = $row->{'greylistperiod'};
}
if (defined($row->{'Track'})) {
$policy{'Track'} = $row->{'Track'};
if (defined($row->{'track'})) {
$policy{'Track'} = $row->{'track'};
}
if (defined($row->{'GreylistAuthValidity'})) {
$policy{'GreylistAuthValidity'} = $row->{'GreylistAuthValidity'};
if (defined($row->{'greylistauthvalidity'})) {
$policy{'GreylistAuthValidity'} = $row->{'greylistauthvalidity'};
}
if (defined($row->{'GreylistUnAuthValidity'})) {
$policy{'GreylistUnAuthValidity'} = $row->{'GreylistUnAuthValidity'};
if (defined($row->{'greylistunauthvalidity'})) {
$policy{'GreylistUnAuthValidity'} = $row->{'greylistunauthvalidity'};
}
if (defined($row->{'UseAutoWhitelist'})) {
$policy{'UseAutoWhitelist'} = $row->{'UseAutoWhitelist'};
if (defined($row->{'useautowhitelist'})) {
$policy{'UseAutoWhitelist'} = $row->{'useautowhitelist'};
}
if (defined($row->{'AutoWhitelistPeriod'})) {
$policy{'AutoWhitelistPeriod'} = $row->{'AutoWhitelistPeriod'};
if (defined($row->{'autowhitelistperiod'})) {
$policy{'AutoWhitelistPeriod'} = $row->{'autowhitelistperiod'};
}
if (defined($row->{'AutoWhitelistCount'})) {
$policy{'AutoWhitelistCount'} = $row->{'AutoWhitelistCount'};
if (defined($row->{'autowhitelistcount'})) {
$policy{'AutoWhitelistCount'} = $row->{'autowhitelistcount'};
}
if (defined($row->{'AutoWhitelistPercentage'})) {
$policy{'AutoWhitelistPercentage'} = $row->{'AutoWhitelistPercentage'};
if (defined($row->{'autowhitelistpercentage'})) {
$policy{'AutoWhitelistPercentage'} = $row->{'autowhitelistpercentage'};
}
if (defined($row->{'UseAutoBlacklist'})) {
$policy{'UseAutoBlacklist'} = $row->{'UseAutoBlacklist'};
if (defined($row->{'useautoblacklist'})) {
$policy{'UseAutoBlacklist'} = $row->{'useautoblacklist'};
}
if (defined($row->{'AutoBlacklistPeriod'})) {
$policy{'AutoBlacklistPeriod'} = $row->{'AutoBlacklistPeriod'};
if (defined($row->{'autoblacklistperiod'})) {
$policy{'AutoBlacklistPeriod'} = $row->{'autoblacklistperiod'};
}
if (defined($row->{'AutoBlacklistCount'})) {
$policy{'AutoBlacklistCount'} = $row->{'AutoBlacklistCount'};
if (defined($row->{'autoblacklistcount'})) {
$policy{'AutoBlacklistCount'} = $row->{'autoblacklistcount'};
}
if (defined($row->{'AutoBlacklistPercentage'})) {
$policy{'AutoBlacklistPercentage'} = $row->{'AutoBlacklistPercentage'};
if (defined($row->{'autoblacklistpercentage'})) {
$policy{'AutoBlacklistPercentage'} = $row->{'autoblacklistpercentage'};
}
} # while (my $row = $sth->fetchrow_hashref())
......@@ -189,7 +189,7 @@ sub check {
while (my $row = $sth->fetchrow_hashref()) {
# Check format is SenderIP
if ((my $address = $row->{'Source'}) =~ s/^SenderIP://i) {
if ((my $address = $row->{'source'}) =~ s/^SenderIP://i) {
# Parse CIDR into its various peices
my $parsedIP = parseCIDR($address);
......@@ -214,7 +214,7 @@ sub check {
}
} else {
$server->log(LOG_ERR,"[GREYLISTING] Whitelist entry '".$row->{'Source'}."' is invalid.");
$server->log(LOG_ERR,"[GREYLISTING] Whitelist entry '".$row->{'source'}."' is invalid.");
DBFreeRes($sth);
return $server->protocol_response(PROTO_DATA_ERROR);
}
......@@ -256,7 +256,7 @@ sub check {
if ($row) {
# Check if we're within the auto-whitelisting period
if ($sessionData->{'Timestamp'} - $row->{'LastSeen'} <= $policy{'AutoWhitelistPeriod'}) {
if ($sessionData->{'Timestamp'} - $row->{'lastseen'} <= $policy{'AutoWhitelistPeriod'}) {
my $sth = DBDo("
UPDATE
......@@ -311,7 +311,7 @@ sub check {
if ((my $row = $sth->fetchrow_hashref())) {
# Check if we're within the auto-blacklisting period
if ($sessionData->{'Timestamp'} - $row->{'Added'} <= $policy{'AutoBlacklistPeriod'}) {
if ($sessionData->{'Timestamp'} - $row->{'added'} <= $policy{'AutoBlacklistPeriod'}) {
$server->maillog("module=Greylisting, action=reject, host=%s, helo=%s, from=%s, to=%s, reason=auto-blacklisted",
$sessionData->{'ClientAddress'},
......@@ -379,7 +379,7 @@ sub check {
return $server->protocol_response(PROTO_DB_ERROR);
}
my $row = $sth->fetchrow_hashref();
my $totalCount = defined($row->{'TotalCount'}) ? $row->{'TotalCount'} : 0;
my $totalCount = defined($row->{'totalcount'}) ? $row->{'totalcount'} : 0;
# If count exceeds or equals blacklist count, nail the server
......@@ -402,7 +402,7 @@ sub check {
return $server->protocol_response(PROTO_DB_ERROR);
}
$row = $sth->fetchrow_hashref();
my $failCount = defined($row->{'FailCount'}) ? $row->{'FailCount'} : 0;
my $failCount = defined($row->{'failcount'}) ? $row->{'failcount'} : 0;
# Check if we should blacklist this host
if (defined($policy{'AutoBlacklistPercentage'}) && $policy{'AutoBlacklistPercentage'} > 0) {
......@@ -525,7 +525,7 @@ sub check {
}
# Check if we should greylist, or not
my $timeElapsed = $row->{'LastUpdate'} - $row->{'FirstSeen'};
my $timeElapsed = $row->{'lastupdate'} - $row->{'firstseen'};
if ($timeElapsed < $policy{'GreylistPeriod'}) {
# Get time left, debug and return
my $timeLeft = $policy{'GreylistPeriod'} - $timeElapsed;
......@@ -534,7 +534,7 @@ sub check {
$sessionData->{'Helo'},
$sessionData->{'Sender'},
$sessionData->{'Recipient'},
$row->{'Tries'} + 1);
$row->{'tries'} + 1);
# Update stats
my $sth = DBDo("
......@@ -597,7 +597,7 @@ sub check {
return $server->protocol_response(PROTO_DB_ERROR);
}
my $row = $sth->fetchrow_hashref();
my $totalCount = defined($row->{'TotalCount'}) ? $row->{'TotalCount'} : 0;
my $totalCount = defined($row->{'totalcount'}) ? $row->{'totalcount'} : 0;
# If count exceeds or equals whitelist count, nail the server
if ($totalCount >= $policy{'AutoWhitelistCount'}) {
......@@ -618,7 +618,7 @@ sub check {
return $server->protocol_response(PROTO_DB_ERROR);
}
$row = $sth->fetchrow_hashref();