]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.3.5-RC1 v2.3.5-RC1
authorWietse Venema <wietse@porcupine.org>
Tue, 5 Dec 2006 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Sat, 10 Feb 2018 20:52:47 +0000 (15:52 -0500)
22 files changed:
postfix/AAAREADME
postfix/HISTORY
postfix/README_FILES/ADDRESS_REWRITING_README
postfix/conf/post-install
postfix/html/ADDRESS_REWRITING_README.html
postfix/proto/ADDRESS_REWRITING_README.html
postfix/src/cleanup/cleanup_message.c
postfix/src/cleanup/cleanup_milter.c
postfix/src/cleanup/cleanup_out.c
postfix/src/global/dict_proxy.c
postfix/src/global/mail_version.h
postfix/src/global/resolve_clnt.c
postfix/src/global/rewrite_clnt.c
postfix/src/global/scache_clnt.c
postfix/src/global/verify_clnt.c
postfix/src/milter/milter8.c
postfix/src/oqmgr/qmgr_entry.c
postfix/src/qmgr/qmgr_job.c
postfix/src/qmgr/qmgr_message.c
postfix/src/smtp/smtp_chat.c
postfix/src/smtp/smtp_connect.c
postfix/src/smtp/smtp_proto.c

index d68a0f16d181c9528cc566b6b8aabf034c304a27..e78b4d8e17f125edc43b58d2d384c8b59ba5d026 100644 (file)
@@ -135,7 +135,6 @@ Postfix daemons:
     src/cleanup/       Canonicalize and enqueue mail
     src/discard/       Trivial discard mailer
     src/error/         Trivial error mailer
-    src/lmtp/          LMTP client
     src/local/         Local delivery
     src/master/                Postfix resident superserver
     src/oqmgr/         Old queue manager
@@ -144,9 +143,10 @@ Postfix daemons:
     src/qmgr/          Queue manager
     src/qmqpd/         QMQPD server
     src/showq/         List Postfix queue status
-    src/smtp/          SMTP client
+    src/smtp/          SMTP and LMTP client
     src/smtpd/         SMTP server
     src/spawn/         Run non-Postfix server
+    src/tlsmgr/                TLS session keys and random pool
     src/trivial-rewrite/ Address rewriting and resolving
     src/verify/                address verification service
     src/virtual/       virtual mailbox-only delivery agent
index b26603692711339d586325e2c022cae542a90d5a..ba6c0b9912a53fcae10c1109d9eb3af888b31f33 100644 (file)
@@ -12769,3 +12769,61 @@ Apologies for any names omitted.
        Bugfix: null pointer bug when receiving a non-protocol
        response on a cached SMTP/LMTP connection.  Report by Brian
        Kantor.  Fix by Victor Duchovni.  File: smtp/smtp_reuse.c.
+
+20061113
+
+       Bugfix: the Postfix install/upgrade procedure broke with
+       non-default config_directory. File: conf/post-install.
+
+20061115
+
+       Bugfix: null pointer bug in end-of-header Milter action
+       when the last header line is too large.  Reported by Mark
+       Martinec. The root of the problem is that the MIME state
+       engine may execute up to three call-back functions when it
+       reaches the end of the headers, before it returns to the
+       caller; as long as call-backs return no result, each call-back
+       has to check for itself if a previous call-back ran into a
+       problem.  File: milter/milter8.c.
+
+       Workaround: reduce effective header_size_limit to 60000
+       when Milter inspection is enabled, to avoid breaking the
+       Milter protocol request length limit. File:
+       cleanup/cleanup_message.c.
+
+20061123
+
+       Workaround: more agressive early refill of in-memory
+       recipients to prevent a worst-case scenario where the queue
+       manager became starved until after the last batch of slow
+       in-memory recipients of jumbo multi-recipient mail. Files:
+       qmgr/qmgr_job.c.
+
+       Safety: don't read more than 5000 recipients at a time, to
+       avoid spending too much time away from interrupts.  File:
+       qmgr/qmgr_message.c.
+
+20061201
+
+       Workaround: don't complain with "Error 0" in the trivial-rewrite,
+       verify, proxymap or connection cache client when the server
+       exits after the client sends its request. We still complain,
+       however, when the problem persists.  Files: global/rewrite_clnt.c,
+       global/resolve_clnt.c, global/verify_clnt.c, global/scache_clnt.c,
+       global/dict_proxy.c.
+
+
+       Safety: the header_size_limit is now enforced more strictly,
+       to avoid inter-operability problems with the Milter protocol.
+       Long headers are truncated at a line boundary if possible,
+       otherwise they are cut between line boundaries. File:
+       cleanup/cleanup_out.c.
+
+20061203
+
+       Bugfix (introduced with Postfix 2.2): with SMTP server
+       tarpit delays of smtp_rset_timeout or larger, the SMTP
+       client could get out of sync with the server while reusing
+       a connection.  The symptoms were "recipient rejected .. in
+       reply to DATA".  Fix by Victor Duchovni and Wietse.  File:
+       smtp/smtp_proto.c.
index 5a701344a87b3b195edbf80a1d176adf25fe77d1..b7e75ad5acd53534f758e1e9b3cb56bcd6cfca76 100644 (file)
@@ -787,14 +787,14 @@ mailbox, or delivery to non-Postfix command.
     Content-Description: Notification
     Content-Type: text/plain
 
