From: Wietse Venema Date: Wed, 30 Nov 2005 05:00:00 +0000 (-0500) Subject: postfix-2.2.6 X-Git-Tag: v2.2.6^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0b6ded1ad39e5e8c92aa47ea050525c873a9e277;p=thirdparty%2Fpostfix.git postfix-2.2.6 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 4cfc645a1..d17c89855 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -10618,11 +10618,11 @@ Apologies for any names omitted. 20050706 - Robustness: the SMTP client now disables caching when it - is unable to communicate with the scache(8) connection - caching server, instead of looping forever and not delivering - mail. File: global/scache_clnt.c. This code is back-ported - from the Postfix 2.3 snapshot release. + Robustness: the SMTP client now disables connection caching + when it is unable to communicate with the scache(8) server, + instead of looping forever and not delivering mail. File: + global/scache_clnt.c. This code is back-ported from the + Postfix 2.3 snapshot release. Portability: after sending a socket, the scache(8) server now waits for an ACK from the connection cache client before @@ -10639,3 +10639,94 @@ Apologies for any names omitted. modules, but that results in too much change, and is not allowed in the stable release). Files: tls/tls_scache.c, util/clean_env.c, util/vstring.h, smtpstone/qmqp-source.c. + +20050806 + + Workaround: accept(2) fails with EPROTO when the client + already disconnected (SunOS 5.5.1). File: sane_accept.c. + +20050815 + + Workaround: old Solaris compilers can't link an archive + without globally visible symbols. File: tls/tls_misc.c. + +20050922 + + Bugfix: the *SQL clients did not uniformly choose the + database host from the available pool of servers due to an + off-by-one error, so that the "last" available server was + not selected. Leandro Santi. Files: dict_mysql.c, dict_pgsql.c. + +20050929 + + Paranoia: don't ignore garbage in SMTP or LMTP server replies + when ESMTP command pipelining is turned on. For example, + after sending ".QUIT", Postfix could recognize + the server's 2XX QUIT reply as a 2XX END-OF-DATA reply after + garbage, causing mail to be lost. The SMTP and LMTP clients + now report a remote protocol error and defer delivery. + Files: smtp/smtp_chat.c, smtp/smtp_trouble.c, lmtp/lmtp_chat.c, + lmtp/lmtp_trouble.c. + +20051011 + + Bugfix: raise the "policy violation" flag when a client + request exceeds a concurrency or rate limit. File: + smtpd/smtpd.c. + + Bugfix (cut-and-paste error): don't reply with 421 (too + many MAIL FROM or RCPT TO commands) when we aren't closing + the connection. File: smtpd/smtpd.c. + +20051013 + + Bugfix: don't do smtpd_end_of_data_restrictions after the + transaction failed due to, e.g., a write error. File: + smtpd/smtpd.c. + + Cleanup: the SMTP server now enforces the message_size_limit + even when the client did not send SIZE information with the + MAIL FROM command. This protects before-queue content + filters against over-size messages. File: smtpd/smtpd.c. + +20051105 + + Workaround: the next-hop logical destination information + for connection caching was reset only after a good non-TLS + connection, so that cached connections to non-TLS backup + servers could suck away traffic from TLS primary servers + (the Postfix SMTP client cannot cache an open TLS connection). + Found during code review. Fixing this requires more change + than is allowed in a stable release. File: smtp/smtp_connect.c. + +20051108 + + Bugfix: two messages could get the same message ID due to + a race condition. This time window was increased when queue + file creation was postponed from MAIL FROM until the first + accepted RCPT TO. The window is closed again. Found by + Victor. Files: global/mail_stream.c, global/mail_queue.c, + cleanup/cleanup_message.c. This code is back-ported from + the Postfix 2.3 snapshot release. + +20051119 + + Bugfix: the queue manager did not write a per-recipient + defer logfile record when the delivery agent crashed after + the initial handshake with the queue manager, and before + reporting the delivery status to the queue manager. Files: + *qmgr/qmgr_deliver.c. + +20051126 + + Log warning when REDIRECT, FILTER, HOLD and DISCARD are + used in smtpd_etrn_restrictions. File: smtpd/smtpd_check.c. + +20051128 + + Bugfix: moved code around from one place to another to make + REDIRECT, FILTER, HOLD and DISCARD access(5) table actions + work in smtpd_end_of_data_restrictions. PREPEND will not + be fixed; it must be specified before the message content + is received. Files: smtpd/smtpd.c, smtpd/smtpd_check.c, + cleanup/cleanup_extracted.c, pickup/pickup.c. diff --git a/postfix/README_FILES/ADDRESS_REWRITING_README b/postfix/README_FILES/ADDRESS_REWRITING_README index f433ec3a5..6004bbcef 100644 --- a/postfix/README_FILES/ADDRESS_REWRITING_README +++ b/postfix/README_FILES/ADDRESS_REWRITING_README @@ -367,7 +367,7 @@ Example: /etc/postfix/master.cf: :10026 inet n - n - - smtpd - -o receive_override_options=no_address_mapping + -o receive_override_options=no_address_mappings Note: do not specify whitespace around the "=" here. @@ -440,7 +440,7 @@ Example: /etc/postfix/master.cf: :10026 inet n - n - - smtpd - -o receive_override_options=no_address_mapping + -o receive_override_options=no_address_mappings Note: do not specify whitespace around the "=" here. @@ -476,7 +476,7 @@ Example: /etc/postfix/master.cf: :10026 inet n - n - - smtpd - -o receive_override_options=no_address_mapping + -o receive_override_options=no_address_mappings Note: do not specify whitespace around the "=" here. @@ -525,7 +525,7 @@ Example: /etc/postfix/master.cf: :10026 inet n - n - - smtpd - -o receive_override_options=no_address_mapping + -o receive_override_options=no_address_mappings Note: do not specify whitespace around the "=" here. diff --git a/postfix/README_FILES/MAILDROP_README b/postfix/README_FILES/MAILDROP_README index 36afd1e06..ca8580847 100644 --- a/postfix/README_FILES/MAILDROP_README +++ b/postfix/README_FILES/MAILDROP_README @@ -100,7 +100,7 @@ To enable maildrop delivery for specific users only, you can use the Postfix local(8) delivery agent's mailbox_command_maps feature: /etc/postfix/main.cf: - mailbox_command_maps = /etc/postfix/mailbox_commands + mailbox_command_maps = hash:/etc/postfix/mailbox_commands /etc/postfix/mailbox_commands: you /path/to/maildrop -d ${USER} diff --git a/postfix/README_FILES/TLS_README b/postfix/README_FILES/TLS_README index fd270b9cb..25d0aa43d 100644 --- a/postfix/README_FILES/TLS_README +++ b/postfix/README_FILES/TLS_README @@ -154,9 +154,9 @@ If you want the Postfix SMTP server to accept remote SMTP client certificates issued by these CAs, append the root certificate to $smtpd_tls_CAfile or install it in the $smtpd_tls_CApath directory. When you configure trust in a root CA, it is not necessary to explicitly trust intermediary CAs signed by the -root CA, unless $smtpd_tls_verify_depth is less than the number of CAs in the -certificate chain for the clients of interest. With a verify depth of 1 you can -only verify certificates directly signed by a trusted CA, and all trusted +root CA, unless $smtpd_tls_ccert_verifydepth is less than the number of CAs in +the certificate chain for the clients of interest. With a verify depth of 1 you +can only verify certificates directly signed by a trusted CA, and all trusted intermediary CAs need to be configured explicitly. With a verify depth of 2 you can verify clients signed by a root CA or a direct intermediary CA (so long as the client is correctly configured to supply its intermediate CA certificate). @@ -192,7 +192,7 @@ $smtpd_tls_CApath directory needs to be accessible inside the optional chroot jail. When you configure Postfix to request client certificates (by setting -$smtpd_tls_asck_ccert = yes), any certificates in $smtpd_tls_CAfile are sent to +$smtpd_tls_ask_ccert = yes), any certificates in $smtpd_tls_CAfile are sent to the client, in order to allow it to choose an identity signed by a CA you trust. If no $smtpd_tls_CAfile is specified, no preferred CA list is sent, and the client is free to choose an identity signed by any CA. Many clients use a diff --git a/postfix/conf/access b/postfix/conf/access index a424ea598..79946780b 100644 --- a/postfix/conf/access +++ b/postfix/conf/access @@ -1,4 +1,4 @@ -# ACCESS(5) ACCESS(5) +# ACCESS(5) ACCESS(5) # # NAME # access - Postfix access table format @@ -263,6 +263,10 @@ # Note: this action does not support multi-line mes- # sage headers. # +# Note: this action must be used before the message +# content is received; it cannot be used in +# smtpd_end_of_data_restrictions. +# # This feature is available in Postfix 2.1 and later. # # REDIRECT user@domain @@ -297,8 +301,8 @@ # user@ and domain constituent parts, nor is user+foo broken # up into user and foo. # -# Patterns are applied in the order as specified in the -# table, until a pattern is found that matches the search +# Patterns are applied in the order as specified in the ta- +# ble, until a pattern is found that matches the search # string. # # Actions are the same as with indexed file lookups, with @@ -308,9 +312,9 @@ # TCP-BASED TABLES # This section describes how the table lookups change when # lookups are directed to a TCP-based server. For a descrip- -# tion of the TCP client/server lookup protocol, see -# tcp_table(5). This feature is not available up to and -# including Postfix version 2.2. +# tion of the TCP client/server lookup protocol, see tcp_ta- +# ble(5). This feature is not available up to and including +# Postfix version 2.2. # # Each lookup operation uses the entire query string once. # Depending on the application, that string is an entire @@ -367,4 +371,4 @@ # P.O. Box 704 # Yorktown Heights, NY 10598, USA # -# ACCESS(5) +# ACCESS(5) diff --git a/postfix/html/ADDRESS_REWRITING_README.html b/postfix/html/ADDRESS_REWRITING_README.html index 226d937be..8233562a8 100644 --- a/postfix/html/ADDRESS_REWRITING_README.html +++ b/postfix/html/ADDRESS_REWRITING_README.html @@ -603,7 +603,7 @@ in the master.cf file. This feature is available in Postfix version
 /etc/postfix/master.cf:
     :10026      inet  n       -       n       -       -       smtpd
