2006-01-11 17:48:08 +01:00
|
|
|
|
2004-02-19 11:55:36 +01:00
|
|
|
=head1 NAME
|
|
|
|
|
|
|
|
postfix-queue
|
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
|
|
|
|
This plugin passes mails on to the postfix cleanup daemon.
|
|
|
|
|
|
|
|
=head1 CONFIG
|
|
|
|
|
2006-01-11 17:48:08 +01:00
|
|
|
The first optional parameter is the location of the cleanup socket. If it does
|
|
|
|
not start with a ``/'', it is treated as a flag for cleanup (see below).
|
|
|
|
If set, the environment variable POSTFIXQUEUE overrides this setting.
|
|
|
|
|
|
|
|
All other parameters are flags for cleanup, no flags are enabled by default.
|
|
|
|
Known flags are:
|
|
|
|
|
|
|
|
=over 3
|
|
|
|
|
|
|
|
=item FLAG_FILTER
|
|
|
|
|
|
|
|
Set the CLEANUP_FLAG_FILTER for cleanup. This enables the use of
|
|
|
|
I<header_filter>, I<body_filter> or I<content_filter> in postfix' main.cf.
|
|
|
|
|
|
|
|
=item FLAG_BCC_OK
|
2004-02-19 11:55:36 +01:00
|
|
|
|
2006-01-11 17:48:08 +01:00
|
|
|
Setting this flag enables (for example) the I<recipient_bcc_maps> parameter
|
|
|
|
|
|
|
|
=item FLAG_MAP_OK
|
|
|
|
|
|
|
|
This flag enables the use of other recipient mappings (e.g.
|
|
|
|
I<virtual_alias_maps>) in postfix' cleanup.
|
|
|
|
|
|
|
|
=back
|
2004-02-19 11:55:36 +01:00
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
use Qpsmtpd::Postfix;
|
|
|
|
|
2006-01-11 17:48:08 +01:00
|
|
|
#
|
|
|
|
# postfix' cleanup flags:
|
|
|
|
use constant CLEANUP_FLAG_FILTER => (1 << 1); # /* Enable content filter */
|
|
|
|
use constant CLEANUP_FLAG_BCC_OK => (1 << 4); # /* Ok to add auto-BCC addresses */
|
|
|
|
use constant CLEANUP_FLAG_MAP_OK => (1 << 5); # /* Ok to map addresses */
|
2004-02-19 11:55:36 +01:00
|
|
|
|
2006-01-11 17:48:08 +01:00
|
|
|
sub register {
|
|
|
|
my ($self, $qp, @args) = @_;
|
|
|
|
|
|
|
|
$self->{_queue_flags} = 0;
|
|
|
|
if (@args > 0) {
|
|
|
|
if ($args[0] =~ m#^/#) {
|
|
|
|
$self->{_queue_socket} = shift @args;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$self->{_queue_socket} = "/var/spool/postfix/public/cleanup";
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach (@args) {
|
|
|
|
if ($_ eq 'FLAG_FILTER') {
|
|
|
|
$self->{_queue_flags} |= CLEANUP_FLAG_FILTER;
|
|
|
|
}
|
|
|
|
elsif ($_ eq 'FLAG_BCC_OK') {
|
|
|
|
$self->{_queue_flags} |= CLEANUP_FLAG_BCC_OK;
|
|
|
|
}
|
|
|
|
elsif ($_ eq 'FLAG_MAP_OK') {
|
|
|
|
$self->{_queue_flags} |= CLEANUP_FLAG_MAP_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
$self->log(LOGWARN, "Ignoring unkown cleanup flag $_");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$self->{_queue_socket} = "/var/spool/postfix/public/cleanup";
|
|
|
|
}
|
|
|
|
|
|
|
|
$self->{_queue_socket} = $ENV{POSTFIXQUEUE} if $ENV{POSTFIXQUEUE};
|
2004-02-19 11:55:36 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2005-07-07 06:17:39 +02:00
|
|
|
sub hook_queue {
|
2006-01-11 17:48:08 +01:00
|
|
|
my ($self, $transaction) = @_;
|
|
|
|
$transaction->notes('postfix-queue-flags', $self->{_queue_flags});
|
2004-02-19 11:55:36 +01:00
|
|
|
|
2006-01-11 17:48:08 +01:00
|
|
|
# $self->log(LOGDEBUG, "queue-flags=".$transaction->notes('postfix-queue-flags'));
|
|
|
|
my ($status, $qid, $reason) = Qpsmtpd::Postfix->inject_mail($transaction);
|
2006-10-26 17:50:02 +02:00
|
|
|
if ($status) {
|
|
|
|
# this section needs to be kept in sync with the cleanup_stat_map
|
|
|
|
# array found in Postfix source file src/global/cleanup_strerror.c
|
|
|
|
# which in turn uses constants defined in src/global/cleanup_user.h
|
|
|
|
if ($status & (1<<8)) {
|
|
|
|
# CLEANUP_STAT_DEFER
|
|
|
|
return(DENYSOFT, $reason || "service unavailable (#4.7.1)");
|
|
|
|
} elsif ($status & (1<<7)) {
|
|
|
|
# CLEANUP_STAT_PROXY
|
|
|
|
return(DENYSOFT, $reason || "proxy reject (#4.3.0)");
|
|
|
|
} elsif ($status & (1<<0)) {
|
|
|
|
# CLEANUP_STAT_BAD
|
|
|
|
return(DENYSOFT, $reason || "internal prototcal error (#4.3.0)");
|
|
|
|
} elsif ($status & (1<<6)) {
|
|
|
|
# CLEANUP_STAT_RCPT
|
|
|
|
return Qpsmtpd::DSN->addr_unspecified(DENY, $reason || "no recipients specified");
|
|
|
|
} elsif ($status & (1<<4)) {
|
|
|
|
# CLEANUP_STAT_HOPS
|
|
|
|
return Qpsmtpd::DSN->too_many_hops(DENY, $reason || "too many hops");
|
|
|
|
} elsif ($status & (1<<2)) {
|
|
|
|
# CLEANUP_STAT_SIZE
|
|
|
|
return Qpsmtpd::DSN->sys_msg_too_big(DENY, $reason || "message file too big");
|
|
|
|
} elsif ($status & (1<<3)) {
|
|
|
|
# CLEANUP_STAT_CONT
|
|
|
|
return Qpsmtpd::DSN->media_conv_prohibited(DENY, $reason || "message content rejected");
|
|
|
|
} elsif ($status & (1<<1)) {
|
|
|
|
# CLEANUP_STAT_WRITE
|
|
|
|
return (DECLINED, $reason || "queue file write error");
|
|
|
|
} else {
|
|
|
|
# we have no idea why we're here.
|
|
|
|
return (DECLINED, $reason || "unknown error from postfix/cleanup: $status");
|
|
|
|
}
|
|
|
|
}
|
2006-01-11 17:48:08 +01:00
|
|
|
$status and return (DECLINED, "Unable to queue message ($status, $reason)");
|
2004-02-19 11:55:36 +01:00
|
|
|
|
2006-01-11 17:48:08 +01:00
|
|
|
my $msg_id = $transaction->header->get('Message-Id') || '';
|
|
|
|
$msg_id =~ s/[\r\n].*//s; # don't allow newlines in the Message-Id here
|
|
|
|
return (OK, "Queued! $msg_id (Queue-Id: $qid)");
|
2004-02-19 11:55:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#vim: sw=2 ts=8
|