-    This is the Postfix program at host spike.porcupine.org.
+    This is the mail system at host spike.porcupine.org.
 
     Enclosed is the mail delivery report that you requested.
 
-                            The Postfix program
+                            The mail system
 
     <postfix-users@postfix.org>: delivery via mail.cloud9.net[168.100.1.4]: 250
-    Ok
+    2.1.5 Ok
 
 The second part of the report is in machine-readable form, and includes the
 following information:
@@ -814,13 +814,13 @@ version 2.3 and later.
     Reporting-MTA: dns; spike.porcupine.org
     X-Postfix-Queue-ID: 84863BC0E5
     X-Postfix-Sender: rfc822; wietse@porcupine.org
-    Arrival-Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT)
+    Arrival-Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
 
     Final-Recipient: rfc822; postfix-users@postfix.org
     Action: deliverable
-    Status: 2.0.0
+    Status: 2.1.5
     Remote-MTA: dns; mail.cloud9.net
-    Diagnostic-Code: smtp; 250 Ok
+    Diagnostic-Code: smtp; 250 2.1.5 Ok
 
 The third part of the report contains the message that Postfix would have
 delivered, including From: and To: message headers, so that you can see any
@@ -831,10 +831,10 @@ no body content so none is shown in the example below.
     Content-Type: message/rfc822
 
     Received: by spike.porcupine.org (Postfix, from userid 1001)
-            id 84863BC0E5; Tue, 13 Apr 2004 19:27:43 -0400 (EDT)
+            id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST)
     Subject: probe
     To: postfix-users@postfix.org
-    Message-Id: <20040413232743.84863BC0E5@spike.porcupine.org>
-    Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT)
+    Message-Id: <20061126220101.84863BC0E5@spike.porcupine.org>
+    Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
     From: wietse@porcupine.org (Wietse Venema)
 
index c64ff19f6164d0a5791d2b0f343098f7942f3c5c..54b3b93bcceb4820c062ed389744328d8f0cf24c 100644 (file)
@@ -589,14 +589,14 @@ EOF
     # This safety net is also documented in LOCAL_RECIPIENT_README.
 
     unknown_local=unknown_local_recipient_reject_code
-    has_lrm=`$POSTCONF -n local_recipient_maps`
-    has_lrjc=`$POSTCONF -n $unknown_local`
+    has_lrm=`$POSTCONF -c $config_directory -n local_recipient_maps`
+    has_lrjc=`$POSTCONF -c $config_directory -n $unknown_local`
 
     if [ -z "$has_lrm" -a -z "$has_lrjc" ]
     then
        echo SAFETY: editing main.cf, setting $unknown_local=450.
        echo See the LOCAL_RECIPIENT_README file for details.
-       $POSTCONF -e "$unknown_local = 450" || exit 1
+       $POSTCONF -c $config_directory -e "$unknown_local = 450" || exit 1
     fi
 
     # Add missing proxymap service to master.cf.
