Prereq: "2.2.5" diff -cr /var/tmp/postfix-2.2.5/src/global/mail_version.h ./src/global/mail_version.h *** /var/tmp/postfix-2.2.5/src/global/mail_version.h Tue Jul 19 17:50:17 2005 --- ./src/global/mail_version.h Mon Nov 28 17:12:19 2005 *************** *** 20,27 **** * 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 VAR_MAIL_VERSION "mail_version" #ifdef SNAPSHOT --- 20,27 ---- * Patches change the patchlevel and the release date. Snapshots change the * release date only. */ ! #define MAIL_RELEASE_DATE "20051130" ! #define MAIL_VERSION_NUMBER "2.2.6" #define VAR_MAIL_VERSION "mail_version" #ifdef SNAPSHOT diff -cr /var/tmp/postfix-2.2.5/HISTORY ./HISTORY *** /var/tmp/postfix-2.2.5/HISTORY Tue Jul 19 19:19:19 2005 --- ./HISTORY Tue Nov 29 11:20:46 2005 *************** *** 10618,10628 **** 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. Portability: after sending a socket, the scache(8) server now waits for an ACK from the connection cache client before --- 10618,10628 ---- 20050706 ! 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,10641 **** --- 10639,10732 ---- 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 -cr /var/tmp/postfix-2.2.5/README_FILES/ADDRESS_REWRITING_README ./README_FILES/ADDRESS_REWRITING_README *** /var/tmp/postfix-2.2.5/README_FILES/ADDRESS_REWRITING_README Wed Mar 9 14:30:56 2005 --- ./README_FILES/ADDRESS_REWRITING_README Tue Nov 8 09:00:53 2005 *************** *** 367,373 **** /etc/postfix/master.cf: :10026 inet n - n - - smtpd ! -o receive_override_options=no_address_mapping Note: do not specify whitespace around the "=" here. --- 367,373 ---- /etc/postfix/master.cf: :10026 inet n - n - - smtpd ! -o receive_override_options=no_address_mappings Note: do not specify whitespace around the "=" here. *************** *** 440,446 **** /etc/postfix/master.cf: :10026 inet n - n - - smtpd ! -o receive_override_options=no_address_mapping Note: do not specify whitespace around the "=" here. --- 440,446 ---- /etc/postfix/master.cf: :10026 inet n - n - - smtpd ! -o receive_override_options=no_address_mappings Note: do not specify whitespace around the "=" here. *************** *** 476,482 **** /etc/postfix/master.cf: :10026 inet n - n - - smtpd ! -o receive_override_options=no_address_mapping Note: do not specify whitespace around the "=" here. --- 476,482 ---- /etc/postfix/master.cf: :10026 inet n - n - - smtpd ! -o receive_override_options=no_address_mappings Note: do not specify whitespace around the "=" here. *************** *** 525,531 **** /etc/postfix/master.cf: :10026 inet n - n - - smtpd ! -o receive_override_options=no_address_mapping Note: do not specify whitespace around the "=" here. --- 525,531 ---- /etc/postfix/master.cf: :10026 inet n - n - - smtpd ! -o receive_override_options=no_address_mappings Note: do not specify whitespace around the "=" here. diff -cr /var/tmp/postfix-2.2.5/README_FILES/MAILDROP_README ./README_FILES/MAILDROP_README *** /var/tmp/postfix-2.2.5/README_FILES/MAILDROP_README Sun Apr 11 17:05:33 2004 --- ./README_FILES/MAILDROP_README Wed Jul 20 17:07:57 2005 *************** *** 100,106 **** local(8) delivery agent's mailbox_command_maps feature: /etc/postfix/main.cf: ! mailbox_command_maps = /etc/postfix/mailbox_commands /etc/postfix/mailbox_commands: you /path/to/maildrop -d ${USER} --- 100,106 ---- local(8) delivery agent's mailbox_command_maps feature: /etc/postfix/main.cf: ! mailbox_command_maps = hash:/etc/postfix/mailbox_commands /etc/postfix/mailbox_commands: you /path/to/maildrop -d ${USER} diff -cr /var/tmp/postfix-2.2.5/README_FILES/TLS_README ./README_FILES/TLS_README *** /var/tmp/postfix-2.2.5/README_FILES/TLS_README Tue Feb 8 11:21:23 2005 --- ./README_FILES/TLS_README Sat Oct 29 18:34:25 2005 *************** *** 154,162 **** 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 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). --- 154,162 ---- 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_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,198 **** 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 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 --- 192,198 ---- jail. When you configure Postfix to request client certificates (by 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 to choose an identity signed by any CA. Many clients use a diff -cr /var/tmp/postfix-2.2.5/conf/access ./conf/access *** /var/tmp/postfix-2.2.5/conf/access Fri Feb 4 18:48:43 2005 --- ./conf/access Mon Nov 28 17:35:02 2005 *************** *** 1,4 **** ! # ACCESS(5) ACCESS(5) # # NAME # access - Postfix access table format --- 1,4 ---- ! # ACCESS(5) ACCESS(5) # # NAME # access - Postfix access table format *************** *** 263,268 **** --- 263,272 ---- # 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,304 **** # 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 # string. # # Actions are the same as with indexed file lookups, with --- 301,308 ---- # 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 ta- ! # ble, until a pattern is found that matches the search # string. # # Actions are the same as with indexed file lookups, with *************** *** 308,316 **** # 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. # # Each lookup operation uses the entire query string once. # Depending on the application, that string is an entire --- 312,320 ---- # 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_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,370 **** # P.O. Box 704 # Yorktown Heights, NY 10598, USA # ! # ACCESS(5) --- 371,374 ---- # P.O. Box 704 # Yorktown Heights, NY 10598, USA # ! # ACCESS(5) diff -cr /var/tmp/postfix-2.2.5/html/ADDRESS_REWRITING_README.html ./html/ADDRESS_REWRITING_README.html *** /var/tmp/postfix-2.2.5/html/ADDRESS_REWRITING_README.html Wed Mar 9 14:30:56 2005 --- ./html/ADDRESS_REWRITING_README.html Tue Nov 8 09:00:53 2005 *************** *** 603,609 ****
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mapping
  
