From 295474503f4fde32012b43a00d6813088cd47747 Mon Sep 17 00:00:00 2001 From: jaredj Date: Thu, 5 Mar 2009 08:06:50 +0800 Subject: Add support for multiple postfix cleanup sockets The current postfix-queue plugin allows the administrator to set a single path to a local postfix cleanup socket file from the plugin 'command line'. This adds a 'cleanup_sockets' configuration directive that can contain a list of paths as well as host/port combinations pointing to postfix cleanup services, which will be tried in the order that they appear. Not yet tested. --- lib/Qpsmtpd/Postfix.pm | 29 ++++++++++++++++++++++------- plugins/queue/postfix-queue | 16 ++++++++++------ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/lib/Qpsmtpd/Postfix.pm b/lib/Qpsmtpd/Postfix.pm index f045f7f..519e5f6 100644 --- a/lib/Qpsmtpd/Postfix.pm +++ b/lib/Qpsmtpd/Postfix.pm @@ -14,6 +14,7 @@ details. use strict; use IO::Socket::UNIX; +use IO::Socket::INET; use vars qw(@ISA); @ISA = qw(IO::Socket::UNIX); @@ -92,12 +93,22 @@ sub print_rec_time { sub open_cleanup { my ($class, $socket) = @_; - $socket = "/var/spool/postfix/public/cleanup" - unless defined $socket; - - my $self = IO::Socket::UNIX->new(Type => SOCK_STREAM, - Peer => $socket); - die qq(Couldn't open unix socket "$socket": $!) unless ref $self; + my $self; + if ($socket =~ m#^(/.+)#) { + $socket = $1; # un-taint socket path + $self = IO::Socket::UNIX->new(Type => SOCK_STREAM, + Peer => $socket) if $socket; + + } elsif ($socket =~ /(.*):(\d+)/) { + my ($host,$port) = ($1,$2); # un-taint address and port + $self = IO::Socket::INET->new(Proto => 'tcp', + PeerAddr => $host,PeerPort => $port) + if $host and $port; + } + unless (ref $self) { + warn "Couldn't open \"$socket\": $!"; + return; + } # allow buffered writes $self->autoflush(0); bless ($self, $class); @@ -163,7 +174,11 @@ $transaction is supposed to be a Qpsmtpd::Transaction object. sub inject_mail { my ($class, $transaction) = @_; - my $strm = $class->open_cleanup($transaction->notes('postfix-queue-socket')); + my @sockets = @{$transaction->notes('postfix-queue-sockets') + // ['/var/spool/postfix/public/cleanup']}; + my $strm; + $strm = $class->open_cleanup($_) and last for @sockets; + die "Unable to open any cleanup sockets!" unless $strm; my %at = $strm->get_attr; my $qid = $at{queue_id}; diff --git a/plugins/queue/postfix-queue b/plugins/queue/postfix-queue index 8b3a3c0..28fa44f 100644 --- a/plugins/queue/postfix-queue +++ b/plugins/queue/postfix-queue @@ -11,7 +11,10 @@ This plugin passes mails on to the postfix cleanup daemon. 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. +The 'postfix_queue' plugin can also contain a list of cleanup socket paths +and/or remote postfix cleanup service hosts specified in the form of +'address:port'. If set, the environment variable POSTFIXQUEUE overrides both +of these settings. All other parameters are flags for cleanup, no flags are enabled by default. See below in ``POSTFIX COMPATIBILITY'' for flags understood by your postfix @@ -133,9 +136,6 @@ sub register { $self->{_queue_socket} = $1; shift @args; } - else { - $self->{_queue_socket} = "/var/spool/postfix/public/cleanup"; - } foreach (@args) { if ($self->can("CLEANUP_".$_) and /^(FLAG_[A-Z0-9_]+)$/) { @@ -152,14 +152,18 @@ sub register { $self->{_queue_socket} = "/var/spool/postfix/public/cleanup"; } - $self->{_queue_socket} = $ENV{POSTFIXQUEUE} if $ENV{POSTFIXQUEUE}; + $self->{_queue_socket_env} = $ENV{POSTFIXQUEUE} if $ENV{POSTFIXQUEUE}; } sub hook_queue { my ($self, $transaction) = @_; $transaction->notes('postfix-queue-flags', $self->{_queue_flags}); - $transaction->notes('postfix-queue-socket', $self->{_queue_socket}); + my @queue; + @queue = ($self->{_queue_socket_env}) if $self->{_queue_socket_env}; + @queue = $self->qp->config('cleanup_sockets') unless @queue; + @queue = ($self->{_queue_socket} // ()) unless @queue; + $transaction->notes('postfix-queue-sockets', \@queue) if @queue; # $self->log(LOGDEBUG, "queue-flags=".$transaction->notes('postfix-queue-flags')); my ($status, $qid, $reason) = Qpsmtpd::Postfix->inject_mail($transaction); -- 1.7.2.2