-        -o receive_override_options=no_address_mapping
+        -o receive_override_options=no_address_mappings
 
@@ -702,7 +702,7 @@ Postfix version 2.1 and later.

 /etc/postfix/master.cf:
     :10026      inet  n       -       n       -       -       smtpd
-        -o receive_override_options=no_address_mapping
+        -o receive_override_options=no_address_mappings
 
@@ -752,7 +752,7 @@ is available in Postfix version 2.1 and later.

 /etc/postfix/master.cf:
     :10026      inet  n       -       n       -       -       smtpd
-        -o receive_override_options=no_address_mapping
+        -o receive_override_options=no_address_mappings
 
@@ -816,7 +816,7 @@ in the master.cf file. This feature is available in Postfix version
 /etc/postfix/master.cf:
     :10026      inet  n       -       n       -       -       smtpd
-        -o receive_override_options=no_address_mapping
+        -o receive_override_options=no_address_mappings
 
diff --git a/postfix/html/MAILDROP_README.html b/postfix/html/MAILDROP_README.html index bdf121caa..1216218c4 100644 --- a/postfix/html/MAILDROP_README.html +++ b/postfix/html/MAILDROP_README.html @@ -149,7 +149,7 @@ use the Postfix local(8) delivery agent's mailbox_command_maps = /etc/postfix/mailbox_commands + mailbox_command_maps = hash:/etc/postfix/mailbox_commands /etc/postfix/mailbox_commands: you /path/to/maildrop -d ${USER} diff --git a/postfix/html/TLS_README.html b/postfix/html/TLS_README.html index 8030a819d..cf4b4c6e2 100644 --- a/postfix/html/TLS_README.html +++ b/postfix/html/TLS_README.html @@ -262,7 +262,7 @@ the overhead of the TLS exchange.

certificates issued by these CAs, append the root certificate to $smtpd_tls_CAfile or install it in the $smtpd_tls_CApath directory. When you configure trust in a root CA, it is not necessary to explicitly trust -intermediary CAs signed by the root CA, unless $smtpd_tls_verify_depth +intermediary CAs signed by the root CA, unless $smtpd_tls_ccert_verifydepth is less than the number of CAs in the certificate chain for the clients of interest. With a verify depth of 1 you can only verify certificates directly signed by a trusted CA, and all trusted intermediary CAs need to @@ -315,7 +315,7 @@ is needed. Thus, the $smtpd_tls_CApat accessible inside the optional chroot jail.

