From: Wietse Venema
Date: Fri, 20 Jul 2007 05:00:00 +0000 (-0500)
Subject: postfix-2.4.4-RC4
X-Git-Tag: v2.4.4-RC4^0
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=940147e72cd8ac3dc507edd6d3df2818588faf09;p=thirdparty%2Fpostfix.git
postfix-2.4.4-RC4
---
diff --git a/postfix/HISTORY b/postfix/HISTORY
index 5cd65d01b..38de68661 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -13509,3 +13509,11 @@ Apologies for any names omitted.
Portability: /dev/poll support for Solaris chroot jail setup
scripts. Files: examples/chroot-setup/Solaris8,
examples/chroot-setup/Solaris10.
+
+20070719
+
+ Cleanup: streamlined Milter client error handling, so that
+ the (Postfix SMTP server's Milter client) does not get out
+ of sync with Milter applications after the (cleanup server's
+ Milter client) encounters some non-recoverable problem.
+ Files: milter/milter8.c, smtpd/smtpd.c.
diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES
index ecbe12960..cf371e567 100644
--- a/postfix/RELEASE_NOTES
+++ b/postfix/RELEASE_NOTES
@@ -14,12 +14,13 @@ specifies the release date of a stable release or snapshot release.
Incompatibility with Postfix 2.4.4
==================================
-By default, the Cyrus SASL client no longer sends an authoriZation
-ID (authzid); it sends only the authentiCation ID (authcid) plus
-the authcid's password. Specify "send_cyrus_sasl_authzid = yes" to
-get the old behavior, which is to send the (authzid, authcid,
-password), with the authzid equal to the authcid. This workaround
-for non-Cyrus SASL servers is back-ported from Postfix 2.5.
+By default, the Postfix Cyrus SASL client no longer sends a SASL
+authoriZation ID (authzid); it sends only the SASL authentiCation
+ID (authcid) plus the authcid's password. Specify "send_cyrus_sasl_authzid
+= yes" to get the old behavior, which is to send the (authzid,
+authcid, password), with the authzid equal to the authcid. This
+workaround for non-Cyrus SASL servers is back-ported from Postfix
+2.5.
Release notes for Postfix 2.4.0
===============================
diff --git a/postfix/html/lmtp.8.html b/postfix/html/lmtp.8.html
index c00a1ea8d..d9a7767de 100644
--- a/postfix/html/lmtp.8.html
+++ b/postfix/html/lmtp.8.html
@@ -256,10 +256,10 @@ SMTP(8) SMTP(8)
Available in Postfix version 2.4.4 and later:
send_cyrus_sasl_authzid (no)
- When authenticating to a SASL server with the
- default setting "no", send no authoriZation ID
- (authzid); send only the authentiCation ID (auth-
- cid) plus the authcid's password.
+ When authenticating to a remote SMTP or LMTP server
+ with the default setting "no", send no SASL autho-
+ riZation ID (authzid); send only the SASL authenti-
+ Cation ID (authcid) plus the authcid's password.
MIME PROCESSING CONTROLS
Available in Postfix version 2.0 and later:
diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html
index c799d1f4a..a19b6b341 100644
--- a/postfix/html/postconf.5.html
+++ b/postfix/html/postconf.5.html
@@ -6691,14 +6691,15 @@ The name of the directory with example Postfix configuration files.
send_cyrus_sasl_authzid
(default: no)
- When authenticating to a SASL server with the default setting
-"no", send no authoriZation ID (authzid); send only the authentiCation
-ID (authcid) plus the authcid's password.
+ When authenticating to a remote SMTP or LMTP server with the
+default setting "no", send no SASL authoriZation ID (authzid); send
+only the SASL authentiCation ID (authcid) plus the authcid's password.
+
The non-default setting "yes" enables the behavior of older
-Postfix versions. These always send an authzid that is equal to
-the authcid, but this causes inter-operability problems with some
-SMTP servers.
+Postfix versions. These always send a SASL authzid that is equal
+to the SASL authcid, but this causes inter-operability problems
+with some SMTP servers.
This feature is available in Postfix 2.4.4 and later.
diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html
index c00a1ea8d..d9a7767de 100644
--- a/postfix/html/smtp.8.html
+++ b/postfix/html/smtp.8.html
@@ -256,10 +256,10 @@ SMTP(8) SMTP(8)
Available in Postfix version 2.4.4 and later:
send_cyrus_sasl_authzid (no)
- When authenticating to a SASL server with the
- default setting "no", send no authoriZation ID
- (authzid); send only the authentiCation ID (auth-
- cid) plus the authcid's password.
+ When authenticating to a remote SMTP or LMTP server
+ with the default setting "no", send no SASL autho-
+ riZation ID (authzid); send only the SASL authenti-
+ Cation ID (authcid) plus the authcid's password.
MIME PROCESSING CONTROLS
Available in Postfix version 2.0 and later:
diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5
index 3603d302e..7af763b32 100644
--- a/postfix/man/man5/postconf.5
+++ b/postfix/man/man5/postconf.5
@@ -3712,14 +3712,14 @@ This feature is available in Postfix 2.0 and later.
.SH sample_directory (default: /etc/postfix)
The name of the directory with example Postfix configuration files.
.SH send_cyrus_sasl_authzid (default: no)
-When authenticating to a SASL server with the default setting
-"no", send no authoriZation ID (authzid); send only the authentiCation
-ID (authcid) plus the authcid's password.
+When authenticating to a remote SMTP or LMTP server with the
+default setting "no", send no SASL authoriZation ID (authzid); send
+only the SASL authentiCation ID (authcid) plus the authcid's password.
.PP
The non-default setting "yes" enables the behavior of older
-Postfix versions. These always send an authzid that is equal to
-the authcid, but this causes inter-operability problems with some
-SMTP servers.
+Postfix versions. These always send a SASL authzid that is equal
+to the SASL authcid, but this causes inter-operability problems
+with some SMTP servers.
.PP
This feature is available in Postfix 2.4.4 and later.
.SH sender_based_routing (default: no)
diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8
index c882a0930..61e91dc7d 100644
--- a/postfix/man/man8/smtp.8
+++ b/postfix/man/man8/smtp.8
@@ -229,9 +229,9 @@ from a remote LMTP server.
.PP
Available in Postfix version 2.4.4 and later:
.IP "\fBsend_cyrus_sasl_authzid (no)\fR"
-When authenticating to a SASL server with the default setting
-"no", send no authoriZation ID (authzid); send only the authentiCation
-ID (authcid) plus the authcid's password.
+When authenticating to a remote SMTP or LMTP server with the
+default setting "no", send no SASL authoriZation ID (authzid); send
+only the SASL authentiCation ID (authcid) plus the authcid's password.
.SH "MIME PROCESSING CONTROLS"
.na
.nf
diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto
index c592b9a03..f5a90edfb 100644
--- a/postfix/proto/postconf.proto
+++ b/postfix/proto/postconf.proto
@@ -10575,13 +10575,14 @@ configuration parameter. See there for details.
%PARAM send_cyrus_sasl_authzid no
- When authenticating to a SASL server with the default setting
-"no", send no authoriZation ID (authzid); send only the authentiCation
-ID (authcid) plus the authcid's password.
+ When authenticating to a remote SMTP or LMTP server with the
+default setting "no", send no SASL authoriZation ID (authzid); send
+only the SASL authentiCation ID (authcid) plus the authcid's password.
+
The non-default setting "yes" enables the behavior of older
-Postfix versions. These always send an authzid that is equal to
-the authcid, but this causes inter-operability problems with some
-SMTP servers.
+Postfix versions. These always send a SASL authzid that is equal
+to the SASL authcid, but this causes inter-operability problems
+with some SMTP servers.
This feature is available in Postfix 2.4.4 and later.
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index a1bca38e8..d260a5ce2 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 "20070711"
-#define MAIL_VERSION_NUMBER "2.4.4-RC3"
+#define MAIL_RELEASE_DATE "20070720"
+#define MAIL_VERSION_NUMBER "2.4.4-RC4"
#ifdef SNAPSHOT
# define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
diff --git a/postfix/src/milter/milter8.c b/postfix/src/milter/milter8.c
index a3b2e364e..2753d7c4b 100644
--- a/postfix/src/milter/milter8.c
+++ b/postfix/src/milter/milter8.c
@@ -64,6 +64,10 @@
#include
#include
+#ifndef SHUT_RDWR
+#define SHUT_RDWR 2
+#endif
+
/* Sendmail 8 Milter protocol. */
#ifdef USE_LIBMILTER_INCLUDES
@@ -437,7 +441,22 @@ static int milter8_conf_error(MILTER8 *milter)
{
const char *reply;
+ /*
+ * While reading the following, keep in mind that a client-side Milter
+ * socket is shared between the Postfix SMTP server and the cleanup
+ * server. The SMTP server reports only the SMTP events to the Milter.
+ * The cleanup server reports the headers and body to the Milter, and
+ * receives the header or body modification requests from the Milter.
+ *
+ * XXX When the cleanup server closes its end of the Milter socket after
+ * some local/remote configuration error, the SMTP server is left out of
+ * sync with the Milter. Sending an ABORT to the Milters will not restore
+ * synchronization, because there may be any number of Milter replies
+ * already in flight. Workaround: poison the socket and force the SMTP
+ * server to abandon it.
+ */
if (milter->fp != 0) {
+ (void) shutdown(vstream_fileno(milter->fp), SHUT_RDWR);
(void) vstream_fclose(milter->fp);
milter->fp = 0;
}
@@ -456,7 +475,22 @@ static int milter8_comm_error(MILTER8 *milter)
{
const char *reply;
+ /*
+ * While reading the following, keep in mind that a client-side Milter
+ * socket is shared between the Postfix SMTP server and the cleanup
+ * server. The SMTP server reports only the SMTP events to the Milter.
+ * The cleanup server reports the headers and body to the Milter, and
+ * receives the header or body modification requests from the Milter.
+ *
+ * XXX When the cleanup server closes its end of the Milter socket after
+ * some local or remote remote protocol error, the SMTP server is left
+ * out of sync with the Milter. Sending an ABORT to the Milters will not
+ * restore synchronization, because there may be any number of Milter
+ * replies already in flight. Workaround: poison the socket and force the
+ * SMTP server to abandon it.
+ */
if (milter->fp != 0) {
+ (void) shutdown(vstream_fileno(milter->fp), SHUT_RDWR);
(void) vstream_fclose(milter->fp);
milter->fp = 0;
}
@@ -475,28 +509,6 @@ static int milter8_comm_error(MILTER8 *milter)
return (milter->state = MILTER8_STAT_ERROR);
}
-/* milter8_edit_error - local queue file update error */
-
-static void milter8_edit_error(MILTER8 *milter, const char *reply)
-{
-
- /*
- * Close the socket, so we don't have to skip pending replies from this
- * Milter instance.
- */
- if (milter->fp != 0) {
- (void) vstream_fclose(milter->fp);
- milter->fp = 0;
- }
-
- /*
- * Set the socket state to ERROR, so we don't try to send further MTA
- * events to this Milter instance.
- */
- milter8_def_reply(milter, reply);
- milter->state = MILTER8_STAT_ERROR;
-}
-
/* milter8_close_stream - close stream to milter application */
static void milter8_close_stream(MILTER8 *milter)
@@ -895,6 +907,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
const char *retval = 0;
VSTRING *body_line_buf = 0;
int done = 0;
+ int body_edit_lockout = 0;
#define DONT_SKIP_REPLY 0
@@ -1000,6 +1013,22 @@ static const char *milter8_event(MILTER8 *milter, int event,
* processing.
*
* XXX Bound the loop iteration count.
+ *
+ * While reading the following, keep in mind that a client-side Milter
+ * socket is shared between the Postfix SMTP server and the cleanup
+ * server. The SMTP server reports only the SMTP events to the Milter.
+ * The cleanup server reports the headers and body to the Milter, and
+ * receives the header or body modification requests from the Milter.
+ *
+ * In the end-of-body stage, the Milter may reply with one or more queue
+ * file edit requests before it replies with its final decision: accept,
+ * reject, etc. After a local queue file edit error, do not close the
+ * Milter socket in the cleanup server. Instead skip all further Milter
+ * replies until the final decision. This way the Postfix SMTP server
+ * stays in sync with the Milter, and Postfix doesn't have to lose the
+ * ability to handle multiple deliveries within the same SMTP session.
+ * This requires that the Postfix SMTP server uses something other than
+ * CLEANUP_STAT_WRITE when it loses contact with the cleanup server.
*/
#define IN_CONNECT_EVENT(e) ((e) == SMFIC_CONNECT || (e) == SMFIC_HELO)
@@ -1027,10 +1056,18 @@ static const char *milter8_event(MILTER8 *milter, int event,
/*
* Handle unfinished message body replacement first.
+ *
+ * XXX When SMFIR_REPLBODY is followed by some different request, we
+ * assume that the body replacement operation is complete. The queue
+ * file editing implementation currently does not support sending
+ * part 1 of the body replacement text, doing some other queue file
+ * updates, and then sending part 2 of the body replacement text. To
+ * avoid loss of data, we log an error when SMFIR_REPLBODY requests
+ * are alternated with other requests.
*/
if (body_line_buf != 0 && cmd != SMFIR_REPLBODY) {
/* In case the last body replacement line didn't end in CRLF. */
- if (LEN(body_line_buf) > 0)
+ if (edit_resp == 0 && LEN(body_line_buf) > 0)
edit_resp = parent->repl_body(parent->chg_context,
MILTER_BODY_LINE,
body_line_buf);
@@ -1038,10 +1075,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
edit_resp = parent->repl_body(parent->chg_context,
MILTER_BODY_END,
(VSTRING *) 0);
- if (edit_resp) {
- milter8_edit_error(milter, edit_resp);
- MILTER8_EVENT_BREAK(milter->def_reply);
- }
+ body_edit_lockout = 1;
vstring_free(body_line_buf);
body_line_buf = 0;
}
@@ -1095,7 +1129,6 @@ static const char *milter8_event(MILTER8 *milter, int event,
if (IN_CONNECT_EVENT(event)) {
msg_warn("milter %s: DISCARD action is not allowed "
"for connect or helo", milter->m.name);
- milter8_conf_error(milter);
MILTER8_EVENT_BREAK(milter->def_reply);
} else {
/* No more events for this message. */
@@ -1231,6 +1264,9 @@ static const char *milter8_event(MILTER8 *milter, int event,
MILTER8_DATA_STRING, milter->body,
MILTER8_DATA_END) != 0)
MILTER8_EVENT_BREAK(milter->def_reply);
+ /* Skip to the next request after previous edit error. */
+ if (edit_resp)
+ continue;
/* XXX Sendmail 8 compatibility. */
if (index == 0)
index = 1;
@@ -1255,10 +1291,6 @@ static const char *milter8_event(MILTER8 *milter, int event,
edit_resp = parent->del_header(parent->chg_context,
(ssize_t) index,
STR(milter->buf));
- if (edit_resp) {
- milter8_edit_error(milter, edit_resp);
- MILTER8_EVENT_BREAK(milter->def_reply);
- }
continue;
#endif
@@ -1271,13 +1303,12 @@ static const char *milter8_event(MILTER8 *milter, int event,
MILTER8_DATA_STRING, milter->body,
MILTER8_DATA_END) != 0)
MILTER8_EVENT_BREAK(milter->def_reply);
+ /* Skip to the next request after previous edit error. */
+ if (edit_resp)
+ continue;
edit_resp = parent->add_header(parent->chg_context,
STR(milter->buf),
STR(milter->body));
- if (edit_resp) {
- milter8_edit_error(milter, edit_resp);
- MILTER8_EVENT_BREAK(milter->def_reply);
- }
continue;
/*
@@ -1294,6 +1325,9 @@ static const char *milter8_event(MILTER8 *milter, int event,
MILTER8_DATA_STRING, milter->body,
MILTER8_DATA_END) != 0)
MILTER8_EVENT_BREAK(milter->def_reply);
+ /* Skip to the next request after previous edit error. */
+ if (edit_resp)
+ continue;
if ((ssize_t) index + 1 < 1) {
msg_warn("milter %s: bad insert header index: %ld",
milter->m.name, (long) index);
@@ -1304,10 +1338,6 @@ static const char *milter8_event(MILTER8 *milter, int event,
(ssize_t) index + 1,
STR(milter->buf),
STR(milter->body));
- if (edit_resp) {
- milter8_edit_error(milter, edit_resp);
- MILTER8_EVENT_BREAK(milter->def_reply);
- }
continue;
#endif
@@ -1319,12 +1349,11 @@ static const char *milter8_event(MILTER8 *milter, int event,
MILTER8_DATA_STRING, milter->buf,
MILTER8_DATA_END) != 0)
MILTER8_EVENT_BREAK(milter->def_reply);
+ /* Skip to the next request after previous edit error. */
+ if (edit_resp)
+ continue;
edit_resp = parent->add_rcpt(parent->chg_context,
STR(milter->buf));
- if (edit_resp) {
- milter8_edit_error(milter, edit_resp);
- MILTER8_EVENT_BREAK(milter->def_reply);
- }
continue;
/*
@@ -1335,12 +1364,11 @@ static const char *milter8_event(MILTER8 *milter, int event,
MILTER8_DATA_STRING, milter->buf,
MILTER8_DATA_END) != 0)
MILTER8_EVENT_BREAK(milter->def_reply);
+ /* Skip to the next request after previous edit error. */
+ if (edit_resp)
+ continue;
edit_resp = parent->del_rcpt(parent->chg_context,
STR(milter->buf));
- if (edit_resp) {
- milter8_edit_error(milter, edit_resp);
- MILTER8_EVENT_BREAK(milter->def_reply);
- }
continue;
/*
@@ -1348,10 +1376,20 @@ static const char *milter8_event(MILTER8 *milter, int event,
* update the message size.
*/
case SMFIR_REPLBODY:
+ if (body_edit_lockout) {
+ msg_warn("milter %s: body replacement requests can't "
+ "currently be mixed with other requests",
+ milter->m.name);
+ milter8_conf_error(milter);
+ MILTER8_EVENT_BREAK(milter->def_reply);
+ }
if (milter8_read_data(milter, data_size,
MILTER8_DATA_BUFFER, milter->body,
MILTER8_DATA_END) != 0)
MILTER8_EVENT_BREAK(milter->def_reply);
+ /* Skip to the next request after previous edit error. */
+ if (edit_resp)
+ continue;
/* Start body replacement. */
if (body_line_buf == 0) {
body_line_buf = vstring_alloc(var_line_limit);
@@ -1376,10 +1414,6 @@ static const char *milter8_event(MILTER8 *milter, int event,
VSTRING_ADDCH(body_line_buf, ch);
}
}
- if (edit_resp) {
- milter8_edit_error(milter, edit_resp);
- MILTER8_EVENT_BREAK(milter->def_reply);
- }
continue;
}
}
@@ -1410,6 +1444,15 @@ static const char *milter8_event(MILTER8 *milter, int event,
if (body_line_buf)
vstring_free(body_line_buf);
+ /*
+ * XXX Some cleanup clients ask the cleanup server to bounce mail for
+ * them. In that case we must override a hard reject retval result after
+ * queue file update failure. This is not a big problem; the odds are
+ * small that a Milter application sends a hard reject after replacing
+ * the message body.
+ */
+ if (edit_resp && (retval == 0 || strchr("DS4", retval[0]) == 0))
+ retval = edit_resp;
return (retval);
}
diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c
index 40ffcade5..0c226697e 100644
--- a/postfix/src/smtp/smtp.c
+++ b/postfix/src/smtp/smtp.c
@@ -207,9 +207,9 @@
/* .PP
/* Available in Postfix version 2.4.4 and later:
/* .IP "\fBsend_cyrus_sasl_authzid (no)\fR"
-/* When authenticating to a SASL server with the default setting
-/* "no", send no authoriZation ID (authzid); send only the authentiCation
-/* ID (authcid) plus the authcid's password.
+/* When authenticating to a remote SMTP or LMTP server with the
+/* default setting "no", send no SASL authoriZation ID (authzid); send
+/* only the SASL authentiCation ID (authcid) plus the authcid's password.
/* MIME PROCESSING CONTROLS
/* .ad
/* .fi
diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c
index 601a1f538..a0fa7e9cf 100644
--- a/postfix/src/smtpd/smtpd.c
+++ b/postfix/src/smtpd/smtpd.c
@@ -2736,6 +2736,24 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
state->cleanup = 0;
}
+ /*
+ * XXX If we lost the cleanup server, the Postfix SMTP server will be out
+ * of sync with Milter applications. Sending an ABORT to the Milters is
+ * not sufficient to restore synchronization, because there may be any
+ * number of Milter replies already in flight. Destroying and recreating
+ * the Milters (and faking the connect and ehlo events) is too much
+ * trouble for testing and maintenance. Workaround: force the Postfix
+ * SMTP server to hang up with a 421 response in the rare case that the
+ * cleanup server breaks AND that the remote SMTP client continues the
+ * session after end-of-data.
+ *
+ * XXX Should use something other than CLEANUP_STAT_WRITE when we lose
+ * contact with the cleanup server. This requires changes to among others
+ * the mail_stream module.
+ */
+ if (smtpd_milters != 0 && (state->err & CLEANUP_STAT_WRITE) != 0)
+ state->access_denied = mystrdup("421 4.3.0 Mail system error");
+
/*
* Handle any errors. One message may suffer from multiple errors, so
* complain only about the most severe error. Forgive any previous client