@@ -678,8 +678,8 @@ EOF
 
 test -n "$first_install_reminder" && {
 
-    ALIASES=`$POSTCONF -h alias_database | sed 's/^[^:]*://'`
-    NEWALIASES_PATH=`$POSTCONF -h newaliases_path`
+    ALIASES=`$POSTCONF -c $config_directory -h alias_database | sed 's/^[^:]*://'`
+    NEWALIASES_PATH=`$POSTCONF -c $config_directory -h newaliases_path`
     cat <<EOF | ${FMT}
 
     Warning: you still need to edit myorigin/mydestination/mynetworks
index 4c1c53813ecbc636d52c38782fd33268c5d6c940..f2243516d26d9b8a98115baa9ccb4627c96ec2af 100644 (file)
@@ -1174,13 +1174,13 @@ to mailbox, or delivery to non-Postfix command. </p>
 Content-Description: Notification
 Content-Type: text/plain
 
-This is the Postfix program at host spike.porcupine.org.
+This is the mail system at host spike.porcupine.org.
 
 Enclosed is the mail delivery report that you requested.
 
-                        The Postfix program
+                        The mail system
 
-&lt;postfix-users@postfix.org&gt;: delivery via mail.cloud9.net[168.100.1.4]: 250 Ok
+&lt;postfix-users@postfix.org&gt;: delivery via mail.cloud9.net[168.100.1.4]: 250 2.1.5 Ok
 </pre>
 </blockquote>
 
@@ -1210,13 +1210,13 @@ Content-Type: message/delivery-status
 Reporting-MTA: dns; spike.porcupine.org
 X-Postfix-Queue-ID: 84863BC0E5
 X-Postfix-Sender: rfc822; wietse@porcupine.org
-Arrival-Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT)
+Arrival-Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
 
 Final-Recipient: rfc822; postfix-users@postfix.org
 Action: deliverable
-Status: 2.0.0
+Status: 2.1.5
 Remote-MTA: dns; mail.cloud9.net
-Diagnostic-Code: smtp; 250 Ok
+Diagnostic-Code: smtp; 250 2.1.5 Ok
 </pre>
 </blockquote>
 
@@ -1232,11 +1232,11 @@ Content-Description: Message
 Content-Type: message/rfc822
 
 Received: by spike.porcupine.org (Postfix, from userid 1001)
-        id 84863BC0E5; Tue, 13 Apr 2004 19:27:43 -0400 (EDT)
+        id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST)
 Subject: probe
 To: postfix-users@postfix.org
-Message-Id: &lt;20040413232743.84863BC0E5@spike.porcupine.org&gt;
-Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT)
+Message-Id: &lt;20061126220101.84863BC0E5@spike.porcupine.org&gt;
+Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
 From: wietse@porcupine.org (Wietse Venema)
 </pre>
 </blockquote>
index 76c78e0cb492bfa7b0f4ddbbb9ba9437cd433276..3fef9064348778cf5436b3b6bd5f117aab161049 100644 (file)
@@ -1174,13 +1174,13 @@ to mailbox, or delivery to non-Postfix command. </p>
 Content-Description: Notification
 Content-Type: text/plain
 
-This is the Postfix program at host spike.porcupine.org.
+This is the mail system at host spike.porcupine.org.
 
 Enclosed is the mail delivery report that you requested.
 
-                        The Postfix program
+                        The mail system
 
-&lt;postfix-users@postfix.org&gt;: delivery via mail.cloud9.net[168.100.1.4]: 250 Ok
+&lt;postfix-users@postfix.org&gt;: delivery via mail.cloud9.net[168.100.1.4]: 250 2.1.5 Ok
 </pre>
 </blockquote>
 
@@ -1210,13 +1210,13 @@ Content-Type: message/delivery-status
 Reporting-MTA: dns; spike.porcupine.org
 X-Postfix-Queue-ID: 84863BC0E5
 X-Postfix-Sender: rfc822; wietse@porcupine.org
-Arrival-Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT)
+Arrival-Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
 
 Final-Recipient: rfc822; postfix-users@postfix.org
 Action: deliverable
-Status: 2.0.0
+Status: 2.1.5
 Remote-MTA: dns; mail.cloud9.net
-Diagnostic-Code: smtp; 250 Ok
+Diagnostic-Code: smtp; 250 2.1.5 Ok
 </pre>
 </blockquote>
 
@@ -1232,11 +1232,11 @@ Content-Description: Message
 Content-Type: message/rfc822
 
 Received: by spike.porcupine.org (Postfix, from userid 1001)
-        id 84863BC0E5; Tue, 13 Apr 2004 19:27:43 -0400 (EDT)
+        id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST)
 Subject: probe
 To: postfix-users@postfix.org
-Message-Id: &lt;20040413232743.84863BC0E5@spike.porcupine.org&gt;
-Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT)
+Message-Id: &lt;20061126220101.84863BC0E5@spike.porcupine.org&gt;
+Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
 From: wietse@porcupine.org (Wietse Venema)
 </pre>
 </blockquote>
index 5af24c59c636d8cd45032fdea34ba6b8115e8d73..5e71c8b8963975a81af2d8361101d504e5974d21 100644 (file)
@@ -596,6 +596,16 @@ static void cleanup_header_done_callback(void *context)
     TOK822 *token;
     time_t  tv;
 