When you configure Postfix to request client certificates (by -setting $smtpd_tls_asck_ccert = yes), any certificates in +setting $smtpd_tls_ask_ccert = yes), any certificates in $smtpd_tls_CAfile are sent to the client, in order to allow it to choose an identity signed by a CA you trust. If no $smtpd_tls_CAfile is specified, no preferred CA list is sent, and the client is free diff --git a/postfix/html/access.5.html b/postfix/html/access.5.html index e60da0971..412b9cd62 100644 --- a/postfix/html/access.5.html +++ b/postfix/html/access.5.html @@ -269,6 +269,10 @@ ACCESS(5) ACCESS(5) Note: this action does not support multi-line mes- sage headers. + Note: this action must be used before the message + content is received; it cannot be used in + smtpd_end_of_data_restrictions. + This feature is available in Postfix 2.1 and later. REDIRECT user@domain diff --git a/postfix/man/man5/access.5 b/postfix/man/man5/access.5 index 7f9cfb821..c61a02696 100644 --- a/postfix/man/man5/access.5 +++ b/postfix/man/man5/access.5 @@ -246,6 +246,9 @@ header appears before the second etc. prepended header. .sp Note: this action does not support multi-line message headers. .sp +Note: this action must be used before the message content +is received; it cannot be used in \fBsmtpd_end_of_data_restrictions\fR. +.sp This feature is available in Postfix 2.1 and later. .IP "\fBREDIRECT \fIuser@domain\fR" After the message is queued, send the message to the specified diff --git a/postfix/proto/ADDRESS_REWRITING_README.html b/postfix/proto/ADDRESS_REWRITING_README.html index 4955a6e8b..57f7fa2a5 100644 --- a/postfix/proto/ADDRESS_REWRITING_README.html +++ b/postfix/proto/ADDRESS_REWRITING_README.html @@ -603,7 +603,7 @@ in the master.cf file. This feature is available in Postfix version

 /etc/postfix/master.cf:
     :10026      inet  n       -       n       -       -       smtpd
-        -o receive_override_options=no_address_mapping
+        -o receive_override_options=no_address_mappings
 
@@ -702,7 +702,7 @@ Postfix version 2.1 and later.

 /etc/postfix/master.cf:
     :10026      inet  n       -       n       -       -       smtpd
-        -o receive_override_options=no_address_mapping
+        -o receive_override_options=no_address_mappings
 
@@ -752,7 +752,7 @@ is available in Postfix version 2.1 and later.

 /etc/postfix/master.cf:
     :10026      inet  n       -       n       -       -       smtpd
-        -o receive_override_options=no_address_mapping
+        -o receive_override_options=no_address_mappings
 
@@ -816,7 +816,7 @@ in the master.cf file. This feature is available in Postfix version
 /etc/postfix/master.cf:
     :10026      inet  n       -       n       -       -       smtpd
-        -o receive_override_options=no_address_mapping
+        -o receive_override_options=no_address_mappings
 
diff --git a/postfix/proto/MAILDROP_README.html b/postfix/proto/MAILDROP_README.html index 8ce2c402f..e41e127f5 100644 --- a/postfix/proto/MAILDROP_README.html +++ b/postfix/proto/MAILDROP_README.html @@ -149,7 +149,7 @@ use the Postfix local(8) delivery agent's mailbox_command_maps feature:
 /etc/postfix/main.cf:
-    mailbox_command_maps = /etc/postfix/mailbox_commands
+    mailbox_command_maps = hash:/etc/postfix/mailbox_commands
 
 /etc/postfix/mailbox_commands:
     you    /path/to/maildrop -d ${USER}
diff --git a/postfix/proto/TLS_README.html b/postfix/proto/TLS_README.html
index 6b2165685..04711f7cc 100644
--- a/postfix/proto/TLS_README.html
+++ b/postfix/proto/TLS_README.html
@@ -262,7 +262,7 @@ the overhead of the TLS exchange. 

certificates issued by these CAs, append the root certificate to $smtpd_tls_CAfile or install it in the $smtpd_tls_CApath directory. When you configure trust in a root CA, it is not necessary to explicitly trust -intermediary CAs signed by the root CA, unless $smtpd_tls_verify_depth +intermediary CAs signed by the root CA, unless $smtpd_tls_ccert_verifydepth is less than the number of CAs in the certificate chain for the clients of interest. With a verify depth of 1 you can only verify certificates directly signed by a trusted CA, and all trusted intermediary CAs need to @@ -315,7 +315,7 @@ is needed. Thus, the $smtpd_tls_CApath directory needs to be accessible inside the optional chroot jail.

