From: Wietse Venema Date: Tue, 15 Apr 2003 05:00:00 +0000 (-0500) Subject: postfix-2.0.8 X-Git-Tag: v2.0.8^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b6ffdc7df16187ba7e46752862bd50aea0728e79;p=thirdparty%2Fpostfix.git postfix-2.0.8 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 283e48572..638882f1a 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -7700,8 +7700,30 @@ Apologies for any names omitted. for non-existent addresses. This required re-architecting the recipient table lookup code. File: smtpd/smtpd_check.c. +20030410 + + Safety: log a fatal error when a net/mask pattern has a + non-zero host part, so that mail delivery is deferred. + File: util/match_ops.c. + +20030411 + + Bugfix: extraneous warning about out-of-order original + recipient records by Patrik Rak. Files: *qmgr/qmgr_message.c. + +10030415 + + Workaround: log a warning and reset incoming queue file + time stamps when the file system clock is ahead of the + local clock, instead of ignoring new mail until the next + queue scan. The file system clock drift detection executes + only once per process instance, to minimize the performance + impact. File: global/mail_stream.c. + Open problems: + 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). diff --git a/postfix/INSTALL b/postfix/INSTALL index b2361a488..4544120cd 100644 --- a/postfix/INSTALL +++ b/postfix/INSTALL @@ -144,15 +144,19 @@ configuration directory other than /etc/postfix, use: Be sure to get the quotes right. These details matter a lot. -Other parameters whose defaults can be specified in this way are: - - Macro name default value for - ------------------------------------- - DEF_COMMAND_DIR command_directory - DEF_DAEMON_DIR daemon_directory - DEF_SENDMAIL_PATH sendmail_path - DEF_MAILQ_PATH mailq_path - DEF_NEWALIAS_PATH newaliases_path +Parameters whose defaults can be specified in this way are: + + Macro name default value for typical default + ----------------------------------------------------------- + DEF_COMMAND_DIR command_directory /usr/sbin + DEF_CONFIG_DIR config_directory /etc/postfix + DEF_DAEMON_DIR daemon_directory /usr/libexec/postfix + DEF_MAILQ_PATH mailq_path /usr/bin/mailq + DEF_MANPAGE_DIR manpage_directory /usr/local/man + DEF_NEWALIAS_PATH newaliases_path /usr/bin/newaliases + DEF_README_DIR readme_directory no (do not install) + DEF_SAMPLE_DIR sample_directory /etc/postfix + DEF_SENDMAIL_PATH sendmail_path /usr/sbin/sendmail In order to build Postfix for very large applications, where you expect to run more than 1000 delivery processes, you may need to diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 4977c0ada..731f1a711 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -24,6 +24,23 @@ snapshot release). Patches change the patchlevel and the release date. Snapshots change only the release date, unless they include the same bugfixes as a patch release. +Incompatible changes with Postfix version 2.0.8 (released 20030415) +=================================================================== + +Too many people mess up their net/mask patterns, causing open +mail relay problems. Postfix processes now abort when given a +net/mask pattern with a non-zero host portion (for example, +168.100.189.2/28), and suggest to specify the proper net/mask +pattern instead (for example, 168.100.189.0/28). + +Major changes with Postfix version 2.0.8 (released 20030415) +============================================================ + +Workaround for file system clock drift that caused Postfix to ignore +new mail (this could happen with file systems mounted from a server). +Postfix now logs a warning and proceeds with only slightly reduced +performance, instead of ignoring new mail. + Incompatible changes with Postfix version 2.0.6 (released 20030305) =================================================================== diff --git a/postfix/conf/sample-misc.cf b/postfix/conf/sample-misc.cf index f4911fc27..54d6fea92 100644 --- a/postfix/conf/sample-misc.cf +++ b/postfix/conf/sample-misc.cf @@ -4,6 +4,13 @@ # This file contains example settings for miscellaneous Postfix # configuration parameters. +# The allow_min_user parameter specifies whether a recipient address +# can have a '-' as the first character. By default, this is not +# allowed, to avoid accidents with software that passes email addresses +# via the command line. +# +allow_min_user = no + # The always_bcc parameter specifies an optional address that # receives a copy of each message that enters the Postfix system, # not including bounces that are generated locally. diff --git a/postfix/html/basic.html b/postfix/html/basic.html index abaf63454..0e4262009 100644 --- a/postfix/html/basic.html +++ b/postfix/html/basic.html @@ -355,9 +355,10 @@ top-level domain).

My own networks

