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
+ %
-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)