When you configure Postfix to request client certificates (by -setting $smtpd_tls_asck_ccert = yes), any certificates in +setting $smtpd_tls_ask_ccert = yes), any certificates in $smtpd_tls_CAfile are sent to the client, in order to allow it to choose an identity signed by a CA you trust. If no $smtpd_tls_CAfile is specified, no preferred CA list is sent, and the client is free diff --git a/postfix/proto/access b/postfix/proto/access index 405ba1f3f..26248d58d 100644 --- a/postfix/proto/access +++ b/postfix/proto/access @@ -226,6 +226,9 @@ # .sp # Note: this action does not support multi-line message headers. # .sp +# Note: this action must be used before the message content +# is received; it cannot be used in \fBsmtpd_end_of_data_restrictions\fR. +# .sp # This feature is available in Postfix 2.1 and later. # .IP "\fBREDIRECT \fIuser@domain\fR" # After the message is queued, send the message to the specified diff --git a/postfix/src/cleanup/cleanup_extracted.c b/postfix/src/cleanup/cleanup_extracted.c index 097abcef5..614ff01f1 100644 --- a/postfix/src/cleanup/cleanup_extracted.c +++ b/postfix/src/cleanup/cleanup_extracted.c @@ -95,14 +95,22 @@ void cleanup_extracted_process(CLEANUP_STATE *state, int type, const char *buf, int len) { const char *encoding; - const char generated_by_cleanup[] = { - REC_TYPE_FILT, REC_TYPE_RDR, REC_TYPE_ATTR, - REC_TYPE_RRTO, REC_TYPE_ERTO, 0, - }; + int extra_opts; if (msg_verbose) msg_info("extracted envelope %c %.*s", type, len, buf); + if (type == REC_TYPE_FLGS) { + /* Not part of queue file format. */ + extra_opts = atol(buf); + if (extra_opts & ~CLEANUP_FLAG_MASK_EXTRA) + msg_warn("%s: ignoring bad extra flags: 0x%x", + state->queue_id, extra_opts); + else + state->flags |= extra_opts; + return; + } + if (strchr(REC_TYPE_EXTRACT, type) == 0) { msg_warn("%s: message rejected: " "unexpected record type %d in extracted envelope", @@ -179,14 +187,8 @@ void cleanup_extracted_process(CLEANUP_STATE *state, int type, if (state->flags & CLEANUP_FLAG_INRCPT) /* Tell qmgr that recipient records are mixed with other information. */ state->qmgr_opts |= QMGR_READ_FLAG_MIXED_RCPT_OTHER; - if (strchr(generated_by_cleanup, type) != 0) { - /* Use our own header/body info instead. */ - return; - } else { - /* Pass on other non-recipient record. */ - cleanup_out(state, type, buf, len); - return; - } + cleanup_out(state, type, buf, len); + return; } /* cleanup_extracted_finish - process one extracted envelope record */ diff --git a/postfix/src/cleanup/cleanup_message.c b/postfix/src/cleanup/cleanup_message.c index 029f70688..e456f0b47 100644 --- a/postfix/src/cleanup/cleanup_message.c +++ b/postfix/src/cleanup/cleanup_message.c @@ -564,6 +564,7 @@ static void cleanup_header_done_callback(void *context) char time_stamp[1024]; /* XXX locale dependent? */ struct tm *tp; TOK822 *token; + time_t tv; /* * Add a missing (Resent-)Message-Id: header. The message ID gives the @@ -573,10 +574,17 @@ static void cleanup_header_done_callback(void *context) * * XXX It is the queue ID non-inode bits that prevent messages from getting * the same Message-Id within the same second. + * + * XXX An arbitrary amount of time may pass between the start of the mail + * transaction and the creation of a queue file. Since we guarantee queue + * ID uniqueness only within a second, we must ensure that the time in + * the message ID matches the queue ID creation time, as long as we use + * the queue ID in the message ID. */ if ((state->headers_seen & (1 << (state->resent[0] ? HDR_RESENT_MESSAGE_ID : HDR_MESSAGE_ID))) == 0) { - tp = gmtime(&state->time); + tv = state->handle->ctime.tv_sec; + tp = gmtime(&tv); strftime(time_stamp, sizeof(time_stamp), "%Y%m%d%H%M%S", tp); cleanup_out_format(state, REC_TYPE_NORM, "%sMessage-Id: <%s.%s@%s>", state->resent, time_stamp, state->queue_id, var_myhostname); diff --git a/postfix/src/dns/dns.h b/postfix/src/dns/dns.h index 90a45b82c..c57114c6f 100644 --- a/postfix/src/dns/dns.h +++ b/postfix/src/dns/dns.h @@ -19,6 +19,9 @@ #ifdef RESOLVE_H_NEEDS_STDIO_H #include #endif +#ifdef RESOLVE_H_NEEDS_NAMESER8_COMPAT_H +#include +#endif #include /* diff --git a/postfix/src/global/dict_mysql.c b/postfix/src/global/dict_mysql.c index e16d22933..3f85338fa 100644 --- a/postfix/src/global/dict_mysql.c +++ b/postfix/src/global/dict_mysql.c @@ -393,12 +393,8 @@ static HOST *dict_mysql_find_host(PLMYSQL *PLDB, unsigned stat, unsigned type) } if (count) { - /* - * Calling myrand() can deplete the random pool. - * Don't rely on the optimizer to weed out the call - * when count == 1. - */ - idx = (count > 1) ? 1 + (count - 1) * (double) myrand() / RAND_MAX : 1; + idx = (count > 1) ? + 1 + count * (double) myrand() / (1.0 + RAND_MAX) : 1; for (i = 0; i < PLDB->len_hosts; i++) { if (dict_mysql_check_stat(PLDB->db_hosts[i], stat, type, t) && diff --git a/postfix/src/global/dict_pgsql.c b/postfix/src/global/dict_pgsql.c index 025cb6b37..9fe6768bf 100644 --- a/postfix/src/global/dict_pgsql.c +++ b/postfix/src/global/dict_pgsql.c @@ -388,12 +388,8 @@ static HOST *dict_pgsql_find_host(PLPGSQL *PLDB, unsigned stat, unsigned type) } if (count) { - /* - * Calling myrand() can deplete the random pool. - * Don't rely on the optimizer to weed out the call - * when count == 1. - */ - idx = (count > 1) ? 1 + (count - 1) * (double) myrand() / RAND_MAX : 1; + idx = (count > 1) ? + 1 + count * (double) myrand() / (1.0 + RAND_MAX) : 1; for (i = 0; i < PLDB->len_hosts; i++) { if (dict_pgsql_check_stat(PLDB->db_hosts[i], stat, type, t) && diff --git a/postfix/src/global/mail_queue.c b/postfix/src/global/mail_queue.c index 9068955c3..89da51b47 100644 --- a/postfix/src/global/mail_queue.c +++ b/postfix/src/global/mail_queue.c @@ -6,9 +6,10 @@ /* SYNOPSIS /* #include /* -/* VSTREAM *mail_queue_enter(queue_name, mode) +/* VSTREAM *mail_queue_enter(queue_name, mode, tp) /* const char *queue_name; /* int mode; +/* struct timeval *tp; /* /* VSTREAM *mail_queue_open(queue_name, queue_id, flags, mode) /* const char *queue_name; @@ -53,7 +54,9 @@ /* id is the file base name, see VSTREAM_PATH(). Queue ids are /* relatively short strings and are recycled in the course of time. /* The only guarantee given is that on a given machine, no two queue -/* entries will have the same queue ID at the same time. +/* entries will have the same queue ID at the same time. The tp +/* argument, if not a null pointer, receives the time stamp that +/* corresponds with the queue ID. /* /* mail_queue_open() opens the named queue file. The \fIflags\fR /* and \fImode\fR arguments are as with open(2). The result is a @@ -304,7 +307,8 @@ int mail_queue_id_ok(const char *queue_id) /* mail_queue_enter - make mail queue entry with locally-unique name */ -VSTREAM *mail_queue_enter(const char *queue_name, int mode) +VSTREAM *mail_queue_enter(const char *queue_name, int mode, + struct timeval * tp) { char *myname = "mail_queue_enter"; static VSTRING *id_buf; @@ -326,7 +330,8 @@ VSTREAM *mail_queue_enter(const char *queue_name, int mode) path_buf = vstring_alloc(10); temp_path = vstring_alloc(100); } - GETTIMEOFDAY(&tv); + if (tp == 0) + tp = &tv; /* * Create a file with a temporary name that does not collide. The process @@ -338,13 +343,12 @@ VSTREAM *mail_queue_enter(const char *queue_name, int mode) * If someone is racing against us, try to win. */ for (;;) { + GETTIMEOFDAY(tp); vstring_sprintf(temp_path, "%s/%d.%d", queue_name, - (int) tv.tv_usec, pid); + (int) tp->tv_usec, pid); if ((fd = open(STR(temp_path), O_RDWR | O_CREAT | O_EXCL, mode)) >= 0) break; if (errno == EEXIST || errno == EISDIR) { - if ((int) ++tv.tv_usec < 0) - tv.tv_usec = 0; continue; } msg_warn("%s: create file %s: %m", myname, STR(temp_path)); @@ -364,7 +368,6 @@ VSTREAM *mail_queue_enter(const char *queue_name, int mode) * If someone is racing against us, try to win. */ file_id = get_file_id(fd); - GETTIMEOFDAY(&tv); /* * XXX Some systems seem to have clocks that correlate with process @@ -374,20 +377,12 @@ VSTREAM *mail_queue_enter(const char *queue_name, int mode) * prevents multiple messages from getting the same Message-ID value. */ for (count = 0;; count++) { - vstring_sprintf(id_buf, "%05X%s", (int) tv.tv_usec, file_id); + GETTIMEOFDAY(tp); + vstring_sprintf(id_buf, "%05X%s", (int) tp->tv_usec, file_id); mail_queue_path(path_buf, queue_name, STR(id_buf)); -#if 0 - if (access(STR(path_buf), X_OK) == 0) { /* collision. */ - if ((int) ++tv.tv_usec < 0) - tv.tv_usec = 0; - continue; - } -#endif if (sane_rename(STR(temp_path), STR(path_buf)) == 0) /* success */ break; if (errno == EPERM || errno == EISDIR) {/* collision. weird. */ - if ((int) ++tv.tv_usec < 0) - tv.tv_usec = 0; continue; } if (errno != ENOENT || mail_queue_mkdirs(STR(path_buf)) < 0) { diff --git a/postfix/src/global/mail_queue.h b/postfix/src/global/mail_queue.h index b3d692821..e9f7655e6 100644 --- a/postfix/src/global/mail_queue.h +++ b/postfix/src/global/mail_queue.h @@ -11,6 +11,11 @@ /* DESCRIPTION /* .nf + /* + * System library. + */ +#include + /* * Utility library. */ @@ -37,7 +42,7 @@ #define MAIL_QUEUE_STAT_READY (S_IRUSR | S_IWUSR | S_IXUSR) #define MAIL_QUEUE_STAT_CORRUPT (S_IRUSR) -extern struct VSTREAM *mail_queue_enter(const char *, int); +extern struct VSTREAM *mail_queue_enter(const char *, int, struct timeval *); extern struct VSTREAM *mail_queue_open(const char *, const char *, int, int); extern int mail_queue_rename(const char *, const char *, const char *); extern int mail_queue_remove(const char *, const char *); diff --git a/postfix/src/global/mail_stream.c b/postfix/src/global/mail_stream.c index 6edeea7ad..4930a6a5c 100644 --- a/postfix/src/global/mail_stream.c +++ b/postfix/src/global/mail_stream.c @@ -10,6 +10,7 @@ /* .in +4 /* VSTREAM *stream; /* char *id; +/* struct timeval ctime; /* private members... /* .in -4 /* } MAIL_STREAM; @@ -264,10 +265,11 @@ int mail_stream_finish(MAIL_STREAM *info, VSTRING *why) MAIL_STREAM *mail_stream_file(const char *queue, const char *class, const char *service, int mode) { + struct timeval tv; MAIL_STREAM *info; VSTREAM *stream; - stream = mail_queue_enter(queue, 0600 | mode); + stream = mail_queue_enter(queue, 0600 | mode, &tv); if (msg_verbose) msg_info("open %s", VSTREAM_PATH(stream)); @@ -280,6 +282,7 @@ MAIL_STREAM *mail_stream_file(const char *queue, const char *class, info->class = mystrdup(class); info->service = mystrdup(service); info->mode = mode; + info->ctime = tv; return (info); } diff --git a/postfix/src/global/mail_stream.h b/postfix/src/global/mail_stream.h index a1e64f13e..f1c393b5a 100644 --- a/postfix/src/global/mail_stream.h +++ b/postfix/src/global/mail_stream.h @@ -11,6 +11,11 @@ /* DESCRIPTION /* .nf + /* + * System library. + */ +#include + /* * Utility library. */ @@ -34,6 +39,7 @@ struct MAIL_STREAM { char *class; /* trigger class */ char *service; /* trigger service */ int mode; /* additional permissions */ + struct timeval ctime; /* creation time */ }; extern MAIL_STREAM *mail_stream_file(const char *, const char *, const char *, int); diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 5fcf512bc..f402600a1 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,8 +20,8 @@ * Patches change the patchlevel and the release date. Snapshots change the * release date only. */ -#define MAIL_RELEASE_DATE "20050719" -#define MAIL_VERSION_NUMBER "2.2.5" +#define MAIL_RELEASE_DATE "20051130" +#define MAIL_VERSION_NUMBER "2.2.6" #define VAR_MAIL_VERSION "mail_version" #ifdef SNAPSHOT diff --git a/postfix/src/global/smtp_stream.h b/postfix/src/global/smtp_stream.h index cbd0f7aba..0d31fa676 100644 --- a/postfix/src/global/smtp_stream.h +++ b/postfix/src/global/smtp_stream.h @@ -28,6 +28,7 @@ */ #define SMTP_ERR_EOF 1 /* unexpected client disconnect */ #define SMTP_ERR_TIME 2 /* time out */ +#define SMTP_ERR_PROTO 3 /* protocol (application) */ extern void smtp_timeout_setup(VSTREAM *, int); extern void PRINTFLIKE(2, 3) smtp_printf(VSTREAM *, const char *,...); diff --git a/postfix/src/lmtp/lmtp_chat.c b/postfix/src/lmtp/lmtp_chat.c index b06377138..7a0c31d9d 100644 --- a/postfix/src/lmtp/lmtp_chat.c +++ b/postfix/src/lmtp/lmtp_chat.c @@ -222,7 +222,21 @@ LMTP_RESP *lmtp_chat_resp(LMTP_STATE *state) if (*cp == ' ' || *cp == 0) break; } + + /* + * XXX Do not ignore garbage when ESMTP command pipelining is turned + * on. After sending ".QUIT", Postfix might recognize + * the server's 2XX QUIT reply as a 2XX END-OF-DATA reply after + * garbage, causing mail to be lost. Instead, make a long jump so + * that all recipients of multi-recipient mail get consistent + * treatment. + */ state->error_mask |= MAIL_ERROR_PROTOCOL; + if (state->features & LMTP_FEATURE_PIPELINING) { + msg_warn("non-LMTP response from %s: %.100s", + session->namaddr, STR(state->buffer)); + vstream_longjmp(session->stream, SMTP_ERR_PROTO); + } } if (three_digs != 0) rdata.code = atoi(STR(state->buffer)); diff --git a/postfix/src/lmtp/lmtp_trouble.c b/postfix/src/lmtp/lmtp_trouble.c index b9d1ce500..c58192ede 100644 --- a/postfix/src/lmtp/lmtp_trouble.c +++ b/postfix/src/lmtp/lmtp_trouble.c @@ -296,6 +296,10 @@ int lmtp_stream_except(LMTP_STATE *state, int code, char *description) vstring_sprintf(why, "conversation with %s timed out while %s", session->namaddr, description); break; + case SMTP_ERR_PROTO: + vstring_sprintf(why, "remote protocol error in reply from %s while %s", + session->namaddr, description); + break; } /* diff --git a/postfix/src/oqmgr/qmgr_deliver.c b/postfix/src/oqmgr/qmgr_deliver.c index 058aa8a55..8b724b1ec 100644 --- a/postfix/src/oqmgr/qmgr_deliver.c +++ b/postfix/src/oqmgr/qmgr_deliver.c @@ -210,6 +210,8 @@ static void qmgr_deliver_update(int unused_event, char *context) QMGR_MESSAGE *message = entry->message; VSTRING *reason = vstring_alloc(1); int status; + QMGR_RCPT *recipient; + int nrcpt; /* * The message transport has responded. Stop the watchdog timer. @@ -239,6 +241,21 @@ static void qmgr_deliver_update(int unused_event, char *context) qmgr_transport_throttle(transport, "unknown mail transport error"); msg_warn("transport %s failure -- see a previous warning/fatal/panic logfile record for the problem description", transport->name); + + /* + * Assume the worst and write a defer logfile record for each + * recipient. This omission was already present in the first queue + * manager implementation of 199703, and was fixed 200511. + * + * Don't move this queue entry back to the todo queue so that + * qmgr_defer_transport() can update the defer log. The queue entry + * is still hot, and making it cold would involve duplicating most + * but not all code at the end of this routine. That's too tricky. + */ + for (nrcpt = 0; nrcpt < entry->rcpt_list.len; nrcpt++) { + recipient = entry->rcpt_list.info + nrcpt; + qmgr_defer_recipient(message, recipient, transport->reason); + } qmgr_defer_transport(transport, transport->reason); } @@ -264,7 +281,7 @@ static void qmgr_deliver_update(int unused_event, char *context) * No problems detected. Mark the transport and queue as alive. The queue * itself won't go away before we dispose of the current queue entry. */ - if (VSTRING_LEN(reason) == 0) { + if (status != DELIVER_STAT_CRASH && VSTRING_LEN(reason) == 0) { qmgr_transport_unthrottle(transport); qmgr_queue_unthrottle(queue); } diff --git a/postfix/src/pickup/pickup.c b/postfix/src/pickup/pickup.c index 2272a3c74..6f73c5579 100644 --- a/postfix/src/pickup/pickup.c +++ b/postfix/src/pickup/pickup.c @@ -230,9 +230,25 @@ static int copy_segment(VSTREAM *qfile, VSTREAM *cleanup, PICKUP_INFO *info, * XXX Workaround: REC_TYPE_FILT (used in envelopes) == REC_TYPE_CONT * (used in message content). */ - if (type == REC_TYPE_FILT && *expected != REC_TYPE_CONTENT[0]) - /* Use our own content filter settings instead. */ - continue; + if (*expected != REC_TYPE_CONTENT[0]) { + if (type == REC_TYPE_FILT) + /* Discard FILTER record after "postsuper -r". */ + continue; + if (type == REC_TYPE_RDR) + /* Discard REDIRECT record after "postsuper -r". */ + continue; + } + if (*expected == REC_TYPE_EXTRACT[0]) { + if (type == REC_TYPE_RRTO) + /* Discard return-receipt record after "postsuper -r". */ + continue; + if (type == REC_TYPE_ERTO) + /* Discard errors-to record after "postsuper -r". */ + continue; + if (type == REC_TYPE_ATTR) + /* Discard other/header/body action after "postsuper -r". */ + continue; + } /* * XXX Force an empty record when the queue file content begins with diff --git a/postfix/src/qmgr/qmgr_deliver.c b/postfix/src/qmgr/qmgr_deliver.c index 28463a0e6..e92872b37 100644 --- a/postfix/src/qmgr/qmgr_deliver.c +++ b/postfix/src/qmgr/qmgr_deliver.c @@ -215,6 +215,8 @@ static void qmgr_deliver_update(int unused_event, char *context) QMGR_MESSAGE *message = entry->message; VSTRING *reason = vstring_alloc(1); int status; + QMGR_RCPT *recipient; + int nrcpt; /* * The message transport has responded. Stop the watchdog timer. @@ -244,6 +246,21 @@ static void qmgr_deliver_update(int unused_event, char *context) qmgr_transport_throttle(transport, "unknown mail transport error"); msg_warn("transport %s failure -- see a previous warning/fatal/panic logfile record for the problem description", transport->name); + + /* + * Assume the worst and write a defer logfile record for each + * recipient. This omission was already present in the first queue + * manager implementation of 199703, and was fixed 200511. + * + * Don't move this queue entry back to the todo queue so that + * qmgr_defer_transport() can update the defer log. The queue entry + * is still hot, and making it cold would involve duplicating most + * but not all code at the end of this routine. That's too tricky. + */ + for (nrcpt = 0; nrcpt < entry->rcpt_list.len; nrcpt++) { + recipient = entry->rcpt_list.info + nrcpt; + qmgr_defer_recipient(message, recipient, transport->reason); + } qmgr_defer_transport(transport, transport->reason); } @@ -269,7 +286,7 @@ static void qmgr_deliver_update(int unused_event, char *context) * No problems detected. Mark the transport and queue as alive. The queue * itself won't go away before we dispose of the current queue entry. */ - if (VSTRING_LEN(reason) == 0) { + if (status != DELIVER_STAT_CRASH && VSTRING_LEN(reason) == 0) { qmgr_transport_unthrottle(transport); qmgr_queue_unthrottle(queue); } diff --git a/postfix/src/smtp/smtp_chat.c b/postfix/src/smtp/smtp_chat.c index 2270f7741..db694c062 100644 --- a/postfix/src/smtp/smtp_chat.c +++ b/postfix/src/smtp/smtp_chat.c @@ -245,7 +245,21 @@ SMTP_RESP *smtp_chat_resp(SMTP_SESSION *session) if (*cp == ' ' || *cp == 0) break; } + + /* + * XXX Do not ignore garbage when ESMTP command pipelining is turned + * on. After sending ".QUIT", Postfix might recognize + * the server's 2XX QUIT reply as a 2XX END-OF-DATA reply after + * garbage, causing mail to be lost. Instead, make a long jump so + * that all recipients of multi-recipient mail get consistent + * treatment. + */ session->error_mask |= MAIL_ERROR_PROTOCOL; + if (session->features & SMTP_FEATURE_PIPELINING) { + msg_warn("non-SMTP response from %s: %s", + session->namaddr, STR(session->buffer)); + vstream_longjmp(session->stream, SMTP_ERR_PROTO); + } } if (three_digs != 0) rdata.code = atoi(STR(session->buffer)); diff --git a/postfix/src/smtp/smtp_connect.c b/postfix/src/smtp/smtp_connect.c index 24474ca06..1fcae1f2f 100644 --- a/postfix/src/smtp/smtp_connect.c +++ b/postfix/src/smtp/smtp_connect.c @@ -358,12 +358,36 @@ static void smtp_cleanup_session(SMTP_STATE *state) * XXX Should not cache TLS sessions unless we are using a single-session, * in-process, cache. And if we did, we should passivate VSTREAM objects * in addition to passivating SMTP_SESSION objects. + * + * XXX Workaround. If this host spoke TLS, connection caching was already + * turned off for this session by smtp_tls_start(). However, this alone + * does not distinguish between "good TLS connection" and "bad + * connection". + * + * In the case of "bad connection" to a primary host we want to store the + * first good alternate connection under the logical next-hop destination + * name name. In the case of a good primary TLS connection that would not + * make sense: the Postfix cache would prefer non-TLS secondary hosts + * over TLS-enabled primary hosts! + * + * The real fix is to have three-valued connection caching state: "do + * cache", "don't cache", and "bad connection", but that involves more + * change than is allowed in a stable release. + * + * To distinguish good TLS connections from bad connections we reset the + * logical next-hop state, so that we won't cache connections to + * less-preferred MX hosts under the logical next-hop destination. */ if (session->reuse_count > 0) { smtp_save_session(state); if (HAVE_NEXTHOP_STATE(state)) FREE_NEXTHOP_STATE(state); } else { +#ifdef USE_TLS + if (session->tls_context) + if (HAVE_NEXTHOP_STATE(state)) + FREE_NEXTHOP_STATE(state); +#endif smtp_session_free(session); } state->session = 0; diff --git a/postfix/src/smtp/smtp_trouble.c b/postfix/src/smtp/smtp_trouble.c index 1d8ba27e3..23f49c5ca 100644 --- a/postfix/src/smtp/smtp_trouble.c +++ b/postfix/src/smtp/smtp_trouble.c @@ -386,6 +386,10 @@ int smtp_stream_except(SMTP_STATE *state, int code, char *description) vstring_sprintf(why, "conversation with %s timed out while %s", session->namaddr, description); break; + case SMTP_ERR_PROTO: + vstring_sprintf(why, "remote protocol error in reply from %s while %s", + session->namaddr, description); + break; } /* diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 756a4cd93..8d02bd3cf 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -1493,8 +1493,9 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) && anvil_clnt_mail(anvil_clnt, state->service, state->addr, &rate) == ANVIL_STAT_OK && rate > var_smtpd_cmail_limit) { - smtpd_chat_reply(state, "421 %s Error: too much mail from %s", - var_myhostname, state->addr); + state->error_mask |= MAIL_ERROR_POLICY; + smtpd_chat_reply(state, "450 Error: too much mail from %s", + state->addr); msg_warn("Message delivery request rate limit exceeded: %d from %s for service %s", rate, state->namaddr, state->service); return (-1); @@ -1702,8 +1703,9 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) && anvil_clnt_rcpt(anvil_clnt, state->service, state->addr, &rate) == ANVIL_STAT_OK && rate > var_smtpd_crcpt_limit) { - smtpd_chat_reply(state, "421 %s Error: too many recipients from %s", - var_myhostname, state->addr); + state->error_mask |= MAIL_ERROR_POLICY; + smtpd_chat_reply(state, "450 Error: too many recipients from %s", + state->addr); msg_warn("Recipient address rate limit exceeded: %d from %s for service %s", rate, state->namaddr, state->service); return (-1); @@ -1919,17 +1921,13 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) /* * Flush out any access table actions that are delegated to the cleanup * server, and that may trigger before we accept the first valid - * recipient. + * recipient. There will be more after end-of-data. * * Terminate the message envelope segment. Start the message content * segment, and prepend our own Received: header. If there is only one * recipient, list the recipient address. */ if (state->cleanup) { - if (state->saved_filter) - rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", state->saved_filter); - if (state->saved_redirect) - rec_fprintf(state->cleanup, REC_TYPE_RDR, "%s", state->saved_redirect); if (state->saved_flags) rec_fprintf(state->cleanup, REC_TYPE_FLGS, "%d", state->saved_flags); rec_fputs(state->cleanup, REC_TYPE_MESG, ""); @@ -2042,13 +2040,18 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) if (prev_rec_type != REC_TYPE_CONT && *start == '.' && (state->proxy == 0 ? (++start, --len) == 0 : len == 1)) break; - state->act_size += len + 2; - if (state->err == CLEANUP_STAT_OK - && out_record(out_stream, curr_rec_type, start, len) < 0) - state->err = out_error; + if (state->err == CLEANUP_STAT_OK) { + state->act_size += len + 2; + if (var_message_limit > 0 && state->act_size > var_message_limit) + state->err = CLEANUP_STAT_SIZE; + else if (out_record(out_stream, curr_rec_type, start, len) < 0) + state->err = out_error; + } } state->where = SMTPD_AFTER_DOT; - if (SMTPD_STAND_ALONE(state) == 0 && (err = smtpd_check_eod(state)) != 0) { + if (state->err == CLEANUP_STAT_OK + && SMTPD_STAND_ALONE(state) == 0 + && (err = smtpd_check_eod(state)) != 0) { smtpd_chat_reply(state, "%s", err); if (state->proxy) { smtpd_proxy_close(state); @@ -2074,8 +2077,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) if (state->err == CLEANUP_STAT_OK && *STR(state->proxy_buffer) != '2') state->err = CLEANUP_STAT_CONT; - } else { - state->error_mask |= MAIL_ERROR_SOFTWARE; + } else if (state->err != CLEANUP_STAT_SIZE) { state->err |= CLEANUP_STAT_PROXY; vstring_sprintf(state->proxy_buffer, "451 Error: queue file write error"); @@ -2083,13 +2085,28 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) } /* - * Send the end-of-segment markers and finish the queue file record - * stream. + * Flush out access table actions that are delegated to the cleanup + * server. There is similar code at the beginning of the DATA command. + * + * Send the end-of-segment markers and finish the queue file record stream. */ else { + if (state->err == CLEANUP_STAT_OK) { + rec_fputs(state->cleanup, REC_TYPE_XTRA, ""); + if (state->saved_filter) + rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", + state->saved_filter); + if (state->saved_redirect) + rec_fprintf(state->cleanup, REC_TYPE_RDR, "%s", + state->saved_redirect); + if (state->saved_flags) + rec_fprintf(state->cleanup, REC_TYPE_FLGS, "%d", + state->saved_flags); + if (vstream_ferror(state->cleanup)) + state->err = CLEANUP_STAT_WRITE; + } if (state->err == CLEANUP_STAT_OK) - if (rec_fputs(state->cleanup, REC_TYPE_XTRA, "") < 0 - || rec_fputs(state->cleanup, REC_TYPE_END, "") < 0 + if (rec_fputs(state->cleanup, REC_TYPE_END, "") < 0 || vstream_fflush(state->cleanup)) state->err = CLEANUP_STAT_WRITE; if (state->err == 0) { @@ -2979,6 +2996,7 @@ static void smtpd_proto(SMTPD_STATE *state, const char *service) && anvil_clnt_connect(anvil_clnt, service, state->addr, &count, &crate) == ANVIL_STAT_OK) { if (var_smtpd_cconn_limit > 0 && count > var_smtpd_cconn_limit) { + state->error_mask |= MAIL_ERROR_POLICY; smtpd_chat_reply(state, "421 %s Error: too many connections from %s", var_myhostname, state->addr); msg_warn("Connection concurrency limit exceeded: %d from %s for service %s", diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index 5e59e2b9c..4d57edcc5 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -1748,6 +1748,15 @@ static int can_delegate_action(SMTPD_STATE *state, const char *table, table, VAR_SMTPD_PROXY_FILT, action); return (0); } + + /* + * ETRN does not receive mail so we can't store queue file records. + */ + if (strcmp(state->where, "ETRN") == 0) { + msg_warn("access table %s: action %s is unavailable in %s", + table, action, VAR_ETRN_CHECKS); + return (0); + } return (not_in_client_helo(state, table, action, reply_class)); } @@ -1955,6 +1964,11 @@ static int check_table_result(SMTPD_STATE *state, const char *table, if (not_in_client_helo(state, table, "PREPEND", reply_class) == 0) return (SMTPD_CHECK_DUNNO); #endif + if (strcmp(state->where, SMTPD_AFTER_DOT) == 0) { + msg_warn("access table %s: action PREPEND must be used before %s", + table, VAR_EOD_CHECKS); + return (SMTPD_CHECK_DUNNO); + } if (*cmd_text == 0 || is_header(cmd_text) == 0) { msg_warn("access map %s entry \"%s\" requires header: text", table, datum); diff --git a/postfix/src/tls/tls_misc.c b/postfix/src/tls/tls_misc.c index 03976abc7..e0a1b15d3 100644 --- a/postfix/src/tls/tls_misc.c +++ b/postfix/src/tls/tls_misc.c @@ -227,4 +227,11 @@ long tls_bio_dump_cb(BIO *bio, int cmd, const char *argp, int argi, return (ret); } +#else + + /* + * Broken linker workaround. + */ +int tls_dummy_for_broken_linkers; + #endif diff --git a/postfix/src/util/sane_accept.c b/postfix/src/util/sane_accept.c index 30a3d8533..a4560c2c5 100644 --- a/postfix/src/util/sane_accept.c +++ b/postfix/src/util/sane_accept.c @@ -59,6 +59,9 @@ int sane_accept(int sock, struct sockaddr * sa, SOCKADDR_SIZE *len) EWOULDBLOCK, ENOBUFS, /* HPUX11 */ ECONNABORTED, +#ifdef EPROTO + EPROTO, /* SunOS 5.5.1 */ +#endif 0, }; int count; @@ -71,6 +74,10 @@ int sane_accept(int sock, struct sockaddr * sa, SOCKADDR_SIZE *len) * hosed beyond recovery. There is no point treating this as a beneficial * error result because the program would go into a tight loop. * + * XXX Solaris 2.5.1 accept() returns EPROTO when a TCP client has + * disconnected in the mean time. Since there is no connection, it is + * safe to map the error code onto EAGAIN. + * * XXX LINUX < 2.1 accept() wakes up before the three-way handshake is * complete, so it can fail with ECONNRESET and other "false alarm" * indications. diff --git a/postfix/src/util/sys_defs.h b/postfix/src/util/sys_defs.h index c358db320..4bddae410 100644 --- a/postfix/src/util/sys_defs.h +++ b/postfix/src/util/sys_defs.h @@ -50,7 +50,7 @@ #endif #define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0) #define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin" -#if (defined(__NetBSD_Version__) && __NetBSD_Version__ > 200040000) +#if (defined(__NetBSD_Version__) && __NetBSD_Version__ > 299000900) # define USE_STATVFS # define STATVFS_IN_SYS_STATVFS_H #else @@ -122,7 +122,7 @@ #define SOCKOPT_SIZE socklen_t #endif -#if __NetBSD_Version__ >= 200060000 /* 2.0F */ +#if __NetBSD_Version__ >= 299000900 /* 2.99.9 */ #define HAS_CLOSEFROM #endif @@ -155,6 +155,7 @@ #define DEF_DB_TYPE "hash" #define ALIAS_DB_MAP "hash:/etc/aliases" #define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0) +#define RESOLVE_H_NEEDS_NAMESER8_COMPAT_H #define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin" #define USE_STATFS #define STATFS_IN_SYS_MOUNT_H