The mynetworks parameter lists all networks that this machine -somehow trusts. This information can be used by the -anti-UCE features to recognize trusted SMTP clients that are -allowed to relay mail through Postfix. +somehow trusts. This information can be used by the anti-UCE features +to recognize trusted SMTP clients that are allowed to relay mail +through Postfix.

diff --git a/postfix/html/virtual.5.html b/postfix/html/virtual.5.html index 2f855eac8..30011e065 100644 --- a/postfix/html/virtual.5.html +++ b/postfix/html/virtual.5.html @@ -138,9 +138,9 @@ VIRTUAL(5) VIRTUAL(5) user2@virtual-alias.domain address2, address3 The virtual-alias.domain anything entry is required for a - virtual alias domain. Without this entry, mail is rejected - with "relay access denied", or bounces with "mail loops - back to myself". + virtual alias domain. Without this entry, mail is rejected + with "relay access denied", or bounces with "mail loops + back to myself". Do not specify virtual alias domain names in the main.cf mydestination or relay_domains configuration parameters. diff --git a/postfix/man/man5/virtual.5 b/postfix/man/man5/virtual.5 index 98a64d047..bec609898 100644 --- a/postfix/man/man5/virtual.5 +++ b/postfix/man/man5/virtual.5 @@ -141,9 +141,9 @@ See the output from \fBpostconf -m\fR for available database types. .fi .sp The \fIvirtual-alias.domain anything\fR entry is required for a -virtual alias domain. Without this entry, mail is rejected +virtual alias domain. \fBWithout this entry, mail is rejected with "relay access denied", or bounces with -"mail loops back to myself". +"mail loops back to myself".\fR Do not specify virtual alias domain names in the \fBmain.cf mydestination\fR or \fBrelay_domains\fR configuration parameters. diff --git a/postfix/postfix-install b/postfix/postfix-install index 6bb2044b2..0bb3b3523 100644 --- a/postfix/postfix-install +++ b/postfix/postfix-install @@ -81,36 +81,37 @@ # The built-in default directory name is the current directory. # This parameter setting is not recorded in the installed main.cf file. # .IP config_directory -# The destination directory for Postfix configuration files. +# The final destination directory for Postfix configuration files. # The built-in default directory name is /etc/postfix. -# This parameter setting is not recorded in the installed main.cf file. +# This parameter setting is not recorded in the installed main.cf file +# and can be changed only by recompiling Postfix. # .IP daemon_directory -# The destination directory for Postfix daemon programs. This directory -# should not be in the command search path of any users. +# The final destination directory for Postfix daemon programs. This +# directory should not be in the command search path of any users. # The built-in default directory name is /usr/libexec/postfix. # This parameter setting is recorded in the installed main.cf file. # .IP command_directory -# The destination directory for Postfix administrative commands. This -# directory should be in the command search path of adminstrative users. -# The built-in default directory name is system dependent. +# The final destination directory for Postfix administrative commands. +# This directory should be in the command search path of adminstrative +# users. The built-in default directory name is system dependent. # This parameter setting is recorded in the installed main.cf file. # .IP queue_directory -# The destination directory for Postfix queues. +# The final destination directory for Postfix queues. # The built-in default directory name is /var/spool/postfix. # This parameter setting is recorded in the installed main.cf file. # .IP sendmail_path -# The full destination pathname for the Postfix sendmail command. +# The final destination pathname for the Postfix sendmail command. # This is the Sendmail-compatible mail posting interface. # The built-in default pathname is system dependent. # This parameter setting is recorded in the installed main.cf file. # .IP newaliases_path -# The full destination pathname for the Postfix newaliases command. +# The final destination pathname for the Postfix newaliases command. # This is the Sendmail-compatible command to build alias databases # for the Postfix local delivery agent. # The built-in default pathname is system dependent. # This parameter setting is recorded in the installed main.cf file. # .IP mailq_path -# The full destination pathname for the Postfix mailq command. +# The final destination pathname for the Postfix mailq command. # This is the Sendmail-compatible command to list the mail queue. # The built-in default pathname is system dependent. # This parameter setting is recorded in the installed main.cf file. @@ -286,30 +287,30 @@ distribution to other machines." tempdir_prompt="a directory for scratch files while installing Postfix. You must have write permission in this directory." -config_directory_prompt="the destination directory for installed -Postfix configuration files." +config_directory_prompt="the final destination directory for +installed Postfix configuration files." -daemon_directory_prompt="the destination directory for installed -Postfix daemon programs. This directory should not be in the -command search path of any users." +daemon_directory_prompt="the final destination directory for +installed Postfix daemon programs. This directory should not be +in the command search path of any users." -command_directory_prompt="the destination directory for installed -Postfix administrative commands. This directory should be in the -command search path of adminstrative users." +command_directory_prompt="the final destination directory for +installed Postfix administrative commands. This directory should +be in the command search path of adminstrative users." -queue_directory_prompt="the destination directory for Postfix +queue_directory_prompt="the final destination directory for Postfix queues." -sendmail_path_prompt="the full destination pathname for the installed -Postfix sendmail command. This is the Sendmail-compatible mail -posting interface." +sendmail_path_prompt="the final destination pathname for the +installed Postfix sendmail command. This is the Sendmail-compatible +mail posting interface." -newaliases_path_prompt="the full destination pathname for the +newaliases_path_prompt="the final destination pathname for the installed Postfix newaliases command. This is the Sendmail-compatible command to build alias databases for the Postfix local delivery agent." -mailq_path_prompt="the full destination pathname for the installed +mailq_path_prompt="the final destination pathname for the installed Postfix mailq command. This is the Sendmail-compatible mail queue listing command." diff --git a/postfix/proto/virtual b/postfix/proto/virtual index 5c559a15a..f0d904aa0 100644 --- a/postfix/proto/virtual +++ b/postfix/proto/virtual @@ -129,9 +129,9 @@ # .fi # .sp # The \fIvirtual-alias.domain anything\fR entry is required for a -# virtual alias domain. Without this entry, mail is rejected +# virtual alias domain. \fBWithout this entry, mail is rejected # with "relay access denied", or bounces with -# "mail loops back to myself". +# "mail loops back to myself".\fR # # Do not specify virtual alias domain names in the \fBmain.cf # mydestination\fR or \fBrelay_domains\fR configuration parameters. diff --git a/postfix/src/global/mail_stream.c b/postfix/src/global/mail_stream.c index 6e4812e03..094cb00b0 100644 --- a/postfix/src/global/mail_stream.c +++ b/postfix/src/global/mail_stream.c @@ -83,6 +83,7 @@ #include #include #include +#include /* Utility library. */ @@ -110,9 +111,10 @@ static VSTRING *id_buf; /* mail_stream_cleanup - clean up after success or failure */ -void mail_stream_cleanup(MAIL_STREAM * info) +void mail_stream_cleanup(MAIL_STREAM *info) { FREE_AND_WIPE(info->close, info->stream); + FREE_AND_WIPE(myfree, info->queue); FREE_AND_WIPE(myfree, info->id); FREE_AND_WIPE(myfree, info->class); FREE_AND_WIPE(myfree, info->service); @@ -121,10 +123,17 @@ void mail_stream_cleanup(MAIL_STREAM * info) /* mail_stream_finish_file - finish file mail stream */ -static int mail_stream_finish_file(MAIL_STREAM * info, VSTRING *unused_why) +static int mail_stream_finish_file(MAIL_STREAM *info, VSTRING *unused_why) { int status = 0; static char wakeup[] = {TRIGGER_REQ_WAKEUP}; + struct stat st; + time_t now; + struct utimbuf tbuf; + char *path_to_reset = 0; + static int incoming_fs_clock_ok = 0; + static int incoming_clock_warned = 0; + int check_incoming_fs_clock; /* * Make sure the message makes it to file. Set the execute bit when no @@ -137,15 +146,50 @@ static int mail_stream_finish_file(MAIL_STREAM * info, VSTRING *unused_why) * as are files with unknown record type codes. Every Postfix queue file * must end with an explicit END record. Postfix queue files without END * record are discarded. + * + * Attempt to detect file system clocks that are ahead of local time, but + * don't check the file system clock all the time. The effect of file + * system clock drift can be difficult to understand (Postfix ignores new + * mail until the next queue run). + * + * This clock drift detection code may not work with file systems that work + * on a local copy of the file and that update the server only after the + * file is closed. */ + check_incoming_fs_clock = + (!incoming_fs_clock_ok && !strcmp(info->queue, MAIL_QUEUE_INCOMING)); + if (vstream_fflush(info->stream) || fchmod(vstream_fileno(info->stream), 0700 | info->mode) #ifdef HAS_FSYNC || fsync(vstream_fileno(info->stream)) #endif + || (check_incoming_fs_clock + && fstat(vstream_fileno(info->stream), &st) < 0) ) status = (errno == EFBIG ? CLEANUP_STAT_SIZE : CLEANUP_STAT_WRITE); +#ifdef TEST + st.st_mtime += 10; +#endif + + /* + * Work around file system clocks that are ahead of local time. + */ + if (status == CLEANUP_STAT_OK && check_incoming_fs_clock) { + if (st.st_mtime <= time(&now)) { + incoming_fs_clock_ok = 1; + } else { + path_to_reset = mystrdup(VSTREAM_PATH(info->stream)); + if (incoming_clock_warned == 0) { + msg_warn("file system clock is %d seconds ahead of local clock", + (int) (st.st_mtime - now)); + msg_warn("resetting file time stamps - this hurts performance"); + incoming_clock_warned = 1; + } + } + } + /* * Close the queue file and mark it as closed. Be prepared for * vstream_fclose() to fail even after vstream_fflush() and fsync() @@ -158,6 +202,16 @@ static int mail_stream_finish_file(MAIL_STREAM * info, VSTRING *unused_why) status = (errno == EFBIG ? CLEANUP_STAT_SIZE : CLEANUP_STAT_WRITE); info->stream = 0; + /* + * Work around file system clocks that are ahead of local time. + */ + if (path_to_reset != 0) { + tbuf.actime = tbuf.modtime = now; + if (utime(path_to_reset, &tbuf) < 0 && errno != ENOENT) + msg_fatal("%s: update file time stamps: %m", info->id); + myfree(path_to_reset); + } + /* * When all is well, notify the next service that a new message has been * queued. @@ -174,7 +228,7 @@ static int mail_stream_finish_file(MAIL_STREAM * info, VSTRING *unused_why) /* mail_stream_finish_ipc - finish IPC mail stream */ -static int mail_stream_finish_ipc(MAIL_STREAM * info, VSTRING *why) +static int mail_stream_finish_ipc(MAIL_STREAM *info, VSTRING *why) { int status = CLEANUP_STAT_WRITE; @@ -199,7 +253,7 @@ static int mail_stream_finish_ipc(MAIL_STREAM * info, VSTRING *why) /* mail_stream_finish - finish action */ -int mail_stream_finish(MAIL_STREAM * info, VSTRING *why) +int mail_stream_finish(MAIL_STREAM *info, VSTRING *why) { return (info->finish(info, why)); } @@ -220,6 +274,7 @@ MAIL_STREAM *mail_stream_file(const char *queue, const char *class, info->stream = stream; info->finish = mail_stream_finish_file; info->close = vstream_fclose; + info->queue = mystrdup(queue); info->id = mystrdup(basename(VSTREAM_PATH(stream))); info->class = mystrdup(class); info->service = mystrdup(service); @@ -247,6 +302,7 @@ MAIL_STREAM *mail_stream_service(const char *class, const char *name) info->stream = stream; info->finish = mail_stream_finish_ipc; info->close = vstream_fclose; + info->queue = 0; info->id = mystrdup(vstring_str(id_buf)); info->class = 0; info->service = 0; @@ -297,6 +353,7 @@ MAIL_STREAM *mail_stream_command(const char *command) info->stream = stream; info->finish = mail_stream_finish_ipc; info->close = vstream_pclose; + info->queue = 0; info->id = mystrdup(vstring_str(id_buf)); info->class = 0; info->service = 0; diff --git a/postfix/src/global/mail_stream.h b/postfix/src/global/mail_stream.h index c9fbfd97a..a1e64f13e 100644 --- a/postfix/src/global/mail_stream.h +++ b/postfix/src/global/mail_stream.h @@ -27,6 +27,7 @@ typedef int (*MAIL_STREAM_CLOSE_FN) (VSTREAM *); struct MAIL_STREAM { VSTREAM *stream; /* file or pipe or socket */ + char *queue; /* (initial) queue name */ char *id; /* queue id */ MAIL_STREAM_FINISH_FN finish; /* finish code */ MAIL_STREAM_CLOSE_FN close; /* close stream */ diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index d3ee7e8c2..f6422cad2 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,10 +20,10 @@ * 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 "20030319" +#define MAIL_RELEASE_DATE "20030415" #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "2.0.7" +#define DEF_MAIL_VERSION "2.0.8" extern char *var_mail_version; /* diff --git a/postfix/src/nqmgr/qmgr_message.c b/postfix/src/nqmgr/qmgr_message.c index 943d3b757..0da7e08cd 100644 --- a/postfix/src/nqmgr/qmgr_message.c +++ b/postfix/src/nqmgr/qmgr_message.c @@ -397,6 +397,7 @@ static int qmgr_message_read(QMGR_MESSAGE *message) message->rcpt_unread--; } } else if (rec_type == REC_TYPE_RCPT) { + /* See also below for code setting orig_rcpt. */ if (message->rcpt_list.len < recipient_limit) { message->rcpt_unread--; qmgr_rcpt_list_add(&message->rcpt_list, curr_offset, @@ -467,7 +468,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message) orig_rcpt = 0; } if (rec_type == REC_TYPE_ORCP) - orig_rcpt = mystrdup(start); + /* See also above for code clearing orig_rcpt. */ + if (message->rcpt_offset == 0) + orig_rcpt = mystrdup(start); } while (rec_type > 0 && rec_type != REC_TYPE_END); /* diff --git a/postfix/src/qmgr/qmgr_message.c b/postfix/src/qmgr/qmgr_message.c index 233477cd8..9afac7ff9 100644 --- a/postfix/src/qmgr/qmgr_message.c +++ b/postfix/src/qmgr/qmgr_message.c @@ -273,6 +273,7 @@ static int qmgr_message_read(QMGR_MESSAGE *message) "queue %s", message->queue_name); } } else if (rec_type == REC_TYPE_RCPT) { + /* See also below for code setting orig_rcpt. */ #define FUDGE(x) ((x) * (var_qmgr_fudge / 100.0)) if (message->rcpt_list.len < FUDGE(var_qmgr_rcpt_limit)) { qmgr_rcpt_list_add(&message->rcpt_list, curr_offset, @@ -347,7 +348,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message) orig_rcpt = 0; } if (rec_type == REC_TYPE_ORCP) - orig_rcpt = mystrdup(start); + /* See also above for code clearing orig_rcpt. */ + if (message->rcpt_offset == 0) + orig_rcpt = mystrdup(start); } while (rec_type > 0 && rec_type != REC_TYPE_END); /* diff --git a/postfix/src/smtpstone/smtp-source.c b/postfix/src/smtpstone/smtp-source.c index b5aeaddc7..9eafa9a18 100644 --- a/postfix/src/smtpstone/smtp-source.c +++ b/postfix/src/smtpstone/smtp-source.c @@ -651,6 +651,7 @@ static void data_done(int unused_event, char *context) mydate = mail_date(time((time_t *) 0)); mypid = getpid(); } +#if SMTP_PRINTF_NO_LONGER_FLUSHES smtp_printf(session->stream, "From: <%s>", sender); smtp_printf(session->stream, "To: <%s>", recipient); smtp_printf(session->stream, "Date: %s", mydate); @@ -658,6 +659,16 @@ static void data_done(int unused_event, char *context) mypid, vstream_fileno(session->stream), message_count, var_myhostname); if (subject) smtp_printf(session->stream, "Subject: %s", subject); +#else + vstream_fprintf(session->stream, "From: <%s>\r\n", sender); + vstream_fprintf(session->stream, "To: <%s>\r\n", recipient); + vstream_fprintf(session->stream, "Date: %s\r\n", mydate); + vstream_fprintf(session->stream, "Message-Id: <%04x.%04x.%04x@%s>\r\n", + mypid, vstream_fileno(session->stream), message_count, + var_myhostname); + if (subject) + vstream_fprintf(session->stream, "Subject: %s\r\n", subject); +#endif smtp_fputs("", 0, session->stream); } @@ -672,6 +683,11 @@ static void data_done(int unused_event, char *context) smtp_fputs("La de da de da 3.", 17, session->stream); smtp_fputs("La de da de da 4.", 17, session->stream); } else { + + /* + * XXX This may cause the process to block with message content + * larger than VSTREAM_BUFIZ bytes. + */ smtp_fputs(message_data, message_length, session->stream); } diff --git a/postfix/src/util/match_ops.c b/postfix/src/util/match_ops.c index 1bde84abd..d1586f7be 100644 --- a/postfix/src/util/match_ops.c +++ b/postfix/src/util/match_ops.c @@ -207,6 +207,7 @@ int match_hostaddr(int unused_flags, const char *addr, const char *pattern) unsigned long mask_bits; unsigned long net_bits; unsigned long addr_bits; + struct in_addr net_addr; if (msg_verbose) msg_info("%s: %s ~? %s", myname, addr, pattern); @@ -242,7 +243,14 @@ int match_hostaddr(int unused_flags, const char *addr, const char *pattern) if (addr_bits == INADDR_NONE) msg_fatal("%s: bad address argument: %s", myname, addr); mask_bits = htonl((0xffffffff) << (BITS_PER_ADDR - mask_shift)); - return ((addr_bits & mask_bits) == (net_bits & mask_bits)); + if ((addr_bits & mask_bits) == net_bits) + return (1); + if (net_bits & ~mask_bits) { + net_addr.s_addr = (net_bits & mask_bits); + msg_fatal("net/mask pattern %s has a non-null host portion; " + "specify %s/%d if this is really what you want", + pattern, inet_ntoa(net_addr), mask_shift); + } } return (0); }