Autoresponder de postfixadmin
Humberto Luis Salardi Chú
humbertosalardi en yahoo.com.mx
Mar Feb 24 14:56:12 GMT 2009
Buenos días a todos, tengo el siguiente inconveniente:
He levantado un servidor de correos con postfix el cual tiene habilitada la
autenticación de usuarios para el SMTP (para evitar intentos de SPAM),
además he configurado el postfixadmin para la administración de la base de
datos de los correos, he querido habilitar la función Vacation del
postfixadmin y el problema es que el script en perl que trae no está
programado con la autenticación de los usuarios (nunca he programado en
Perl), en el log del vacation.pl aparece el siguiente error:
RCPT TO: error (554 5.7.1 <dirección en dominio.com.pe>: Relay access denied)
El contenido del script es el siguiente:
#!/usr/bin/perl -w
#
# Virtual Vacation 3.1
# by Mischa Peters <mischa at high5 dot net>
# Copyright (c) 2002 - 2005 High5!
# Licensed under GPL for more info check GPL-LICENSE.TXT
#
# Additions:
# 2004/07/13 David Osborn <ossdev at daocon.com>
# strict, processes domain level aliases, more
# subroutines, send reply from original to address
#
# 2004/11/09 David Osborn <ossdev at daocon.com>
# Added syslog support
# Slightly better logging which includes messageid
# Avoid infinite loops with domain aliases
#
# 2005-01-19 Troels Arvin <troels en arvin.dk>
# PostgreSQL-version.
# Normalized DB schema from one vacation table ("vacation")
# to two ("vacation", "vacation_notification"). Uses
# referential integrity CASCADE action to simplify cleanup
# when a user is no longer on vacation.
# Inserting variables into queries stricly by prepare()
# to try to avoid SQL injection.
# International characters are now handled well.
#
# 2005-01-21 Troels Arvin <troels en arvin.dk>
# Uses the Email::Valid package to avoid sending notices
# to obviously invalid addresses.
#
# 2007-08-15 David Goodwin <david en palepurple.co.uk>
# Use the Perl Mail::Sendmail module for sending mail
# Check for headers that start with blank lines (patch from
forum)
#
# 2007-08-20 Martin Ambroz <amsys en trustica.cz>
# Added initial Unicode support
#
# 2008-05-09 Fabio Bonelli <fabiobonelli en libero.it>
# Properly handle failed queries to vacation_notification.
# Fixed log reporting.
#
# Requirements:
# You need to have the DBD::Pg or DBD::mysql perl-module installed.
# You need to have the Mail::Sendmail module installed.
# You need to have the Email::Valid module installed.
# You need to have the MIME::Charset module installed.
# You need to have the MIME::EncWords module installed.
#
# On Debian based systems :
# libmail-sendmail-perl
# libdbd-pg-perl
# libemail-valid-perl
# libmime-perl
# libmime-charset-perl (currently in testing, see instructions below)
# libmime-encwords-perl (currently in testing, see instructions below)
#
# Note: When you use this module, you may start seeing error messages
# like "Cannot insert a duplicate key into unique index
# vacation_notification_pkey" in your system logs. This is expected
# behavior, and not an indication of trouble (see the "already_notified"
# subroutine for an explanation).
#
# You must also have the Email::Valid and MIME-tools perl-packages
# installed. They are available in some package collections, under the
# names 'perl-Email-Valid' and 'perl-MIME-tools', respectively.
# One such package collection (for Linux) is:
# http://dag.wieers.com/home-made/apt/packages.php
#
# ========== begin configuration ==========
# IMPORTANT: If you put passwords into this script, then remember
# to restrict access to the script, so that only the vacation user
# can read it.
# db_type - uncomment one of these
#my $db_type = 'Pg';
my $db_type = 'mysql';
# leave empty for connection via UNIX socket
my $db_host = 'localhost';
# connection details
my $db_username = 'root';
my $db_password = 'xxxxxxx';
my $db_name = 'postfix';
# smtp server used to send vacation e-mails
my $smtp_server = 'localhost';
my $syslog = 1;
# path to logfile, when empty logging is supressed
my $logfile='/var/log/vacation/vacation.log';
#my $logfile = "/var/log/vacation/vacation.log";
# path to file for debugging, debug supressed when empty
my $debugfile='/ var/log/vacation/vacation.debug';
#my $debugfile = "/var/log/vacation/vacation.debug";
# =========== end configuration ===========
use DBI;
use MIME::Base64;
use MIME::EncWords qw(:all);
use Email::Valid;
use strict;
use Mail::Sendmail;
binmode (STDIN,':utf8');
my $dbh;
if ($db_host) {
$dbh =
DBI->connect("DBI:$db_type:dbname=$db_name;host=$db_host","$db_username",
"$db_password", { RaiseError => 1 });
} else {
$dbh = DBI->connect("DBI:$db_type:dbname=$db_name","$db_username",
"$db_password", { RaiseError => 1 });
}
if (!$dbh) {
panic("Could not connect to database");
exit(0);
}
my $db_true; # MySQL and PgSQL use different values for TRUE
if ($db_type eq "mysql") {
$dbh->do("SET CHARACTER SET utf8;");
$db_true = '1';
} else { # Pg
# TODO: SET CHARACTER SET is mysql only, needs FIX for ALL databases
$db_true = 'True';
}
# used to detect infinite address lookup loops
my $loopcount=0;
sub do_debug {
if ( $debugfile ) {
my $date;
open (DEBUG, ">> $debugfile") or die ("Unable to open debug file");
binmode (DEBUG, ':utf8');
chop ($date = `date "+%Y/%m/%d %H:%M:%S"`);
print DEBUG "====== $date ======\n";
my $i;
for ($i=0;$i<$#_;$i++) {
print DEBUG $_[$i], ' | ';
}
print DEBUG $_[($#_)], "\n";
close (DEBUG);
}
}
sub already_notified {
my ($to, $from) = @_;
my $query = qq{INSERT into vacation_notification (on_vacation,notified)
values (?,?)};
my $stm = $dbh->prepare($query);
if (!$stm) {
do_log('',$to,$from,'',"Could not prepare query $query");
return 1;
}
$stm->{'PrintError'} = 0;
$stm->{'RaiseError'} = 0;
if (!$stm->execute($to,$from)) {
my $e=$dbh->errstr;
# Violation of a primay key constraint may happen here, and that's
# fine. All other error conditions are not fine, however.
if ($e !~ /_pkey/) {
do_log('',$to,$from,'',"Unexpected error: '$e' from query
'$query'");
# Let's play safe and notify anyway
return 0;
}
return 1;
}
return 0;
}
sub do_log {
my ($messageid, $to, $from, $subject, $logmessage) = @_;
my $date;
if ( $syslog ) {
open (SYSLOG, "|/usr/bin/logger -p mail.info -t Vacation") or die
("Unable to open logger");
binmode(SYSLOG, ':utf8');
if ($logmessage) {
printf SYSLOG "Orig-To: %s From: %s MessageID: %s Subject: %s. Log
message: %s", $to, $from, $messageid, $subject, $logmessage;
} else {
printf SYSLOG "Orig-To: %s From: %s MessageID: %s Subject: %s",
$to, $from, $messageid, $subject;
}
close (SYSLOG);
}
if ( $logfile ) {
open (LOG, ">> $logfile") or die ("Unable to open log file");
binmode (LOG, ':utf8');
chop ($date = `date "+%Y/%m/%d %H:%M:%S"`);
if ($logmessage) {
print LOG "$date: To: $to From: $from Subject: $subject MessageID:
$messageid. Log message: $logmessage\n";
} else {
print LOG "$date: To: $to From: $from Subject: $subject MessageID:
$messageid\n";
}
close (LOG);
}
}
sub do_mail {
# from, to, subject, body
my ($from, $to, $subject, $body) = @_;
my $vacation_subject = encode_mimewords($subject, 'Encoding'=> 'q',
'Charset'=>'utf-8', 'Field'=>'Subject');
my %mail;
%mail = (
'smtp' => $smtp_server,
'Subject' => $vacation_subject,
'From' => $from,
'To' => $to,
'MIME-Version' => '1.0',
'Content-Type' => 'text/plain; charset=UTF-8',
'Content-Transfer-Encoding' => 'base64',
'Precedence' => 'junk',
'X-Loop' => 'Postfix Admin Virtual Vacation',
'Message' => encode_base64($body)
);
sendmail(%mail) or do_log($Mail::Sendmail::error);
do_debug('Mail::Sendmail said :' . $Mail::Sendmail::log);
}
sub panic {
my ($arg) = @_;
do_log('','','','',"$arg");
exit(0);
}
sub panic_prepare {
my ($arg) = @_;
do_log('','','','',"Could not prepare '$arg'");
exit(0);
}
sub panic_execute {
my ($arg,$param) = @_;
do_log('','','','',"Could not execute '$arg' with parameters $param");
exit(0);
}
sub find_real_address {
my ($email) = @_;
if (++$loopcount > 20) {
do_log ("find_real_address loop!", "currently: $email", "ERROR",
"ERROR");
panic("possible infinite loop in find_real_address for <$email>. Check
for alias loop\n");
}
my $realemail;
my $query = qq{SELECT email FROM vacation WHERE email=? and
active=$db_true};
my $stm = $dbh->prepare($query) or panic_prepare($query);
$stm->execute($email) or panic_execute($query,"email='$email'");
my $rv = $stm->rows;
# Recipient has vacation
if ($rv == 1) {
$realemail = $email;
} else {
$query = qq{SELECT goto FROM alias WHERE address=?};
$stm = $dbh->prepare($query) or panic_prepare($query);
$stm->execute($email) or panic_execute($query,"address='$email'");
$rv = $stm->rows;
# Recipient is an alias, check if mailbox has vacation
if ($rv == 1) {
my @row = $stm->fetchrow_array;
my $alias = $row[0];
$query = qq{SELECT email FROM vacation WHERE email=? and
active=$db_true};
$stm = $dbh->prepare($query) or panic_prepare($query);
$stm->execute($alias) or panic_prepare($query,"email='$alias'");
$rv = $stm->rows;
# Alias has vacation
if ($rv == 1) {
$realemail = $alias;
}
# We still have to look for domain level aliases...
} else {
my ($user, $domain) = split(/@/, $email);
$query = qq{SELECT goto FROM alias WHERE address=?};
$stm = $dbh->prepare($query) or panic_prepare($query);
$stm->execute("\@$domain") or
panic_execute($query,"address='\@$domain'");
$rv = $stm->rows;
# The receipient has a domain level alias
if ($rv == 1) {
my @row = $stm->fetchrow_array;
my $wildcard_dest = $row[0];
my ($wilduser, $wilddomain) = split(/@/, $wildcard_dest);
# Check domain alias
if ($wilduser) {
($rv, $realemail) = find_real_address ($wildcard_dest);
} else {
my $new_email = $user . '@' . $wilddomain;
($rv, $realemail) = find_real_address ($new_email);
}
}
}
}
return ($rv, $realemail);
}
sub send_vacation_email {
my ($email, $orig_from, $orig_to, $orig_messageid) = @_;
my $query = qq{SELECT subject,body FROM vacation WHERE email=?};
my $stm = $dbh->prepare($query) or panic_prepare($query);
$stm->execute($email) or panic_execute($query,"email='$email'");
my $rv = $stm->rows;
if ($rv == 1) {
my @row = $stm->fetchrow_array;
if (already_notified($email, $orig_from)) { return; }
do_debug ("[SEND RESPONSE] for $orig_messageid:\n", "FROM: $email
(orig_to: $orig_to)\n", "TO: $orig_from\n", "VACATION SUBJECT: $row[0]\n",
"VACATION BODY: $row[1]\n");
# do_mail(from, to, subject, body);
do_mail ($email, $orig_from, $row[0], $row[1]);
do_log ($orig_messageid, $orig_to, $orig_from, '');
}
}
########################### main #################################
my ($from, $to, $cc, $subject, $messageid, $lastheader);
$subject='';
# Take headers apart
while (<STDIN>) {
last if (/^$/);
if (/^\s+(.*)/ and $lastheader) { $$lastheader .= " $1"; }
elsif (/^from:\s+(.*)\n$/i) { $from = $1; $lastheader = \$from; }
elsif (/^to:\s+(.*)\n$/i) { $to = $1; $lastheader = \$to; }
elsif (/^cc:\s+(.*)\n$/i) { $cc = $1; $lastheader = \$cc; }
elsif (/^subject:\s+(.*)\n$/i) { $subject = $1; $lastheader = \$subject;
}
elsif (/^message-id:\s+(.*)\n$/i) { $messageid = $1; $lastheader =
\$messageid; }
elsif (/^x-spam-(flag|status):\s+yes/i) { exit (0); }
elsif (/^precedence:\s+(bulk|list|junk)/i) { exit (0); }
elsif (/^x-loop:\s+postfix\ admin\ virtual\ vacation/i) { exit (0); }
else {$lastheader = "" ; }
}
# If either From: or To: are not set, exit
if (!$from || !$to || !$messageid) { exit (0); }
$from = lc ($from);
if (!Email::Valid->address($from,-mxcheck => 1)) { do_debug("Invalid from
email address: $from; exiting."); exit(0); }
# Check if it's an obvious sender, exit
if ($from =~ /([\w\-.%]+\@[\w.-]+)/) { $from = $1; }
if ($from eq "" || $from =~
/^owner-|-(request|owner)\@|^(mailer-daemon|postmaster)\@/i) { exit (0); }
# Strip To: and Cc: and push them in array
my @strip_cc_array;
my @strip_to_array = split(/, */, lc ($to) );
if (defined $cc) { @strip_cc_array = split(/, */, lc ($cc) ); }
push (@strip_to_array, @strip_cc_array);
my @search_array;
# Strip email address from headers
for (@strip_to_array) {
if ($_ =~ /([\w\-.%]+\@[\w.-]+)/) {
push (@search_array, $1);
do_debug ("[STRIP RECIPIENTS]: ", $messageid, $1);
}
}
# Search for email address which has vacation
for (@search_array) {
/([\w\-.%]+\@[\w.-]+)/ or next;
my $addr = $1;
my ($rv, $email) = find_real_address ($addr);
if ($rv == 1) {
do_debug ("[FOUND VACATION]: ", $messageid, $from, $to, $email);
send_vacation_email( $email, $from, $to, $messageid);
}
}
0;
#/* vim: set expandtab softtabstop=3 tabstop=3 shiftwidth=3: */
Alguna idea para solucionarlo?
Gracias de antemano
http://www.fuvensa.com/images/CH&T%20-%20Logo.jpg
Humberto Luis Salardi Chú
Telefax: (511) 243 2234
Móvil: (511) 99789 9040
Nextel: 51*415*0170
email: <mailto:hsalardi en fuvensa.com> hsalardi en fuvensa.com
URL: <http://www.fuvensa.com> http://www.fuvensa.com
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: https://lists.ubuntu.com/archives/ubuntu-pe/attachments/20090224/5471a39e/attachment-0001.htm
------------ próxima parte ------------
Se ha borrado un mensaje que no está en formato texto plano...
Nombre : no disponible
Tipo : image/jpeg
Tamaño : 2530 bytes
Descripción: no disponible
Url : https://lists.ubuntu.com/archives/ubuntu-pe/attachments/20090224/5471a39e/attachment-0001.jpeg
Más información sobre la lista de distribución ubuntu-pe