]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.4.4-RC4 v2.4.4-RC4
authorWietse Venema <wietse@porcupine.org>
Fri, 20 Jul 2007 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Sat, 10 Feb 2018 20:18:15 +0000 (15:18 -0500)
12 files changed:
postfix/HISTORY
postfix/RELEASE_NOTES
postfix/html/lmtp.8.html
postfix/html/postconf.5.html
postfix/html/smtp.8.html
postfix/man/man5/postconf.5
postfix/man/man8/smtp.8
postfix/proto/postconf.proto
postfix/src/global/mail_version.h
postfix/src/milter/milter8.c
postfix/src/smtp/smtp.c
postfix/src/smtpd/smtpd.c

index 5cd65d01b556800ab0c3bcbc503e3529df1fb5a3..38de6866191a8349c15c8ec5acf8e0cb209864ce 100644 (file)
@@ -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.
index ecbe129603da00942af2937fb1d0c339b3dee937..cf371e5676b092a0d7a7a7fdef6f1d03467db10d 100644 (file)
@@ -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
 ===============================
index c00a1ea8df287814f8cc2e853f1db413da899b18..d9a7767de611e6dc062aef315e09a2cde7b2f551 100644 (file)
@@ -256,10 +256,10 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.4.4 and later:
 
        <b><a href="postconf.5.html#send_cyrus_sasl_authzid">send_cyrus_sasl_authzid</a> (no)</b>
-              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.
 
 <b>MIME PROCESSING CONTROLS</b>
        Available in Postfix version 2.0 and later:
index c799d1f4a262705065185440f7a4342414ae7156..a19b6b341eec5b5fb112c0728c2d54248882a425 100644 (file)
@@ -6691,14 +6691,15 @@ The name of the directory with example Postfix configuration files.
 <DT><b><a name="send_cyrus_sasl_authzid">send_cyrus_sasl_authzid</a>
 (default: no)</b></DT><DD>
 
-<p> 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. </p>
+<p> 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.
+</p>
 
 <p> 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. </p>
+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. </p>
 
 <p> This feature is available in Postfix 2.4.4 and later. </p>
 
index c00a1ea8df287814f8cc2e853f1db413da899b18..d9a7767de611e6dc062aef315e09a2cde7b2f551 100644 (file)
@@ -256,10 +256,10 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.4.4 and later:
 
        <b><a href="postconf.5.html#send_cyrus_sasl_authzid">send_cyrus_sasl_authzid</a> (no)</b>
-              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.
 
 <b>MIME PROCESSING CONTROLS</b>
        Available in Postfix version 2.0 and later:
index 3603d302e32392c162e47b156330749a57d82d8a..7af763b32893adf717bbaf2a93b45549ec385df1 100644 (file)
@@ -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)
index c882a0930edf21cb2c639c9084d07603b5e30915..61e91dc7dd8cee74770dac5d6b5789d5e666b439 100644 (file)
@@ -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
index c592b9a03ffee5c2b9aeb9fa2a7ef3c58b4361e5..f5a90edfb62f1f87dec24a0a8f45727772c3161e 100644 (file)
@@ -10575,13 +10575,14 @@ configuration parameter.  See there for details. </p>
 
 %PARAM send_cyrus_sasl_authzid no
 
-<p> 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. </p>
+<p> 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.
+</p>
 
 <p> 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. </p>
+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. </p>
 
 <p> This feature is available in Postfix 2.4.4 and later. </p>
index a1bca38e8a80fbfaaf91ba167a51ef3680a992ec..d260a5ce2a4323e61c29878ef5fb5cc2319b7c7b 100644 (file)
@@ -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
index a3b2e364e3d54364aed07ddce5eda7d6db593c7f..2753d7c4b9443bab8681602ce3818de9e4bd29f3 100644 (file)
 #include <string.h>
 #include <stdarg.h>
 
+#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);
 }
 
index 40ffcade5396a6868d1113e9ed91cfed2bc07d73..0c226697e1aeae4161bfdf1c0a80e099c34f8267 100644 (file)
 /* .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
index 601a1f53887f1c13af026783d26b6cbfcc098f77..a0fa7e9cf7c546cfcc46c571309cdf24b9bd770f 100644 (file)
@@ -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