--- 603,609 ----
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mappings
  
*************** *** 702,708 ****
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mapping
  
--- 702,708 ----
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mappings
  
*************** *** 752,758 ****
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mapping
  
--- 752,758 ----
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mappings
  
*************** *** 816,822 ****
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mapping
  
--- 816,822 ----
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mappings
  
diff -cr /var/tmp/postfix-2.2.5/html/MAILDROP_README.html ./html/MAILDROP_README.html *** /var/tmp/postfix-2.2.5/html/MAILDROP_README.html Tue Feb 22 09:05:36 2005 --- ./html/MAILDROP_README.html Wed Jul 20 17:07:57 2005 *************** *** 149,155 ****
  /etc/postfix/main.cf:
!     mailbox_command_maps = /etc/postfix/mailbox_commands
  
  /etc/postfix/mailbox_commands:
      you    /path/to/maildrop -d ${USER}
--- 149,155 ----
  
  /etc/postfix/main.cf:
!     mailbox_command_maps = hash:/etc/postfix/mailbox_commands
  
  /etc/postfix/mailbox_commands:
      you    /path/to/maildrop -d ${USER}
diff -cr /var/tmp/postfix-2.2.5/html/TLS_README.html ./html/TLS_README.html
*** /var/tmp/postfix-2.2.5/html/TLS_README.html	Tue Feb 22 09:05:37 2005
--- ./html/TLS_README.html	Sat Oct 29 18:34:25 2005
***************
*** 262,268 ****
  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 intermediary CAs need to
--- 262,268 ----
  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_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,321 ****
  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 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 --- 315,321 ---- accessible inside the optional chroot jail.

