diff --git a/postfix/HISTORY b/postfix/HISTORY index 5f9750b5f..35a4f1d37 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -15274,3 +15274,67 @@ Apologies for any names omitted. Bugfix: don't panic when an unexpected smtpd access map is specified. File: smtpd/smtpd_check.c. + +20090918 + + Bugfix (introduced Postfix 2.3): with Milter RCPT TO replies + turned off, there was no automatic flush-before-read on the + smtpd-to-milter stream, because the read was done on the + cleanup-to-milter stream. Problem reported by Stephen Warren. + File: milter/milter8.c. + +20091005 + + Bugfix: core dump while printing error message for malformed + % sequence in LDAP, MySQL or PostgreSQL configuration. + File: global/db_common.c. Fix by Victor Duchovni. + +20091012 + + Bugfix: postmulti did not skip commands with -p. Luca + Berra. File: postmulti/postmulti.c. + +20091026 + + Cleanup: changed parameter evaluation order so that the + multi_instance_wrapper parameter value is evaluated after + the command and daemon directory parameters. File: + global/mail_params.h. + +20091209 + + Bugfix: sender_dependent_relayhost_maps did not reject an + empty lookup result, and did not recognize lookup errors, + thus treating errors as "not found". Problem found during + code maintenance. File: trivial-rewrite/resolve.c. + +20091229 + + Cleanup: the address_verify_poll_count default parameter + value is now stress-dependent, so that the Postfix SMTP + server will not wait (up to 6 seconds) for the address + verification result. File: global/mail_params.h. + +20100107 + + Documentation: the access(5) manual page did not document + the "send 521 and disconnect" behavior in the Postfix SMTP + server. File: proto/access. + + Bugfix: the pickup daemon did not discard messages that + were requeued after all recipients were delivered (or + bounced), and the cleanup server tried to bounce such + messages. Files: pickup/pickup.c, global/cleanup_user.h. + +20100115 + + Bugfix: the valid_hostname() fuction did not set the + "non-numeric" flag after encountering the '-' character. + Reported by Jan Schampera. File: util/valid_hostname.c. + +20100116 + + Workaround: as of Postfix 2.3 the VRFY command did not allow + a mailbox address inside <>, which broke expectations. RFC + 2821 (and 5321) is vague about the VRFY request format, but + spends lots of text on the reply format. File: smtpd/smtpd.c. diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 0a926aa38..ff0743155 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -241,7 +241,7 @@ Major changes - header rewriting Message-ID: or To: headers only when clients match $local_header_rewrite_clients. Specify "always_add_missing_headers = yes" for backwards compatibility. Adding such headers can break -DKIM signatures that cover headers that are not present. +DKIM signatures that cover headers that are not present. For compatibility with existing logfile processing software, Postfix will log ``message-id=<>'' for messages without Message-Id header. diff --git a/postfix/conf/access b/postfix/conf/access index 00aa6cd19..4a575355e 100644 --- a/postfix/conf/access +++ b/postfix/conf/access @@ -187,8 +187,23 @@ # text. 4NN means "try again later", while 5NN means # "do not try again". # -# The reply code "421" causes Postfix to disconnect -# immediately (Postfix version 2.3 and later). +# The following responses have special meaning for +# the Postfix SMTP server: +# +# 421 text (Postfix 2.3 and later) +# +# 521 text (Postfix 2.6 and later) +# After responding with the numerical three- +# digit code and text, disconnect immediately +# from the SMTP client. This frees up SMTP +# server resources so that they can be made +# available to another SMTP client. +# +# Note: The "521" response should be used only +# with botnets and other malware where inter- +# operability is of no concern. The "send 521 +# and disconnect" behavior is NOT defined in +# the SMTP standard. # # REJECT optional text... # Reject the address etc. that matches the pattern. diff --git a/postfix/html/access.5.html b/postfix/html/access.5.html index 626d105e8..42ffcad42 100644 --- a/postfix/html/access.5.html +++ b/postfix/html/access.5.html @@ -193,8 +193,23 @@ ACCESS(5) ACCESS(5) text. 4NN means "try again later", while 5NN means "do not try again". - The reply code "421" causes Postfix to disconnect - immediately (Postfix version 2.3 and later). + The following responses have special meaning for + the Postfix SMTP server: + + 421 text (Postfix 2.3 and later) + + 521 text (Postfix 2.6 and later) + After responding with the numerical three- + digit code and text, disconnect immediately + from the SMTP client. This frees up SMTP + server resources so that they can be made + available to another SMTP client. + + Note: The "521" response should be used only + with botnets and other malware where inter- + operability is of no concern. The "send 521 + and disconnect" behavior is NOT defined in + the SMTP standard. REJECT optional text... Reject the address etc. that matches the pattern. diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index c18d7c75c..48c7003db 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -256,9 +256,11 @@ How many times to query the verify(8) service for th of an address verification request in progress.

