and 2) MIME input processing is turned off, and 3) MIME
8bit->7bit conversion is requested upon delivery via SMTP.
+20030424
+
+ Cleanup: readlline() did not terminate the result before
+ complaining about lines starting with whitespace.
+
+ Cleanup: eliminated valid_hostname warning for invalid
+ queue file names. File: global/mail_queue.c.
+
+ Bugfix: the Postfix sendmail command applied the message
+ size limit when running as newaliases. The limiting code
+ is now moved to the message enqueuing branch of the code.
+ File: sendmail/sendmail.c.
+
+20030429
+
+ Bugfix: "," was not recognized in proxy_read_maps settings.
+ Fix by Leandro Santi. File: proxymap/proxymap.c.
+
+20030502
+
+ Bugfix: defer delivery after .forward etc. file read error.
+ File: local/token.c. Problem reported by Ben Rosengart,
+ Panix.
+
+20030520
+
+ Cleanup: future time stamps in Received: headers and negative
+ delays in delivery agent logging after "postdrop -r",
+ because deferred queue files had future file modification
+ times. File: src/postsuper/postsuper.c.
+
+20030521
+
+ Cleanup: nqmgr warnings about "recipient count mismatch"
+ after "postdrop -r", because the cleanup server did not
+ count the "already done" recipients. Problem reported by
+ Richard Stockton, Gramma Software. Files:
+ cleanup/cleanup_envelope.c, cleanup/cleanup_extracted.c
+
Open problems:
- Low: smtp-source may block when sending large test messages.
+ Low: smtp-source may block when sending large test messages.
Low: after successful delivery, per-queue window += 1/window,
after failure, queue window -= 1 (Victor).
Note: the localhost port 10025 SMTP server filter should announce
itself as "220 localhost...". Postfix aborts delivery when it
-connects to an SMTP server that uses the same hostname, because
-that normally means you have a mail delivery loop problem.
+connects to an SMTP server that uses the same hostname as Postfix
+("host <servername> greeted me with my own hostname"), because that
+normally means you have a mail delivery loop problem.
The example here assumes that the /some/where/filter command is a
PERL script. PERL has modules that make talking SMTP easy. The
The "-o local_recipient_maps=" and "-o relay_recipient_maps=" avoid
unnecessary table lookups.
-The "-o myhostname=localhost.domain.tld" avoids a possible problem
-if your content filter is based on a proxy that simply relays SMTP
-commands.
+The "-o myhostname=localhost.domain.tld" avoids false alarms ("host
+<servername> greeted me with my own hostname") if your content
+filter is based on a proxy that simply relays SMTP commands.
The "-o smtpd_xxx_restrictions" and "-o mynetworks=127.0.0.0/8"
turn off UCE controls that would only waste time here.
SASL authentication information is not passed on via message headers
or via SMTP. It is no-one's business what username and authentication
-method the poster was using in order to access the mail server.
+method the poster was using in order to access the mail server. The
+people who need to know can find the information in the maillog file.
When sending mail, Postfix looks up the server hostname or destination
domain (the address remote part) in a table, and if a username/password
mmencode is part of the metamail software.
MIME::Base64 is available from www.cpan.org.
+Trouble shooting the SASL internals
+===================================
+
+[based on text by Liviu Daia]
+
+In the Cyrus SASL sources you'll find a subdirectory named "sample".
+Run make there, then run the resulting sample server and client in
+separate terminals. Strace / ktrace / truss the server to see what
+makes it unhappy, fix the problem, then write the authors thanking
+them for providing such useful logging. Repeat the previous step
+until you can successfully authenticate with the sample client.
+Only then get back to Postfix.
+
Enabling SASL authentication in the Postfix SMTP client
=======================================================
maps, and the mailbox location map can specify either mailbox or
maildir delivery (controlled by trailing slash on mailbox name).
-The agent does not support user+foo address extensions, aliases or
-.forward files (use the virtual table instead), and therefore
-doesn't support file or program aliases. This choice was made to
-simplify and streamline the code (it allowed me to dispense with
-70% of local's code - mostly the bits that are a security headache)
-- if you need this functionality, this agent isn't for you.
+The agent allows but ignores user+foo address extensions, does not
+support aliases or .forward files (use the virtual table instead),
+and therefore doesn't support file or program aliases. This choice
+was made to simplify and streamline the code (it allowed me to
+dispense with 70% of local's code - mostly the bits that are a
+security headache) - if you need this functionality, this agent
+isn't for you.
It also doesn't support writing to a common spool as root and then
chowning the mailbox to the user - I felt this functionality didn't
Specifies the list of domains that should be delivered to the
$virtual_transport delivery agent (default: virtual). As of
- version 1.2, Postfix is smart enough that you don't have to
+ version 2.0, Postfix is smart enough that you don't have to
list every virtual domain in a Postfix transport map.
virtual_mailbox_maps
==============================================================
This example does not use the Postfix local delivery agent at all.
-With this configuration Postfix does no user+foo address extension,
-no alias expansion, no .forward file expansion, and no lookups of
-recipients in /etc/passwd.
+With this configuration Postfix does no alias expansion, no .forward
+file expansion, no lookups of recipients in /etc/passwd, and allows
+but ignores user+foo address extensions.
Instead of "hash" specify "dbm" or "btree", depending on your system
type. The command "postconf -m" displays possible lookup table
#
-# Postfix master process configuration file. Each line describes how
-# a mailer component program should be run. The fields that make up
-# each line are described below. A "-" field value requests that a
-# default value be used for that field.
+# Postfix master process configuration file. Each logical line
+# describes how a Postfix daemon program should be run.
+#
+# A logical line starts with non-whitespace, non-comment text.
+# Empty lines and whitespace-only lines are ignored, as are comment
+# lines whose first non-whitespace character is a `#'.
+# A line that starts with whitespace continues a logical line.
+#
+# The fields that make up each line are described below. A "-" field
+# value requests that a default value be used for that field.
#
# Service: any name that is valid for the specified transport type
# (the next field). With INET transports, a service is specified as
# SPECIFY ONLY PROGRAMS THAT ARE WRITTEN TO RUN AS POSTFIX DAEMONS.
# ALL DAEMONS SPECIFIED HERE MUST SPEAK A POSTFIX-INTERNAL PROTOCOL.
#
-# DO NOT CHANGE THE ZERO PROCESS LIMIT FOR CLEANUP/BOUNCE/DEFER OR
-# POSTFIX WILL BECOME STUCK UP UNDER HEAVY LOAD
-#
-# DO NOT CHANGE THE ONE PROCESS LIMIT FOR PICKUP/QMGR OR POSTFIX WILL
-# DELIVER MAIL MULTIPLE TIMES.
-#
# DO NOT SHARE THE POSTFIX QUEUE BETWEEN MULTIPLE POSTFIX INSTANCES.
#
# ==========================================================================
#
# EXAMPLE SMTPD ACCESS MAP
# # Protect your outgoing majordomo exploders
-# /^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
+# /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
#
# # Bounce friend@whatever, except when whatever is our domain (you would
# # be better just bouncing all friend@ mail - this is just an example).
#
# This blocks mail from poorly written mail software.
#
-strict_mime_domain_encoding = no
+strict_mime_encoding_domain = no
# Protect your outgoing majordomo exploders
#
-/^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
+/^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
# Bounce friend@whatever, except when whatever is our domain (you would
/^postmaster@/ OK
# Protect your outgoing majordomo exploders
-/^(.*)-outgoing@(.*)$/!/^owner-.*/ 550 Use ${1}@${2} instead
+if !/^owner-.*/
+/^(.*)-outgoing@(.*)$/ 550 Use ${1}@${2} instead
+endif
ple, bounces from qmail or from old versions of
Postfix).
- <b>strict</b><i>_</i><b>mime</b><i>_</i><b>domain</b><i>_</i><b>encoding</b>
+ <b>strict</b><i>_</i><b>mime</b><i>_</i><b>encoding</b><i>_</i><b>domain</b>
Reject mail with invalid <b>Content-Transfer-Encoding:</b>
information for message/* or multipart/*. This
blocks mail from poorly written software.
<b>EXAMPLE</b> <b>SMTPD</b> <b>ACCESS</b> <b>MAP</b>
# Protect your outgoing majordomo exploders
- /^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
+ /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
# Bounce friend@whatever, except when whatever is our domain (you would
# be better just bouncing all friend@ mail - this is just an example).
.na
.nf
# Protect your outgoing majordomo exploders
-/^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
+/^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
# Bounce friend@whatever, except when whatever is our domain (you would
# be better just bouncing all friend@ mail - this is just an example).
request contains valid 8-bit MIME mail, and it breaks bounces from
mailers that do not properly encapsulate 8-bit content (for example,
bounces from qmail or from old versions of Postfix).
-.IP \fBstrict_mime_domain_encoding\fR
+.IP \fBstrict_mime_encoding_domain\fR
Reject mail with invalid \fBContent-Transfer-Encoding:\fR
information for message/* or multipart/*. This blocks mail
from poorly written software.
# or $(n) if they aren't followed by whitespace.
# EXAMPLE SMTPD ACCESS MAP
# # Protect your outgoing majordomo exploders
-# /^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
+# /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
#
# # Bounce friend@whatever, except when whatever is our domain (you would
# # be better just bouncing all friend@ mail - this is just an example).
/* request contains valid 8-bit MIME mail, and it breaks bounces from
/* mailers that do not properly encapsulate 8-bit content (for example,
/* bounces from qmail or from old versions of Postfix).
-/* .IP \fBstrict_mime_domain_encoding\fR
+/* .IP \fBstrict_mime_encoding_domain\fR
/* Reject mail with invalid \fBContent-Transfer-Encoding:\fR
/* information for message/* or multipart/*. This blocks mail
/* from poorly written software.
vstring_free(clean_addr);
myfree(state->orig_rcpt);
state->orig_rcpt = 0;
+ } else if (type == REC_TYPE_DONE) {
+ /* void */ ;
} else if (type == REC_TYPE_WARN) {
if ((state->warn_time = atol(buf)) < 0) {
state->errs |= CLEANUP_STAT_BAD;
myfree(state->orig_rcpt);
state->orig_rcpt = 0;
return;
+ } else if (type == REC_TYPE_DONE) {
+ return;
} else if (type == REC_TYPE_ORCP) {
state->orig_rcpt = mystrdup(buf);
+ return;
}
if (type != REC_TYPE_END) {
cleanup_out(state, type, buf, len);
/*
* OK if in valid hostname form.
*/
- return (valid_hostname(queue_id, DO_GRIPE));
+ return (valid_hostname(queue_id, DONT_GRIPE));
}
/* mail_queue_enter - make mail queue entry with locally-unique name */
* Patches change the patchlevel and the release date. Snapshots change the
* release date only, unless they include the same bugfix as a patch release.
*/
-#define MAIL_RELEASE_DATE "20030418"
+#define MAIL_RELEASE_DATE "20030521"
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "2.0.9"
+#define DEF_MAIL_VERSION "2.0.10"
extern char *var_mail_version;
/*
#include <tok822.h>
#include <mail_params.h>
#include <bounce.h>
+#include <defer.h>
/* Application-specific. */
break;
}
}
+ if (vstream_ferror(fp))
+ status = defer_append(BOUNCE_FLAG_KEEP,
+ BOUNCE_ATTR(state.msg_attr),
+ "error reading .forward file: %m");
vstring_free(buf);
return (status);
}
if ((type = rec_get(qfile, buf, var_line_limit)) < 0
|| strchr(expected, type) == 0)
return (file_read_error(info, type));
+ if (msg_verbose)
+ msg_info("%s: read %c %s", info->id, type, vstring_str(buf));
if (type == *expected)
break;
if (type == REC_TYPE_FROM)
info->rcpt = mystrdup(vstring_str(buf));
if (type == REC_TYPE_TIME)
continue;
+ if (type == REC_TYPE_SIZE)
+ continue;
if (type == REC_TYPE_ATTR) {
if ((error_text = split_nameval(vstring_str(buf), &attr_name,
&attr_value)) != 0) {
}
if (rec_type == REC_TYPE_ERROR)
msg_fatal("uid=%ld: malformed input", (long) uid);
- if (rec_type == REC_TYPE_TIME)
- rec_fprintf(dst->stream, REC_TYPE_TIME, "%ld",
- (long) time((time_t *) 0));
if (strchr(*expected, rec_type) == 0)
msg_fatal("uid=%ld: unexpected record type: %d", (long) uid, rec_type);
if (rec_type == **expected)
#include <string.h>
#include <signal.h>
#include <stdio.h> /* remove() */
+#include <utime.h>
/* Utility library. */
VSTRING *new_path_buf;
int found;
int tries;
+ struct utimbuf tbuf;
/*
* Sanity check. No early returns beyond this point.
continue;
(void) mail_queue_path(new_path_buf, MAIL_QUEUE_MAILDROP, queue_id);
if (postrename(old_path, STR(new_path_buf)) == 0) {
+ tbuf.actime = tbuf.modtime = time((time_t *) 0);
+ if (utime(STR(new_path_buf), &tbuf) < 0)
+ msg_warn("%s: reset time stamps: %m", STR(new_path_buf));
msg_info("%s: requeued", queue_id);
found = 1;
break;
static void post_jail_init(char *unused_name, char **unused_argv)
{
- const char *sep = " \t\r\n";
+ const char *sep = ", \t\r\n";
char *saved_filter;
char *bp;
char *type_name;
*/
buf = vstring_alloc(100);
+ /*
+ * Stop run-away process accidents by limiting the queue file size. This
+ * is not a defense against DOS attack.
+ */
+ if (var_message_limit > 0 && get_file_limit() > var_message_limit)
+ set_file_limit((off_t) var_message_limit);
+
/*
* The sender name is provided by the user. In principle, the mail pickup
* service could deduce the sender name from queue file ownership, but:
*
* XXX Should limit the size of envelope records.
*/
- rec_fprintf(dst, REC_TYPE_TIME, "%ld", (long) time((time_t *) 0));
if (full_name || (full_name = fullname()) != 0)
rec_fputs(dst, REC_TYPE_FULL, full_name);
rec_fputs(dst, REC_TYPE_FROM, saved_sender);
if (chdir(var_queue_dir))
msg_fatal_status(EX_UNAVAILABLE, "chdir %s: %m", var_queue_dir);
- /*
- * Stop run-away process accidents by limiting the queue file size. This
- * is not a defense against DOS attack.
- */
- if (var_message_limit > 0 && get_file_limit() > var_message_limit)
- set_file_limit((off_t) var_message_limit);
-
signal(SIGPIPE, SIG_IGN);
/*
break;
}
}
+ VSTRING_TERMINATE(buf);
/*
* Invalid input: continuing text without preceding text. Allowing this
/*
* Done.
*/
- VSTRING_TERMINATE(buf);
return (LEN(buf) > 0 ? buf : 0);
}