(ops, resent from the right address)
On Fri, Jan 14, 2011 at 10:24:19PM +1300, Nicholas Lee wrote:
> >>> Is there a plugin that will check rcpt addresses against a back end smtp
> >>> server?
I have a plug-in, ripped ad modified from some other plugin.
(sorry, still no (c) info, please add some gpl header and credits[1] and
manual before add to public repo - it was for internal use only.. my
fault, i wanted to add headers/credits/manual and sumbit to public repo,
but .. you known ..).
Usage:
rcpt_smtp xx.xx.xx.xx yy @domain.ext [@domain.ext ..]
rcpt_deny
For sample
rcpt_smtp 127.0.0.1 26 @antani.it @pippotronic.com
rcpt_deny
You can have more than one rcpt_smtp entry, also should work for
multiple lines/ip with the same domain (HA, etc).
Remember to add rcpt_deny at the end (btw, there's a not so good
behaviour, it responds with a relay denied also for valid
domains/invalid users combinations).
works ok for me, i use it with qpsmtpd-forkserver on a not so heavily
loaded mailserver.
ciao,
Igor
[1] I don't remember exactly which plugin i used as template, but should
be easily identifiable;
use Qpsmtpd::Constants;
use Net::SMTP;
sub init {
my ($self, $qp, @args) = @_;
if (@args > 0) {
if ($args[0] =~ /^([\.\w_-]+)$/) {
$self->{_smtp_server} = $1
}
else {
die "Bad data in smtp server: $args[0]";
}
$self->{_smtp_port} = 25;
if (@args > 1 and $args[1] =~ /^(\d+)$/) {
$self->{_smtp_port} = $1;
}
if( @args > 2 ) {
shift(@args);
shift(@args);
$self->{_domains} = join( ",", @args );
}
} else {
die("No SMTP server specified in rcpt_smtp config");
}
}
sub hook_rcpt {
my ($self, $transaction, $recipient) = @_;
return (DECLINED) unless $recipient->host && $recipient->user;
my $rcpt = lc $recipient->user . '@' . $recipient->host;
my @domains;
if( defined( $self->{_domains} ) ) {
@domains = split( /,/, $self->{_domains} );
} else {
@domains = ( "ANY" );
}
foreach my $domain (@domains) {
if( $domain eq "ANY" || $rcpt =~ m/\Q$domain\E$/ ) {
$self->log(LOGDEBUG, "rcpt_smtp check $rcpt for domain:
$domain -> $self->{_smtp_server}:$self->{_smtp_port} " );
my $smtp = Net::SMTP->new(
$self->{_smtp_server},
Port => $self->{_smtp_port},
Timeout => 60,
Hello =>
$self->qp->config("me"),
);
# check if smtp connection was successful, or return
deny
if( !$smtp ) {
$self->log(LOGWARN, "WARNING: rcpt_smtp unable
to connect ($self->{_smtp_server}:$self->{_smtp_port}:$!)" );
return Qpsmtpd::DSN->sys_not_accepting_mail();
}
# check address from/to
$smtp->mail( $transaction->sender->address );
$smtp->recipient($rcpt);
# store return code (eg: 5 for "550 Relaying denied
(#5.7.1)"
my $smtp_code = substr( $smtp->code(), 0, 1 );
$self->log(LOGDEBUG, "rcpt_smtp check for $rcpt from
$self->{_smtp_server}:$self->{_smtp_port}: " . $smtp->code() . " / " .
$smtp->message() );
$smtp->quit();
if( $smtp_code eq "2" ) {
return Qpsmtpd::DSN->addr_rcpt_ok();
} elsif( $smtp_code eq "4" ) {
return Qpsmtpd::DSN->sys_not_accepting_mail(
"Temporary error" );
} elsif( $smtp_code eq "5" ) {
return Qpsmtpd::DSN->relaying_denied();
}
}
}
return (DECLINED);
}
# vim: ts=4 sw=4 expandtab syn=perl
use Qpsmtpd::Constants;
sub hook_rcpt {
my ($self, $transaction, $recipient) = @_;
return Qpsmtpd::DSN->relaying_denied();
}