Eu tenho um problema parecido com o seu. Requisito pré-fila nos deixou com três opções
Como só estamos verificando o destinatário, a delegação de política de acesso SMTP seria suficiente. O Milter e o Proxy SMTPD foram usados se precisarmos de acesso ao cabeçalho e ao corpo também.
Meu script verificador foi fornecido pelo desenvolvedor. O uso do programa só estava chamando ./myscript recipient_address
qual recipient_address pelo postfix. Para fazer isso, eu uso uma versão modificada do script perl . Esse script perl me permite ler stdin, dividir a string por linha e dividir a linha com o mesmo sinal =
.
Em seguida, declaro o daemon do spawn em master.cf
policy unix - n n - - spawn user=mydedicateduser argv=/path/to/perl/script.pl
Em seguida, defina-o em main.cf
smtpd_recipient_restrictions =
...
reject_unauth_destination
check_policy_service unix:private/policy
...
Este script abaixo pode ser substituído por outra linguagem de programação. Aqui o pseudo-código para explicar como funciona.
while True:
get the stdin
if stdin = '' # ---> the end of parameter
call the external script with recipient parameter
get the return code
if recipient valid
print "dunno"
else if recipient not valid
print "reject"
else # ---> command error
print "defer if permit"
break
else
validate the stdin, the proper format is 'parameter=value'
if valid
put it in array
Para código python , você pode modificar o código deste snippet . Não há necessidade de definir o daemon de spawn.
Para completar, aqui o código-fonte completo de /path/to/perl/script.pl
#!/usr/bin/perl -w
use strict;
use Sys::Syslog qw(:DEFAULT setlogsock);
use Getopt::Long;
#
# Syslogging options for verbose mode and for fatal errors.
# NOTE: comment out the $syslog_socktype line if syslogging does not
# work on your system.
#
my $syslog_socktype = 'unix'; # inet, unix, stream, console
my $syslog_facility = 'mail';
my $syslog_options = 'pid';
my $syslog_priority = 'info';
# Configuration
my $executable_path = '/my/execute/script.sh';
#
# Procedures
#
#
# Log an error and abort.
#
sub fatal_exit {
my $first = shift @_;
syslog "err", "fatal: $first", @_;
exit 1;
}
# SMTPD access policy routine. The result is an action just like
# it would be specified on the right-hand side of a Postfix access
# table. Request attributes are available via the %attr hash.
sub smtpd_access_policy() {
system($executable_path, $attr{'recipient'});
# -1 command error
# 0 user isn't valid
# else user valud
if ( $? == -1 ) {
# command error
return "defer_if_permit Something error"
}
if ( $? == 0 ) {
return "reject user not found";
}
return "dunno";
}
#
# Main program
#
#
# This process runs as a daemon, so it can't log to a terminal. Use
# syslog so that people can actually see our messages.
#
setlogsock $syslog_socktype;
openlog $0, $syslog_options, $syslog_facility;
unless(GetOptions('v:+' => \$verbose)) {
syslog $syslog_priority, "Invalid option. Usage: %s [-v] [-v] ...", $0;
exit 1;
}
#
# Unbuffer standard output.
#
select((select(STDOUT), $| = 1)[0]);
#
# Receive a bunch of attributes, evaluate the policy, send the result.
#
while (<STDIN>) {
chomp;
if (/^([^=]+)=(.*)$/) {
$attr{substr($1, 0, 512)} = substr($2, 0, 512);
} elsif ($_ eq '') {
if ($verbose>2) {
for (keys %attr) {
syslog $syslog_priority, "Attribute: %s=%s", $_, $attr{$_};
}
}
fatal_exit "unrecognized request type: '%s'", $attr{'request'}
unless $attr{'request'} eq 'smtpd_access_policy';
my $action = smtpd_access_policy();
syslog $syslog_priority, "Action: %s", $action if $verbose>1;
print STDOUT "action=$action\n\n";
%attr = ();
} else {
syslog $syslog_priority, "warning: ignoring garbage: %.100s", $_;
}
}
exit 0;