+    /*
+     * XXX Workaround: when we reach the end of headers, mime_state_update()
+     * may execute up to three call-backs before returning to the caller:
+     * head_out(), head_end(), and body_out() or body_end(). As long as
+     * call-backs don't return a result, each call-back has to check for
+     * itself if the previous call-back experienced a problem.
+     */
+    if (CLEANUP_OUT_OK(state) == 0)
+       return;
+
     /*
      * Add a missing (Resent-)Message-Id: header. The message ID gives the
      * time in GMT units, plus the local queue ID.
@@ -706,6 +716,16 @@ static void cleanup_body_callback(void *context, int type,
 {
     CLEANUP_STATE *state = (CLEANUP_STATE *) context;
 
+    /*
+     * XXX Workaround: when we reach the end of headers, mime_state_update()
+     * may execute up to three call-backs before returning to the caller:
+     * head_out(), head_end(), and body_out() or body_end(). As long as
+     * call-backs don't return a result, each call-back has to check for
+     * itself if the previous call-back experienced a problem.
+     */
+    if (CLEANUP_OUT_OK(state) == 0)
+       return;
+
     /*
      * Crude message body content filter for emergencies. This code has
      * several problems: it sees one line at a time; it looks at long lines
@@ -892,6 +912,15 @@ void    cleanup_message(CLEANUP_STATE *state, int type, const char *buf, ssize_t
                                         cleanup_mime_error_callback,
                                         (void *) state);
 
+    /*
+     * XXX Workaround: truncate a long message header so that we don't exceed
+     * the Milter request size limit of 65535.
+     */
+#define KLUDGE_HEADER_LIMIT    60000
+    if ((cleanup_milters || state->milters)
+       && var_header_limit > KLUDGE_HEADER_LIMIT)
+       var_header_limit = KLUDGE_HEADER_LIMIT;
+
     /*
      * Pass control to the header processing routine.
      */
index 6e40e1680e3c2e0fc652b8f59841671f115a69b2..5836159c4037a7e0585dac82f52af6d72c453aaf 100644 (file)
@@ -1697,6 +1697,8 @@ static void usage(void)
     msg_warn("    del_rcpt addr");
 }
 
+/* flatten_args - unparse partial command line */
+
 static void flatten_args(VSTRING *buf, char **argv)
 {
     char  **cpp;
@@ -1710,6 +1712,8 @@ static void flatten_args(VSTRING *buf, char **argv)
     VSTRING_TERMINATE(buf);
 }
 