When you configure Postfix to request client certificates (by ! 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 -cr /var/tmp/postfix-2.2.5/html/access.5.html ./html/access.5.html *** /var/tmp/postfix-2.2.5/html/access.5.html Tue Feb 22 09:05:46 2005 --- ./html/access.5.html Mon Nov 28 17:35:02 2005 *************** *** 269,274 **** --- 269,278 ---- 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 -cr /var/tmp/postfix-2.2.5/man/man5/access.5 ./man/man5/access.5 *** /var/tmp/postfix-2.2.5/man/man5/access.5 Fri Feb 4 18:50:56 2005 --- ./man/man5/access.5 Mon Nov 28 17:35:02 2005 *************** *** 246,251 **** --- 246,254 ---- .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 -cr /var/tmp/postfix-2.2.5/proto/ADDRESS_REWRITING_README.html ./proto/ADDRESS_REWRITING_README.html *** /var/tmp/postfix-2.2.5/proto/ADDRESS_REWRITING_README.html Wed Mar 9 14:30:54 2005 --- ./proto/ADDRESS_REWRITING_README.html Tue Nov 8 09:00:45 2005 *************** *** 603,609 ****

  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mapping
  
--- 603,609 ----
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mappings
  
*************** *** 702,708 ****
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mapping
  
--- 702,708 ----
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mappings
  
*************** *** 752,758 ****
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mapping
  
--- 752,758 ----
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mappings
  
*************** *** 816,822 ****
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mapping
  
--- 816,822 ----
  /etc/postfix/master.cf:
      :10026      inet  n       -       n       -       -       smtpd
!         -o receive_override_options=no_address_mappings
  
diff -cr /var/tmp/postfix-2.2.5/proto/MAILDROP_README.html ./proto/MAILDROP_README.html *** /var/tmp/postfix-2.2.5/proto/MAILDROP_README.html Fri Apr 9 13:53:13 2004 --- ./proto/MAILDROP_README.html Wed Jul 20 17:07:47 2005 *************** *** 149,155 ****
  /etc/postfix/main.cf:
!     mailbox_command_maps = /etc/postfix/mailbox_commands
  
  /etc/postfix/mailbox_commands:
      you    /path/to/maildrop -d ${USER}
--- 149,155 ----
  
  /etc/postfix/main.cf:
!     mailbox_command_maps = hash:/etc/postfix/mailbox_commands
  
  /etc/postfix/mailbox_commands:
      you    /path/to/maildrop -d ${USER}
diff -cr /var/tmp/postfix-2.2.5/proto/TLS_README.html ./proto/TLS_README.html
*** /var/tmp/postfix-2.2.5/proto/TLS_README.html	Tue Feb  8 11:20:06 2005
--- ./proto/TLS_README.html	Sat Oct 29 18:34:16 2005
***************
*** 262,268 ****
  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 intermediary CAs need to
--- 262,268 ----
  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_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,321 ****
  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 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 --- 315,321 ---- accessible inside the optional chroot jail.

When you configure Postfix to request client certificates (by ! 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 -cr /var/tmp/postfix-2.2.5/proto/access ./proto/access *** /var/tmp/postfix-2.2.5/proto/access Fri Feb 4 18:39:19 2005 --- ./proto/access Mon Nov 28 17:22:25 2005 *************** *** 226,231 **** --- 226,234 ---- # .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 -cr /var/tmp/postfix-2.2.5/src/cleanup/cleanup_extracted.c ./src/cleanup/cleanup_extracted.c *** /var/tmp/postfix-2.2.5/src/cleanup/cleanup_extracted.c Thu Jun 5 13:56:52 2003 --- ./src/cleanup/cleanup_extracted.c Mon Nov 28 16:40:46 2005 *************** *** 95,108 **** 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, ! }; if (msg_verbose) msg_info("extracted envelope %c %.*s", type, len, buf); if (strchr(REC_TYPE_EXTRACT, type) == 0) { msg_warn("%s: message rejected: " "unexpected record type %d in extracted envelope", --- 95,116 ---- const char *buf, int len) { const char *encoding; ! 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,192 **** 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_extracted_finish - process one extracted envelope record */ --- 187,194 ---- 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; ! cleanup_out(state, type, buf, len); ! return; } /* cleanup_extracted_finish - process one extracted envelope record */ diff -cr /var/tmp/postfix-2.2.5/src/cleanup/cleanup_message.c ./src/cleanup/cleanup_message.c *** /var/tmp/postfix-2.2.5/src/cleanup/cleanup_message.c Wed Mar 30 09:21:31 2005 --- ./src/cleanup/cleanup_message.c Sat Nov 26 20:48:44 2005 *************** *** 564,569 **** --- 564,570 ---- 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,582 **** * * XXX It is the queue ID non-inode bits that prevent messages from getting * the same Message-Id within the same second. */ if ((state->headers_seen & (1 << (state->resent[0] ? HDR_RESENT_MESSAGE_ID : HDR_MESSAGE_ID))) == 0) { ! tp = gmtime(&state->time); 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); --- 574,590 ---- * * 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) { ! 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 -cr /var/tmp/postfix-2.2.5/src/dns/dns.h ./src/dns/dns.h *** /var/tmp/postfix-2.2.5/src/dns/dns.h Tue Jan 18 20:22:00 2005 --- ./src/dns/dns.h Tue Nov 15 09:46:27 2005 *************** *** 19,24 **** --- 19,27 ---- #ifdef RESOLVE_H_NEEDS_STDIO_H #include #endif + #ifdef RESOLVE_H_NEEDS_NAMESER8_COMPAT_H + #include + #endif #include /* diff -cr /var/tmp/postfix-2.2.5/src/global/dict_mysql.c ./src/global/dict_mysql.c *** /var/tmp/postfix-2.2.5/src/global/dict_mysql.c Tue Mar 8 13:58:45 2005 --- ./src/global/dict_mysql.c Thu Sep 22 11:45:34 2005 *************** *** 393,404 **** } 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; for (i = 0; i < PLDB->len_hosts; i++) { if (dict_mysql_check_stat(PLDB->db_hosts[i], stat, type, t) && --- 393,400 ---- } if (count) { ! 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 -cr /var/tmp/postfix-2.2.5/src/global/dict_pgsql.c ./src/global/dict_pgsql.c *** /var/tmp/postfix-2.2.5/src/global/dict_pgsql.c Mon May 23 17:09:42 2005 --- ./src/global/dict_pgsql.c Thu Sep 22 11:45:11 2005 *************** *** 388,399 **** } 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; for (i = 0; i < PLDB->len_hosts; i++) { if (dict_pgsql_check_stat(PLDB->db_hosts[i], stat, type, t) && --- 388,395 ---- } if (count) { ! 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 -cr /var/tmp/postfix-2.2.5/src/global/mail_queue.c ./src/global/mail_queue.c *** /var/tmp/postfix-2.2.5/src/global/mail_queue.c Mon Dec 15 12:44:48 2003 --- ./src/global/mail_queue.c Sat Nov 26 20:53:25 2005 *************** *** 6,14 **** /* SYNOPSIS /* #include /* ! /* VSTREAM *mail_queue_enter(queue_name, mode) /* const char *queue_name; /* int mode; /* /* VSTREAM *mail_queue_open(queue_name, queue_id, flags, mode) /* const char *queue_name; --- 6,15 ---- /* SYNOPSIS /* #include /* ! /* 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,59 **** /* 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. /* /* mail_queue_open() opens the named queue file. The \fIflags\fR /* and \fImode\fR arguments are as with open(2). The result is a --- 54,62 ---- /* 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. 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,310 **** /* mail_queue_enter - make mail queue entry with locally-unique name */ ! VSTREAM *mail_queue_enter(const char *queue_name, int mode) { char *myname = "mail_queue_enter"; static VSTRING *id_buf; --- 307,314 ---- /* mail_queue_enter - make mail queue entry with locally-unique name */ ! VSTREAM *mail_queue_enter(const char *queue_name, int mode, ! struct timeval * tp) { char *myname = "mail_queue_enter"; static VSTRING *id_buf; *************** *** 326,332 **** path_buf = vstring_alloc(10); temp_path = vstring_alloc(100); } ! GETTIMEOFDAY(&tv); /* * Create a file with a temporary name that does not collide. The process --- 330,337 ---- path_buf = vstring_alloc(10); temp_path = vstring_alloc(100); } ! if (tp == 0) ! tp = &tv; /* * Create a file with a temporary name that does not collide. The process *************** *** 338,350 **** * If someone is racing against us, try to win. */ for (;;) { vstring_sprintf(temp_path, "%s/%d.%d", queue_name, ! (int) tv.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)); --- 343,354 ---- * If someone is racing against us, try to win. */ for (;;) { + GETTIMEOFDAY(tp); vstring_sprintf(temp_path, "%s/%d.%d", queue_name, ! (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) { continue; } msg_warn("%s: create file %s: %m", myname, STR(temp_path)); *************** *** 364,370 **** * 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 --- 368,373 ---- *************** *** 374,393 **** * 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); 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) { --- 377,388 ---- * prevents multiple messages from getting the same Message-ID value. */ for (count = 0;; count++) { ! 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 (sane_rename(STR(temp_path), STR(path_buf)) == 0) /* success */ break; if (errno == EPERM || errno == EISDIR) {/* collision. weird. */ continue; } if (errno != ENOENT || mail_queue_mkdirs(STR(path_buf)) < 0) { diff -cr /var/tmp/postfix-2.2.5/src/global/mail_queue.h ./src/global/mail_queue.h *** /var/tmp/postfix-2.2.5/src/global/mail_queue.h Sat Nov 16 18:04:30 2002 --- ./src/global/mail_queue.h Sat Nov 26 20:43:21 2005 *************** *** 12,17 **** --- 12,22 ---- /* .nf /* + * System library. + */ + #include + + /* * Utility library. */ #include *************** *** 37,43 **** #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_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 *); --- 42,48 ---- #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, 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 -cr /var/tmp/postfix-2.2.5/src/global/mail_stream.c ./src/global/mail_stream.c *** /var/tmp/postfix-2.2.5/src/global/mail_stream.c Thu Jan 1 22:02:01 2004 --- ./src/global/mail_stream.c Sat Nov 26 20:45:29 2005 *************** *** 10,15 **** --- 10,16 ---- /* .in +4 /* VSTREAM *stream; /* char *id; + /* struct timeval ctime; /* private members... /* .in -4 /* } MAIL_STREAM; *************** *** 264,273 **** MAIL_STREAM *mail_stream_file(const char *queue, const char *class, const char *service, int mode) { MAIL_STREAM *info; VSTREAM *stream; ! stream = mail_queue_enter(queue, 0600 | mode); if (msg_verbose) msg_info("open %s", VSTREAM_PATH(stream)); --- 265,275 ---- 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, &tv); if (msg_verbose) msg_info("open %s", VSTREAM_PATH(stream)); *************** *** 280,285 **** --- 282,288 ---- info->class = mystrdup(class); info->service = mystrdup(service); info->mode = mode; + info->ctime = tv; return (info); } diff -cr /var/tmp/postfix-2.2.5/src/global/mail_stream.h ./src/global/mail_stream.h *** /var/tmp/postfix-2.2.5/src/global/mail_stream.h Tue Apr 15 14:04:43 2003 --- ./src/global/mail_stream.h Mon Nov 28 19:24:47 2005 *************** *** 12,17 **** --- 12,22 ---- /* .nf /* + * System library. + */ + #include + + /* * Utility library. */ #include *************** *** 34,39 **** --- 39,45 ---- 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 -cr /var/tmp/postfix-2.2.5/src/global/smtp_stream.h ./src/global/smtp_stream.h *** /var/tmp/postfix-2.2.5/src/global/smtp_stream.h Wed Dec 8 17:16:40 2004 --- ./src/global/smtp_stream.h Tue Nov 29 11:26:21 2005 *************** *** 28,33 **** --- 28,34 ---- */ #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 -cr /var/tmp/postfix-2.2.5/src/lmtp/lmtp_chat.c ./src/lmtp/lmtp_chat.c *** /var/tmp/postfix-2.2.5/src/lmtp/lmtp_chat.c Tue Mar 22 14:16:08 2005 --- ./src/lmtp/lmtp_chat.c Tue Nov 29 11:25:25 2005 *************** *** 222,228 **** --- 222,242 ---- 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 -cr /var/tmp/postfix-2.2.5/src/lmtp/lmtp_trouble.c ./src/lmtp/lmtp_trouble.c *** /var/tmp/postfix-2.2.5/src/lmtp/lmtp_trouble.c Mon Mar 28 11:13:32 2005 --- ./src/lmtp/lmtp_trouble.c Tue Nov 29 11:28:36 2005 *************** *** 296,301 **** --- 296,305 ---- 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 -cr /var/tmp/postfix-2.2.5/src/oqmgr/qmgr_deliver.c ./src/oqmgr/qmgr_deliver.c *** /var/tmp/postfix-2.2.5/src/oqmgr/qmgr_deliver.c Mon Oct 25 16:59:08 2004 --- ./src/oqmgr/qmgr_deliver.c Sat Nov 19 22:31:27 2005 *************** *** 210,215 **** --- 210,217 ---- 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,244 **** --- 241,261 ---- 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,270 **** * 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) { qmgr_transport_unthrottle(transport); qmgr_queue_unthrottle(queue); } --- 281,287 ---- * 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 (status != DELIVER_STAT_CRASH && VSTRING_LEN(reason) == 0) { qmgr_transport_unthrottle(transport); qmgr_queue_unthrottle(queue); } diff -cr /var/tmp/postfix-2.2.5/src/pickup/pickup.c ./src/pickup/pickup.c *** /var/tmp/postfix-2.2.5/src/pickup/pickup.c Fri Feb 4 15:44:06 2005 --- ./src/pickup/pickup.c Mon Nov 28 20:08:22 2005 *************** *** 230,238 **** * 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; /* * XXX Force an empty record when the queue file content begins with --- 230,254 ---- * XXX Workaround: REC_TYPE_FILT (used in envelopes) == REC_TYPE_CONT * (used in message content). */ ! 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 -cr /var/tmp/postfix-2.2.5/src/qmgr/qmgr_deliver.c ./src/qmgr/qmgr_deliver.c *** /var/tmp/postfix-2.2.5/src/qmgr/qmgr_deliver.c Mon Oct 25 16:59:09 2004 --- ./src/qmgr/qmgr_deliver.c Sat Nov 19 22:30:22 2005 *************** *** 215,220 **** --- 215,222 ---- 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,249 **** --- 246,266 ---- 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,275 **** * 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) { qmgr_transport_unthrottle(transport); qmgr_queue_unthrottle(queue); } --- 286,292 ---- * 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 (status != DELIVER_STAT_CRASH && VSTRING_LEN(reason) == 0) { qmgr_transport_unthrottle(transport); qmgr_queue_unthrottle(queue); } diff -cr /var/tmp/postfix-2.2.5/src/smtp/smtp_chat.c ./src/smtp/smtp_chat.c *** /var/tmp/postfix-2.2.5/src/smtp/smtp_chat.c Tue Mar 22 14:13:59 2005 --- ./src/smtp/smtp_chat.c Tue Nov 29 11:20:17 2005 *************** *** 245,251 **** --- 245,265 ---- 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 -cr /var/tmp/postfix-2.2.5/src/smtp/smtp_connect.c ./src/smtp/smtp_connect.c *** /var/tmp/postfix-2.2.5/src/smtp/smtp_connect.c Tue Jun 21 20:20:50 2005 --- ./src/smtp/smtp_connect.c Sat Nov 5 21:00:04 2005 *************** *** 358,369 **** --- 358,393 ---- * 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 -cr /var/tmp/postfix-2.2.5/src/smtp/smtp_trouble.c ./src/smtp/smtp_trouble.c *** /var/tmp/postfix-2.2.5/src/smtp/smtp_trouble.c Mon Mar 28 10:59:01 2005 --- ./src/smtp/smtp_trouble.c Tue Nov 29 11:28:41 2005 *************** *** 386,391 **** --- 386,395 ---- 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 -cr /var/tmp/postfix-2.2.5/src/smtpd/smtpd.c ./src/smtpd/smtpd.c *** /var/tmp/postfix-2.2.5/src/smtpd/smtpd.c Wed Mar 9 15:07:43 2005 --- ./src/smtpd/smtpd.c Mon Nov 28 17:32:41 2005 *************** *** 1493,1500 **** && 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); msg_warn("Message delivery request rate limit exceeded: %d from %s for service %s", rate, state->namaddr, state->service); return (-1); --- 1493,1501 ---- && anvil_clnt_mail(anvil_clnt, state->service, state->addr, &rate) == ANVIL_STAT_OK && rate > var_smtpd_cmail_limit) { ! 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,1709 **** && 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); msg_warn("Recipient address rate limit exceeded: %d from %s for service %s", rate, state->namaddr, state->service); return (-1); --- 1703,1711 ---- && anvil_clnt_rcpt(anvil_clnt, state->service, state->addr, &rate) == ANVIL_STAT_OK && rate > var_smtpd_crcpt_limit) { ! 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,1935 **** /* * Flush out any access table actions that are delegated to the cleanup * server, and that may trigger before we accept the first valid ! * recipient. * * 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, ""); --- 1921,1933 ---- /* * Flush out any access table actions that are delegated to the cleanup * server, and that may trigger before we accept the first valid ! * 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_flags) rec_fprintf(state->cleanup, REC_TYPE_FLGS, "%d", state->saved_flags); rec_fputs(state->cleanup, REC_TYPE_MESG, ""); *************** *** 2042,2054 **** 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; } state->where = SMTPD_AFTER_DOT; ! if (SMTPD_STAND_ALONE(state) == 0 && (err = smtpd_check_eod(state)) != 0) { smtpd_chat_reply(state, "%s", err); if (state->proxy) { smtpd_proxy_close(state); --- 2040,2057 ---- if (prev_rec_type != REC_TYPE_CONT && *start == '.' && (state->proxy == 0 ? (++start, --len) == 0 : len == 1)) break; ! 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 (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,2081 **** if (state->err == CLEANUP_STAT_OK && *STR(state->proxy_buffer) != '2') state->err = CLEANUP_STAT_CONT; ! } else { ! state->error_mask |= MAIL_ERROR_SOFTWARE; state->err |= CLEANUP_STAT_PROXY; vstring_sprintf(state->proxy_buffer, "451 Error: queue file write error"); --- 2077,2083 ---- if (state->err == CLEANUP_STAT_OK && *STR(state->proxy_buffer) != '2') state->err = CLEANUP_STAT_CONT; ! } else if (state->err != CLEANUP_STAT_SIZE) { state->err |= CLEANUP_STAT_PROXY; vstring_sprintf(state->proxy_buffer, "451 Error: queue file write error"); *************** *** 2083,2095 **** } /* ! * Send the end-of-segment markers and finish the queue file record ! * stream. */ else { if (state->err == CLEANUP_STAT_OK) ! if (rec_fputs(state->cleanup, REC_TYPE_XTRA, "") < 0 ! || rec_fputs(state->cleanup, REC_TYPE_END, "") < 0 || vstream_fflush(state->cleanup)) state->err = CLEANUP_STAT_WRITE; if (state->err == 0) { --- 2085,2112 ---- } /* ! * 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_END, "") < 0 || vstream_fflush(state->cleanup)) state->err = CLEANUP_STAT_WRITE; if (state->err == 0) { *************** *** 2979,2984 **** --- 2996,3002 ---- && 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 -cr /var/tmp/postfix-2.2.5/src/smtpd/smtpd_check.c ./src/smtpd/smtpd_check.c *** /var/tmp/postfix-2.2.5/src/smtpd/smtpd_check.c Fri Mar 4 20:13:10 2005 --- ./src/smtpd/smtpd_check.c Mon Nov 28 17:28:45 2005 *************** *** 1748,1753 **** --- 1748,1762 ---- 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,1960 **** --- 1964,1974 ---- 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 -cr /var/tmp/postfix-2.2.5/src/tls/tls_misc.c ./src/tls/tls_misc.c *** /var/tmp/postfix-2.2.5/src/tls/tls_misc.c Thu Mar 3 18:09:43 2005 --- ./src/tls/tls_misc.c Mon Aug 15 15:39:07 2005 *************** *** 227,230 **** --- 227,237 ---- return (ret); } + #else + + /* + * Broken linker workaround. + */ + int tls_dummy_for_broken_linkers; + #endif diff -cr /var/tmp/postfix-2.2.5/src/util/sane_accept.c ./src/util/sane_accept.c *** /var/tmp/postfix-2.2.5/src/util/sane_accept.c Fri Sep 12 19:52:21 2003 --- ./src/util/sane_accept.c Sat Aug 6 17:16:18 2005 *************** *** 59,64 **** --- 59,67 ---- EWOULDBLOCK, ENOBUFS, /* HPUX11 */ ECONNABORTED, + #ifdef EPROTO + EPROTO, /* SunOS 5.5.1 */ + #endif 0, }; int count; *************** *** 70,75 **** --- 73,82 ---- * disconnected in the mean time. From then on, UNIX-domain sockets are * 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" diff -cr /var/tmp/postfix-2.2.5/src/util/sys_defs.h ./src/util/sys_defs.h *** /var/tmp/postfix-2.2.5/src/util/sys_defs.h Mon Jul 11 16:00:38 2005 --- ./src/util/sys_defs.h Tue Nov 15 09:46:35 2005 *************** *** 50,56 **** #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) # define USE_STATVFS # define STATVFS_IN_SYS_STATVFS_H #else --- 50,56 ---- #endif #define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0) #define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin" ! #if (defined(__NetBSD_Version__) && __NetBSD_Version__ > 299000900) # define USE_STATVFS # define STATVFS_IN_SYS_STATVFS_H #else *************** *** 122,128 **** #define SOCKOPT_SIZE socklen_t #endif ! #if __NetBSD_Version__ >= 200060000 /* 2.0F */ #define HAS_CLOSEFROM #endif --- 122,128 ---- #define SOCKOPT_SIZE socklen_t #endif ! #if __NetBSD_Version__ >= 299000900 /* 2.99.9 */ #define HAS_CLOSEFROM #endif *************** *** 155,160 **** --- 155,161 ---- #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