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
+ %<letter> 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.
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.
# 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.
text. <b>4</b><i>NN</i> means "try again later", while <b>5</b><i>NN</i> 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:
+
+ <b>421</b> <i>text</i> (Postfix 2.3 and later)
+
+ <b>521</b> <i>text</i> (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.
<b>REJECT</b> <i>optional text...</i>
Reject the address etc. that matches the pattern.
of an address verification request in progress.
</p>
-<p>
-The default poll count is 3.
-</p>
+<p> By default, the Postfix SMTP server polls the <a href="verify.8.html">verify(8)</a> 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 <a href="verify.8.html">verify(8)</a> service up to three times by
+default. </p>
<p>
Specify 1 to implement a crude form of greylisting, that is, always
;;
FreeBSD.7*) SYSTYPE=FREEBSD7
;;
+ FreeBSD.8*) SYSTYPE=FREEBSD8
+ ;;
OpenBSD.2*) SYSTYPE=OPENBSD2
;;
OpenBSD.3*) SYSTYPE=OPENBSD3
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
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.
# 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
of an address verification request in progress.
</p>
-<p>
-The default poll count is 3.
-</p>
+<p> 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. </p>
<p>
Specify 1 to implement a crude form of greylisting, that is, always
* 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.
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;
}
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,
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[] = {
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"
* 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
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,
/*
* 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);
}
*/
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;
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);
}
&& (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;
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[] = {
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,
char *oper;
char *junk;
const char *relay;
+ const char *sender_key;
*flags = 0;
vstring_strcpy(channel, "CHANNEL NOT UPDATED");
* 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);
*/
#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) \
#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 */
* 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)
#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)
}
label_length = 0;
} else if (ch == '-') {
+ non_numeric = 1;
label_length++;
if (label_length == 1 || cp[1] == 0 || cp[1] == '.') {
if (gripe)