+/* open_queue_file - open an unedited queue file (all-zero dummy PTRs) */
+
 static void open_queue_file(CLEANUP_STATE *state, const char *path)
 {
     VSTRING *buf = vstring_alloc(100);
@@ -1720,6 +1724,13 @@ static void open_queue_file(CLEANUP_STATE *state, const char *path)
     long    rcpt_count;
     long    qmgr_opts;
 
+    if (state->dst != 0) {
+       msg_warn("closing %s", cleanup_path);
+       vstream_fclose(state->dst);
+       state->dst = 0;
+       myfree(cleanup_path);
+       cleanup_path = 0;
+    }
     if ((state->dst = vstream_fopen(path, O_RDWR, 0)) == 0) {
        msg_warn("open %s: %m", path);
     } else {
@@ -1794,6 +1805,7 @@ int     main(int unused_argc, char **argv)
 
     msg_vstream_init(argv[0], VSTREAM_ERR);
     var_line_limit = DEF_LINE_LIMIT;
+    var_header_limit = DEF_HEADER_LIMIT;
 
     for (;;) {
        ARGV   *argv;
index c816373727da144e7e425f659865e5b77643588a..52d3211fbac6da608a24e452ece4795575fc98cd 100644 (file)
@@ -175,9 +175,22 @@ void    cleanup_out_header(CLEANUP_STATE *state, VSTRING *header_buf)
      * of such header lines. NB: This code destroys the header. We could try
      * to avoid clobbering it, but we're not going to use the data any
      * further.
+     * 
+     * XXX We prefer to truncate a header at the last line boundary before the
+     * header size limit. If this would undershoot the limit by more than
+     * 10%, we truncate between line boundaries to avoid losing too much
+     * text. This "unkind cut" may result in syntax errors and may trigger
+     * warnings from down-stream MTAs.
      */
     for (line = start; line; line = next_line) {
        next_line = split_at(line, '\n');
+       if ((next_line ? next_line - 1 : line + strlen(line))
+           > start + var_header_limit) {
+           if (line - start > 0.9 * var_header_limit)  /* nice cut */
+               break;
+           start[var_header_limit] = 0;        /* unkind cut */
+           next_line = 0;
+       }
        if (line == start || IS_SPACE_TAB(*line)) {
            cleanup_out_string(state, REC_TYPE_NORM, line);
        } else {
index 5ce496af76d2845c6e9be213dae578b3a142c9e9..b8da5abcebc32d9accf3c53a81ec45fa2610c8c5 100644 (file)
@@ -90,6 +90,7 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
     DICT_PROXY *dict_proxy = (DICT_PROXY *) dict;
     VSTREAM *stream;
     int     status;
+    int     count = 0;
 
     /*
      * The client and server live in separate processes that may start and
@@ -103,6 +104,7 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
     for (;;) {
        stream = clnt_stream_access(proxy_stream);
        errno = 0;
+       count += 1;
        if (attr_print(stream, ATTR_FLAG_NONE,
                       ATTR_TYPE_STR, MAIL_ATTR_REQ, PROXY_REQ_LOOKUP,
                       ATTR_TYPE_STR, MAIL_ATTR_TABLE, dict->name,
@@ -114,7 +116,7 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
                         ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status,
                         ATTR_TYPE_STR, MAIL_ATTR_VALUE, dict_proxy->result,
                         ATTR_TYPE_END) != 2) {
-           if (msg_verbose || (errno != EPIPE && errno != ENOENT))
+           if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
                msg_warn("%s: service %s: %m", myname, VSTREAM_PATH(stream));
        } else {
            if (msg_verbose)
index 7e9562ced6fc8403e843b64a07c1ec650b4c7c30..22caf42e59c1d64dcd144cd2b06067b9e28a1afe 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      "20061101"
-#define MAIL_VERSION_NUMBER    "2.3.4"
+#define MAIL_RELEASE_DATE      "20061205"
+#define MAIL_VERSION_NUMBER    "2.3.5-RC1"
 
 #ifdef SNAPSHOT
 # define MAIL_VERSION_DATE     "-" MAIL_RELEASE_DATE
index 1b9ae4e8d87e6ba59f835d6b83b5fb3947a1aec7..b96f0a736bfbf575803ce3c98c216ddf6a34b340 100644 (file)
@@ -164,6 +164,7 @@ void    resolve_clnt(const char *class, const char *sender,
     const char *myname = "resolve_clnt";
     VSTREAM *stream;
     int     server_flags;
+    int     count = 0;
 
     /*
      * One-entry cache.
@@ -226,6 +227,7 @@ void    resolve_clnt(const char *class, const char *sender,
     for (;;) {
        stream = clnt_stream_access(rewrite_clnt_stream);
        errno = 0;
+       count += 1;
        if (attr_print(stream, ATTR_FLAG_NONE,
                       ATTR_TYPE_STR, MAIL_ATTR_REQ, class,
                       ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
@@ -239,7 +241,7 @@ void    resolve_clnt(const char *class, const char *sender,
                         ATTR_TYPE_STR, MAIL_ATTR_RECIP, reply->recipient,
                         ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &reply->flags,
                         ATTR_TYPE_END) != 5) {
-           if (msg_verbose || (errno != EPIPE && errno != ENOENT))
+           if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
                msg_warn("problem talking to service %s: %m",
                         var_rewrite_service);
        } else {
index 601f7ca000fa73aeacaee31a2d51d166d1976f03..8bb3f0a5247967432349fed7cbf7bf851772c3af 100644 (file)
@@ -82,6 +82,7 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
 {
     VSTREAM *stream;
     int     server_flags;
+    int     count = 0;
 
     /*
      * One-entry cache.
@@ -129,6 +130,7 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
     for (;;) {
        stream = clnt_stream_access(rewrite_clnt_stream);
        errno = 0;
+       count += 1;
        if (attr_print(stream, ATTR_FLAG_NONE,
                       ATTR_TYPE_STR, MAIL_ATTR_REQ, REWRITE_ADDR,
                       ATTR_TYPE_STR, MAIL_ATTR_RULE, rule,
@@ -139,7 +141,7 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
                         ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &server_flags,
                         ATTR_TYPE_STR, MAIL_ATTR_ADDR, result,
                         ATTR_TYPE_END) != 2) {
-           if (msg_verbose || (errno != EPIPE && errno != ENOENT))
+           if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
                msg_warn("problem talking to service %s: %m",
                         var_rewrite_service);
        } else {
index 10573e7df1d88b1e4bc17f087c7a7fbc9222f06f..658e88f75b521a631ef4eb6e573c92222dd4e19d 100644 (file)
@@ -91,6 +91,7 @@ static void scache_clnt_save_endp(SCACHE *scache, int endp_ttl,
     VSTREAM *stream;
     int     status;
     int     tries;
+    int     count = 0;
 
     if (msg_verbose)
        msg_info("%s: endp=%s prop=%s fd=%d",
@@ -110,6 +111,7 @@ static void scache_clnt_save_endp(SCACHE *scache, int endp_ttl,
     for (tries = 0; sp->auto_clnt != 0; tries++) {
        if ((stream = auto_clnt_access(sp->auto_clnt)) != 0) {
            errno = 0;
+           count += 1;
            if (attr_print(stream, ATTR_FLAG_NONE,
                         ATTR_TYPE_STR, MAIL_ATTR_REQ, SCACHE_REQ_SAVE_ENDP,
                           ATTR_TYPE_INT, MAIL_ATTR_TTL, endp_ttl,
@@ -126,7 +128,7 @@ static void scache_clnt_save_endp(SCACHE *scache, int endp_ttl,
                || attr_scan(stream, ATTR_FLAG_STRICT,
                             ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status,
                             ATTR_TYPE_END) != 1) {
-               if (msg_verbose || (errno != EPIPE && errno != ENOENT))
+               if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
                    msg_warn("problem talking to service %s: %m",
                             VSTREAM_PATH(stream));
                /* Give up or recover. */
@@ -281,7 +283,7 @@ static void scache_clnt_save_dest(SCACHE *scache, int dest_ttl,
                             myname, status);
                break;
            }
-           }
+       }
        /* Give up or recover. */
        if (tries >= SCACHE_MAX_TRIES - 1) {
            msg_warn("disabling connection caching");
index 916cce3fc876d00179cb0fbb7870feeeb6ad0453..7468c1f0c6a12b6d0d40e9dd72fc28ac8b3552b4 100644 (file)
@@ -96,6 +96,7 @@ int     verify_clnt_query(const char *addr, int *addr_status, VSTRING *why)
 {
     VSTREAM *stream;
     int     request_status;
+    int     count = 0;
 
     /*
      * Do client-server plumbing.
@@ -109,6 +110,7 @@ int     verify_clnt_query(const char *addr, int *addr_status, VSTRING *why)
     for (;;) {
        stream = clnt_stream_access(vrfy_clnt);
        errno = 0;
+       count += 1;
        if (attr_print(stream, ATTR_FLAG_NONE,
                       ATTR_TYPE_STR, MAIL_ATTR_REQ, VRFY_REQ_QUERY,
                       ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
@@ -119,7 +121,7 @@ int     verify_clnt_query(const char *addr, int *addr_status, VSTRING *why)
                         ATTR_TYPE_INT, MAIL_ATTR_ADDR_STATUS, addr_status,
                         ATTR_TYPE_STR, MAIL_ATTR_WHY, why,
                         ATTR_TYPE_END) != 3) {
-           if (msg_verbose || (errno != EPIPE && errno != ENOENT))
+           if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
                msg_warn("problem talking to service %s: %m",
                         var_verify_service);
        } else {
index b4105c0cb3004781a87042877e466876a87a4c76..4ded90673f7e2adb6833f369fedbb89b849c9474 100644 (file)
@@ -858,6 +858,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
                                         int skip_reply,
                                         ARGV *macros,...)
 {
+    const char *myname = "milter8_event";
     va_list ap;
     ssize_t data_len;
     int     err;
@@ -871,6 +872,17 @@ static const char *milter8_event(MILTER8 *milter, int event,
 
 #define DONT_SKIP_REPLY        0
 
+    /*
+     * Sanity check.
+     */
+    if (milter->fp == 0 || milter->def_reply != 0) {
+       msg_warn("%s: attempt to send event %s to milter %s after error",
+                myname,
+                (smfic_name = str_name_code(smfic_table, event)) != 0 ?
+                smfic_name : "(unknown MTA event)", milter->m.name);
+       return (milter->def_reply);
+    }
+
     /*
      * Skip this event if it doesn't exist in the protocol that I announced.
      */
@@ -1185,7 +1197,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
                                                       (ssize_t) index,
                                                       STR(milter->buf));
                    if (edit_resp)
-                       return (milter8_def_reply(milter, edit_resp));
+                       return (edit_resp);
                    continue;
 #endif
 
@@ -1203,7 +1215,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
                                                   STR(milter->buf),
                                                   STR(milter->body));
                    if (edit_resp)
-                       return (milter8_def_reply(milter, edit_resp));
+                       return (edit_resp);
                    continue;
 
                    /*
@@ -1232,7 +1244,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
                                                   STR(milter->buf),
                                                   STR(milter->body));
                    if (edit_resp)
-                       return (milter8_def_reply(milter, edit_resp));
+                       return (edit_resp);
                    continue;
 #endif
 
@@ -1248,7 +1260,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
                    edit_resp = parent->add_rcpt(parent->chg_context,
                                                 STR(milter->buf));
                    if (edit_resp)
-                       return (milter8_def_reply(milter, edit_resp));
+                       return (edit_resp);
                    continue;
 
                    /*
@@ -1263,7 +1275,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
                    edit_resp = parent->del_rcpt(parent->chg_context,
                                                 STR(milter->buf));
                    if (edit_resp)
-                       return (milter8_def_reply(milter, edit_resp));
+                       return (edit_resp);
                    continue;
 
                    /*
@@ -1280,7 +1292,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
                    edit_resp = parent->repl_body(parent->chg_context,
                                                  milter->body);
                    if (edit_resp)
-                       return (milter8_def_reply(milter, edit_resp));
+                       return (edit_resp);
                    continue;
 #endif
                }
@@ -1927,6 +1939,16 @@ static void milter8_header(void *ptr, int unused_header_class,
     char   *cp;
     int     skip_reply;
 
+    /*
+     * XXX Workaround: mime_state_update() may invoke multiple call-backs
+     * before returning to the caller.
+     */
+#define MILTER8_MESSAGE_DONE(milter, msg_ctx) \
+       ((milter)->state != MILTER8_STAT_MESSAGE || (msg_ctx)->resp != 0)
+
+    if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
+       return;
+
     /*
      * XXX Sendmail compatibility. Don't expose our first (received) header
      * to mail filter applications. See also cleanup_milter.c for code to
@@ -1990,6 +2012,8 @@ static void milter8_eoh(void *ptr)
     MILTER_MSG_CONTEXT *msg_ctx = (MILTER_MSG_CONTEXT *) ptr;
     MILTER8 *milter = msg_ctx->milter;
 
+    if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
+       return;
     if (msg_verbose)
        msg_info("%s: eoh milter %s", myname, milter->m.name);
     msg_ctx->resp =
@@ -2012,6 +2036,9 @@ static void milter8_body(void *ptr, int rec_type,
     ssize_t space;
     ssize_t count;
 
+    if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
+       return;
+
     /*
      * XXX Sendmail compatibility: don't expose our first body line.
      */
@@ -2079,6 +2106,8 @@ static void milter8_eob(void *ptr)
     MILTER_MSG_CONTEXT *msg_ctx = (MILTER_MSG_CONTEXT *) ptr;
     MILTER8 *milter = msg_ctx->milter;
 
+    if (MILTER8_MESSAGE_DONE(milter, msg_ctx))
+       return;
     if (msg_verbose)
        msg_info("%s: eob milter %s", myname, milter->m.name);
     msg_ctx->resp =
@@ -2144,7 +2173,7 @@ static const char *milter8_message(MILTER *m, VSTREAM *qfile,
 
        /*
         * XXX When the message (not MIME body part) does not end in CRLF
-        * (i.e. the last record was REC_TYPE_CONT), do we send CRLF
+        * (i.e. the last record was REC_TYPE_CONT), do we send CRLF
         * terminator before triggering the end-of-body condition?
         */
        for (;;) {
@@ -2164,9 +2193,7 @@ static const char *milter8_message(MILTER *m, VSTREAM *qfile,
                msg_ctx.resp = "450 4.3.0 Queue file write error";
                break;
            }
-           if (msg_ctx.resp != 0)
-               break;
-           if (milter->state != MILTER8_STAT_MESSAGE)
+           if (MILTER8_MESSAGE_DONE(milter, &msg_ctx))
                break;
            if (rec_type != REC_TYPE_NORM && rec_type != REC_TYPE_CONT)
                break;
index 3783a61f1b6429979c3069929ccd100016188b3c..ccffdb0b080c985282e2e961c31555d8eedcffec 100644 (file)
@@ -237,7 +237,7 @@ void    qmgr_entry_done(QMGR_ENTRY *entry, int which)
 #define FUDGE(x)       ((x) * (var_qmgr_fudge / 100.0))
     message->refcount--;
     if (message->rcpt_offset > 0
-       && qmgr_recipient_count < FUDGE(var_qmgr_rcpt_limit))
+       && qmgr_recipient_count < FUDGE(var_qmgr_rcpt_limit) - 100)
        qmgr_message_realloc(message);
     if (message->refcount == 0)
        qmgr_active_done(message);
index 30365f6a8192d8508ec91bb9133c6ffa7a2297c3..6318893f443c107f2674bb10146c12eb5e842eb5 100644 (file)
@@ -763,6 +763,16 @@ static QMGR_PEER *qmgr_job_peer_select(QMGR_JOB *job)
     QMGR_PEER *peer;
     QMGR_MESSAGE *message = job->message;
 
+    /*
+     * Workaround to prevent queue manager starvation until the last slow
+     * batch of multi-recipient mail is finished. Postfix 2.4 has a final
+     * solution, but that involves major changes.
+     */
+    if (message->rcpt_offset != 0
+       && message->rcpt_limit > message->rcpt_count + 100
+       && message->refcount > 0) {
+       qmgr_message_realloc(message);
+    }
     if (HAS_ENTRIES(job) && (peer = qmgr_peer_select(job)) != 0)
        return (peer);
 
index aa71e190772c694088145a43d164ceb82581da44..dcb796df0251dc0740fe863b04099a48dd353cb2 100644 (file)
@@ -361,6 +361,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
        if (recipient_limit < message->rcpt_limit)
            recipient_limit = message->rcpt_limit;
     }
+    /* Keep interrupt latency in check. */
+    if (recipient_limit > 5000)
+       recipient_limit = 5000;
     if (recipient_limit <= 0)
        msg_panic("%s: no recipient slots available", message->queue_id);
 
index 82ea275644d5e5c3a985a17af8ab5fed459893e5..252924f92899cd6491f1cfb68d47281df396c616 100644 (file)
@@ -305,7 +305,8 @@ SMTP_RESP *smtp_chat_resp(SMTP_SESSION *session)
         */
        session->error_mask |= MAIL_ERROR_PROTOCOL;
        if (session->features & SMTP_FEATURE_PIPELINING) {
-           msg_warn("non-%s response from %s: %.100s",
+           msg_warn("%s: non-%s response from %s: %.100s",
+                    session->state->request->queue_id,
                     (session->state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) ?
                     "LMTP" : "ESMTP", session->namaddrport,
                     STR(session->buffer));
index 3f87e7dc3045ca995844e56c9967d88e5276ef28..19b5267f4300c9221fa5e2db2f4eba6bbaa4cce2 100644 (file)
@@ -379,7 +379,11 @@ static void smtp_cleanup_session(SMTP_STATE *state)
     bad_session = THIS_SESSION_IS_BAD;         /* smtp_quit() may fail */
     if (THIS_SESSION_IS_EXPIRED)
        smtp_quit(state);                       /* also disables caching */
-    if (THIS_SESSION_IS_CACHED) {
+    if (THIS_SESSION_IS_CACHED
+       /* Redundant tests for safety... */
+       && vstream_ferror(session->stream) == 0
+       && vstream_ftimeout(session->stream) == 0
+       && vstream_feof(session->stream) == 0) {
        smtp_save_session(state);
     } else {
        smtp_session_free(session);
@@ -493,6 +497,7 @@ static void smtp_connect_local(SMTP_STATE *state, const char *path)
            && smtp_helo(state) != 0) {
            if (!THIS_SESSION_IS_DEAD
                && vstream_ferror(session->stream) == 0
+               && vstream_ftimeout(session->stream) == 0
                && vstream_feof(session->stream) == 0)
                smtp_quit(state);
        } else {
@@ -871,6 +876,7 @@ static void smtp_connect_remote(SMTP_STATE *state, const char *nexthop,
                     */
                    if (!THIS_SESSION_IS_DEAD
                        && vstream_ferror(session->stream) == 0
+                       && vstream_ftimeout(session->stream) == 0
                        && vstream_feof(session->stream) == 0)
                        smtp_quit(state);
                } else {
index 276db41ce130ac657c1b9838b9654d660d4f46d0..23ed31648624f93adc9af0688bbbe75355f39ad3 100644 (file)
@@ -1014,6 +1014,8 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
     } while (0)
 
 #define RETURN(x) do { \
+       if (recv_state != SMTP_STATE_LAST) \
+           DONT_CACHE_THIS_SESSION; \
        vstring_free(next_command); \
        if (survivors) \
            myfree((char *) survivors); \