-

-The default poll count is 3. -

+

By default, the Postfix SMTP server polls the verify(8) service +up to three times under non-overload conditions, and only once when +under overload. With Postfix version 2.5 and earlier, the SMTP +server always polls the verify(8) service up to three times by +default.

Specify 1 to implement a crude form of greylisting, that is, always diff --git a/postfix/makedefs b/postfix/makedefs index 483f8953d..320c9ff46 100644 --- a/postfix/makedefs +++ b/postfix/makedefs @@ -144,6 +144,8 @@ case "$SYSTEM.$RELEASE" in ;; FreeBSD.7*) SYSTYPE=FREEBSD7 ;; + FreeBSD.8*) SYSTYPE=FREEBSD8 + ;; OpenBSD.2*) SYSTYPE=OPENBSD2 ;; OpenBSD.3*) SYSTYPE=OPENBSD3 diff --git a/postfix/man/man5/access.5 b/postfix/man/man5/access.5 index 1fb511c80..c3d3e4946 100644 --- a/postfix/man/man5/access.5 +++ b/postfix/man/man5/access.5 @@ -185,9 +185,22 @@ defer actions. See "ENHANCED STATUS CODES" below. Reject the address etc. that matches the pattern, and respond with the numerical three-digit code and text. \fB4\fINN\fR means "try again later", while \fB5\fINN\fR means "do not try again". + +The following responses have special meaning for the Postfix +SMTP server: +.RS +.IP "\fB421 \fItext\fR (Postfix 2.3 and later)" +.IP "\fB521 \fItext\fR (Postfix 2.6 and later)" +After responding with the numerical three-digit code and +text, disconnect immediately from the SMTP client. This +frees up SMTP server resources so that they can be made +available to another SMTP client. .IP -The reply code "421" causes Postfix to disconnect immediately -(Postfix version 2.3 and later). +Note: The "521" response should be used only with botnets +and other malware where interoperability is of no concern. +The "send 521 and disconnect" behavior is NOT defined in +the SMTP standard. +.RE .IP "\fBREJECT \fIoptional text...\fR Reject the address etc. that matches the pattern. Reply with "\fB$access_map_reject_code \fIoptional text...\fR" when the diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index fbe4fd308..b85d17877 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -142,7 +142,11 @@ This feature is available in Postfix 2.1 and later. How many times to query the \fBverify\fR(8) service for the completion of an address verification request in progress. .PP -The default poll count is 3. +By default, the Postfix SMTP server polls the \fBverify\fR(8) service +up to three times under non-overload conditions, and only once when +under overload. With Postfix version 2.5 and earlier, the SMTP +server always polls the \fBverify\fR(8) service up to three times by +default. .PP Specify 1 to implement a crude form of greylisting, that is, always defer the first delivery request for a never seen before address. diff --git a/postfix/proto/access b/postfix/proto/access index 48b6deb1a..208778f4a 100644 --- a/postfix/proto/access +++ b/postfix/proto/access @@ -165,9 +165,22 @@ # Reject the address etc. that matches the pattern, and respond with # the numerical three-digit code and text. \fB4\fINN\fR means "try # again later", while \fB5\fINN\fR means "do not try again". +# +# The following responses have special meaning for the Postfix +# SMTP server: +# .RS +# .IP "\fB421 \fItext\fR (Postfix 2.3 and later)" +# .IP "\fB521 \fItext\fR (Postfix 2.6 and later)" +# After responding with the numerical three-digit code and +# text, disconnect immediately from the SMTP client. This +# frees up SMTP server resources so that they can be made +# available to another SMTP client. # .IP -# The reply code "421" causes Postfix to disconnect immediately -# (Postfix version 2.3 and later). +# Note: The "521" response should be used only with botnets +# and other malware where interoperability is of no concern. +# The "send 521 and disconnect" behavior is NOT defined in +# the SMTP standard. +# .RE # .IP "\fBREJECT \fIoptional text...\fR # Reject the address etc. that matches the pattern. Reply with # "\fB$access_map_reject_code \fIoptional text...\fR" when the diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index e5c12aaeb..ae69f8d3a 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -287,9 +287,11 @@ How many times to query the verify(8) service for the completion of an address verification request in progress.

-

-The default poll count is 3. -

+

By default, the Postfix SMTP server polls the verify(8) service +up to three times under non-overload conditions, and only once when +under overload. With Postfix version 2.5 and earlier, the SMTP +server always polls the verify(8) service up to three times by +default.

Specify 1 to implement a crude form of greylisting, that is, always diff --git a/postfix/src/global/cleanup_user.h b/postfix/src/global/cleanup_user.h index e44f105ab..0a098d3da 100644 --- a/postfix/src/global/cleanup_user.h +++ b/postfix/src/global/cleanup_user.h @@ -65,7 +65,8 @@ * These are set when we can't bounce even if we were asked to. */ #define CLEANUP_STAT_MASK_CANT_BOUNCE \ - (CLEANUP_STAT_BAD | CLEANUP_STAT_WRITE | CLEANUP_STAT_DEFER) + (CLEANUP_STAT_BAD | CLEANUP_STAT_WRITE | CLEANUP_STAT_DEFER \ + | CLEANUP_STAT_RCPT) /* * These are set when we can't examine every record of a message. diff --git a/postfix/src/global/db_common.c b/postfix/src/global/db_common.c index 92223b056..887ceacd4 100644 --- a/postfix/src/global/db_common.c +++ b/postfix/src/global/db_common.c @@ -228,7 +228,7 @@ int db_common_parse(DICT *dict, void **ctxPtr, const char *format, int query break; default: msg_fatal("db_common_parse: %s: Invalid %s template: %s", - dict->name, query ? "query" : "result", format); + ctx->dict->name, query ? "query" : "result", format); } return dynamic; } diff --git a/postfix/src/global/mail_params.c b/postfix/src/global/mail_params.c index d53931c6e..f5350a1ac 100644 --- a/postfix/src/global/mail_params.c +++ b/postfix/src/global/mail_params.c @@ -510,7 +510,7 @@ void mail_params_init() VAR_SYSLOG_FACILITY, DEF_SYSLOG_FACILITY, &var_syslog_facility, 1, 0, VAR_INET_PROTOCOLS, DEF_INET_PROTOCOLS, &var_inet_protocols, 1, 0, VAR_MULTI_CONF_DIRS, DEF_MULTI_CONF_DIRS, &var_multi_conf_dirs, 0, 0, - VAR_MULTI_WRAPPER, DEF_MULTI_WRAPPER, &var_multi_wrapper, 0, 0, + /* multi_instance_wrapper may have dependencies but not dependents. */ VAR_MULTI_GROUP, DEF_MULTI_GROUP, &var_multi_group, 0, 0, VAR_MULTI_NAME, DEF_MULTI_NAME, &var_multi_name, 0, 0, 0, @@ -567,6 +567,8 @@ void mail_params_init() VAR_PROXYMAP_SERVICE, DEF_PROXYMAP_SERVICE, &var_proxymap_service, 1, 0, VAR_PROXYWRITE_SERVICE, DEF_PROXYWRITE_SERVICE, &var_proxywrite_service, 1, 0, VAR_INT_FILT_CLASSES, DEF_INT_FILT_CLASSES, &var_int_filt_classes, 0, 0, + /* multi_instance_wrapper may have dependencies but not dependents. */ + VAR_MULTI_WRAPPER, DEF_MULTI_WRAPPER, &var_multi_wrapper, 0, 0, 0, }; static const CONFIG_STR_FN_TABLE function_str_defaults_2[] = { diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 04c3f5747..5237f2572 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -2552,7 +2552,7 @@ extern bool var_verify_neg_cache; extern char *var_verify_sender; #define VAR_VERIFY_POLL_COUNT "address_verify_poll_count" -#define DEF_VERIFY_POLL_COUNT 3 +#define DEF_VERIFY_POLL_COUNT "${stress?1}${stress:3}" extern int var_verify_poll_count; #define VAR_VERIFY_POLL_DELAY "address_verify_poll_delay" diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index a38994fed..a19d850aa 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,8 +20,8 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20090828" -#define MAIL_VERSION_NUMBER "2.6.5" +#define MAIL_RELEASE_DATE "20100319" +#define MAIL_VERSION_NUMBER "2.6.6" #ifdef SNAPSHOT # define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE diff --git a/postfix/src/milter/milter8.c b/postfix/src/milter/milter8.c index e839532f6..6fea0f06a 100644 --- a/postfix/src/milter/milter8.c +++ b/postfix/src/milter/milter8.c @@ -2584,6 +2584,13 @@ static int milter8_send(MILTER *m, VSTREAM *stream) if (msg_verbose) msg_info("%s: milter %s", myname, milter->m.name); + /* + * The next read on this Milter socket happens in a different process. It + * will not automatically flush the output buffer in this process. + */ + if (milter->fp) + vstream_fflush(milter->fp); + if (attr_print(stream, ATTR_FLAG_MORE, ATTR_TYPE_STR, MAIL_ATTR_MILT_NAME, milter->m.name, ATTR_TYPE_INT, MAIL_ATTR_MILT_VERS, milter->version, diff --git a/postfix/src/pickup/pickup.c b/postfix/src/pickup/pickup.c index ccf64749e..921c07d91 100644 --- a/postfix/src/pickup/pickup.c +++ b/postfix/src/pickup/pickup.c @@ -191,10 +191,14 @@ static int cleanup_service_error_reason(PICKUP_INFO *info, int status, /* * XXX If the cleanup server gave a reason, then it was already logged. * Don't bother logging it another time. + * + * XXX Discard a message without recipient. This can happen with "postsuper + * -r" when a message is already delivered (or bounced). The Postfix + * sendmail command rejects submissions without recipients. */ if (reason == 0) msg_warn("%s: %s", info->path, cleanup_strerror(status)); - return ((status & CLEANUP_STAT_BAD) ? + return ((status & (CLEANUP_STAT_BAD | CLEANUP_STAT_RCPT)) ? REMOVE_MESSAGE_FILE : KEEP_MESSAGE_FILE); } diff --git a/postfix/src/postmulti/postmulti.c b/postfix/src/postmulti/postmulti.c index 9cfec54a2..d8f12e1a0 100644 --- a/postfix/src/postmulti/postmulti.c +++ b/postfix/src/postmulti/postmulti.c @@ -1528,6 +1528,8 @@ static int iterate_command(int iter_cmd, int iter_flags, char **argv, */ FOREACH_ITERATOR_INSTANCE(iter_flags, entry) { ip = RING_TO_INSTANCE(entry); + if ((iter_flags & ITER_FLAG_SKIP_DISABLED) && !ip->enabled) + continue; if (!match_instance_selection(ip, selection)) continue; matched = 1; diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 33c6b927a..a4a34a03c 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -3205,9 +3205,9 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) smtpd_chat_reply(state, "501 5.1.3 Bad recipient address syntax"); return (-1); } - /* Not: state->addr_buf */ + /* Use state->addr_buf, with the unquoted result from extract_addr() */ if (SMTPD_STAND_ALONE(state) == 0 - && (err = smtpd_check_rcpt(state, argv[1].strval)) != 0) { + && (err = smtpd_check_rcpt(state, STR(state->addr_buf))) != 0) { smtpd_chat_reply(state, "%s", err); return (-1); } @@ -4464,7 +4464,7 @@ static void smtpd_proto(SMTPD_STATE *state) && (err = milter_unknown_event(smtpd_milters, argv[0].strval)) != 0 && (err = check_milter_reply(state, err)) != 0) { - smtpd_chat_reply(state, err); + smtpd_chat_reply(state, "%s", err); } else smtpd_chat_reply(state, "502 5.5.2 Error: command not recognized"); state->error_mask |= MAIL_ERROR_PROTOCOL; @@ -4897,6 +4897,7 @@ int main(int argc, char **argv) VAR_SMTPD_SOFT_ERLIM, DEF_SMTPD_SOFT_ERLIM, &var_smtpd_soft_erlim, 1, 0, VAR_SMTPD_HARD_ERLIM, DEF_SMTPD_HARD_ERLIM, &var_smtpd_hard_erlim, 1, 0, VAR_SMTPD_JUNK_CMD, DEF_SMTPD_JUNK_CMD, &var_smtpd_junk_cmd_limit, 1, 0, + VAR_VERIFY_POLL_COUNT, DEF_VERIFY_POLL_COUNT, &var_verify_poll_count, 1, 0, 0, }; static const CONFIG_INT_TABLE int_table[] = { @@ -4925,7 +4926,6 @@ int main(int argc, char **argv) VAR_VIRT_MAILBOX_CODE, DEF_VIRT_MAILBOX_CODE, &var_virt_mailbox_code, 0, 0, VAR_RELAY_RCPT_CODE, DEF_RELAY_RCPT_CODE, &var_relay_rcpt_code, 0, 0, VAR_PLAINTEXT_CODE, DEF_PLAINTEXT_CODE, &var_plaintext_code, 0, 0, - VAR_VERIFY_POLL_COUNT, DEF_VERIFY_POLL_COUNT, &var_verify_poll_count, 1, 0, VAR_SMTPD_CRATE_LIMIT, DEF_SMTPD_CRATE_LIMIT, &var_smtpd_crate_limit, 0, 0, VAR_SMTPD_CCONN_LIMIT, DEF_SMTPD_CCONN_LIMIT, &var_smtpd_cconn_limit, 0, 0, VAR_SMTPD_CMAIL_LIMIT, DEF_SMTPD_CMAIL_LIMIT, &var_smtpd_cmail_limit, 0, 0, diff --git a/postfix/src/trivial-rewrite/resolve.c b/postfix/src/trivial-rewrite/resolve.c index 454cd5ae5..a391daf32 100644 --- a/postfix/src/trivial-rewrite/resolve.c +++ b/postfix/src/trivial-rewrite/resolve.c @@ -153,6 +153,7 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr, char *oper; char *junk; const char *relay; + const char *sender_key; *flags = 0; vstring_strcpy(channel, "CHANNEL NOT UPDATED"); @@ -508,12 +509,22 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr, * override the recipient domain. */ if (rp->snd_relay_info - && (relay = mail_addr_find(rp->snd_relay_info, *sender ? - sender : var_null_relay_maps_key, - (char **) 0)) != 0) + && (relay = mail_addr_find(rp->snd_relay_info, + sender_key = (*sender ? sender : + var_null_relay_maps_key), + (char **) 0)) != 0) { + if (*relay == 0) { + msg_warn("%s: ignoring null lookup result for %s", + rp->snd_relay_maps_name, sender_key); + relay = "DUNNO"; + } vstring_strcpy(nexthop, strcasecmp(relay, "DUNNO") == 0 ? rcpt_domain : relay); - else if (*RES_PARAM_VALUE(rp->relayhost)) + } else if (dict_errno != 0) { + msg_warn("%s lookup failure", rp->snd_relay_maps_name); + *flags |= RESOLVE_FLAG_FAIL; + FREE_MEMORY_AND_RETURN; + } else if (*RES_PARAM_VALUE(rp->relayhost)) vstring_strcpy(nexthop, RES_PARAM_VALUE(rp->relayhost)); else vstring_strcpy(nexthop, rcpt_domain); diff --git a/postfix/src/util/sys_defs.h b/postfix/src/util/sys_defs.h index 0119d5274..ff2552b82 100644 --- a/postfix/src/util/sys_defs.h +++ b/postfix/src/util/sys_defs.h @@ -25,6 +25,7 @@ */ #if defined(FREEBSD2) || defined(FREEBSD3) || defined(FREEBSD4) \ || defined(FREEBSD5) || defined(FREEBSD6) || defined(FREEBSD7) \ + || defined(FREEBSD8) \ || defined(BSDI2) || defined(BSDI3) || defined(BSDI4) \ || defined(OPENBSD2) || defined(OPENBSD3) || defined(OPENBSD4) \ || defined(NETBSD1) || defined(NETBSD2) || defined(NETBSD3) \ @@ -110,6 +111,10 @@ #define HAS_DUPLEX_PIPE /* 4.1 breaks with kqueue(2) */ #endif +#if __FreeBSD_version >= 800098 /* commit: r194262 */ +#define HAS_CLOSEFROM +#endif + /* OpenBSD version is year+month */ #if OpenBSD >= 199805 /* XXX */ @@ -1471,7 +1476,7 @@ typedef int pid_t; * sections above. */ #ifndef PRINTFLIKE -#if (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) || __GNUC__ == 3 +#if (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) || __GNUC__ >= 3 #define PRINTFLIKE(x,y) __attribute__ ((format (printf, (x), (y)))) #else #define PRINTFLIKE(x,y) @@ -1479,7 +1484,7 @@ typedef int pid_t; #endif #ifndef SCANFLIKE -#if (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) || __GNUC__ == 3 +#if (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) || __GNUC__ >= 3 #define SCANFLIKE(x,y) __attribute__ ((format (scanf, (x), (y)))) #else #define SCANFLIKE(x,y) diff --git a/postfix/src/util/valid_hostname.c b/postfix/src/util/valid_hostname.c index 66ebdef5c..1beeb9af4 100644 --- a/postfix/src/util/valid_hostname.c +++ b/postfix/src/util/valid_hostname.c @@ -116,6 +116,7 @@ int valid_hostname(const char *name, int gripe) } label_length = 0; } else if (ch == '-') { + non_numeric = 1; label_length++; if (label_length == 1 || cp[1] == 0 || cp[1] == '.') { if (gripe)