From: Wietse Venema Date: Tue, 1 Jun 2010 05:00:00 +0000 (-0500) Subject: postfix-2.8-20100601 X-Git-Tag: v2.8.0-RC1~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b6f945a4ecf91ba2d23aefc55494d5777029723;p=thirdparty%2Fpostfix.git postfix-2.8-20100601 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 0dd53715b..90c996b0b 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -15754,3 +15754,69 @@ Apologies for any names omitted. Bugfix (introduced 20100305) the new smtp_address_preference feature was not tested with LMTP support. Problem reported by Stefan Foerster. File: smtp/smtp.c. + +20100407 + + Bugfix (introduced 20100305): reject_rhsbl_reverse_client + was skipped if the forward-confirmed reverse DNS (FCRDNS) + remote SMTP client hostname was "unknown". Victor Duchovni. + File: smtpd/smtpd_check.c. + +20100422 + + Workaround (introduced: postfix-19990906 a.k.a. Postfix + 0.8.0). The Postfix local delivery agent did not properly + distinguish between "address has no extension" and "address + has an extension, but the extension is invalid". In both + cases it would run only the full recipient local-part through + the alias maps. Instead, it now drops the faulty extension + from the recipient address local-part (it would be too + error-prone to replace all tests for "no extension" by tests + for "no valid extension". File: local/recipient.c. + +20100430 + + Feature: customized hard/soft reject responses by Jason + Parsons. File: smtpstone/smtp-sink.c. + +20100515 + + Bugfix (introduced Postfix 2.6): the Postfix SMTP client + XFORWARD implementation did not skip "unknown" SMTP client + attributes, causing a syntax error when sending a PORT + attribute. Reported by Victor Duchovni. File: smtp/smtp_proto.c. + +20100526 + + Cleanup: a unit-test driver was not updated after an internal + API change. Vesa-Matti J Kari File: milter/milter.c. + +20100529 + + Portability: OpenSSL 1.0.0 changes the priority of anonymous + cyphers. Victor Duchovni. Files: postconf.proto, + global/mail_params.h, tls/tls_certkey.c, tls/tls_client.c, + tls/tls_dh.c, tls/tls_server.c. + + Portability: Mac OS 10.6.3 requires + instead of . Files: makedefs, + util/sys_defs.h, dns/dns.h. + +20100531 + + Robustness: skip LDAP queries with non-UTF-8 search strings + (in anticipation of UTF8SMTP support). File: global/dict_ldap.c. + + Strict UTF-8 validator per RFC 3629. File: util/valid_utf_8.c. + +20100601 + + Feature: Postfix LDAP client support for RFC 2255 LDAP URLs. + Victor Duchovni. Files: proto/ldap_table global/dict_ldap.c. + + Safety: Postfix processes log a warning when a matchlist + has a #comment at the end of a line (for example mynetworks + or relay_domains). File: util/match_list.c. + + Portability: Berkeley DB 5.x has the same API as Berkeley + DB 4.1 and later. File: util/dict_db.c. diff --git a/postfix/README_FILES/BACKSCATTER_README b/postfix/README_FILES/BACKSCATTER_README index 7209a2072..90ac32a89 100644 --- a/postfix/README_FILES/BACKSCATTER_README +++ b/postfix/README_FILES/BACKSCATTER_README @@ -35,7 +35,8 @@ goes on and on like this: to= proto=ESMTP helo= What you see are lots of "user unknown" errors with "from=<>". These are error -reports from MAILER-DAEMONs elsewhere on the Internet. +reports from MAILER-DAEMONs elsewhere on the Internet, about email that was +sent with a false sender address in your domain. HHooww ddoo II bblloocckk bbaacckkssccaatttteerr mmaaiill ttoo rraannddoomm rreecciippiieenntt aaddddrreesssseess?? diff --git a/postfix/README_FILES/SASL_README b/postfix/README_FILES/SASL_README index 0b890cfff..193e787b4 100644 --- a/postfix/README_FILES/SASL_README +++ b/postfix/README_FILES/SASL_README @@ -26,10 +26,9 @@ can give it "same network" privileges. Postfix does not implement SASL itself, but instead uses existing implementations as building blocks. This means that some SASL-related -configuration will involve files that belong to Postfix, while other -configuration will involve files that belong to the specific SASL -implementation that Postfix will use. This document covers both the Postfix and -non-Postfix configuration. +configuration files will belong to Postfix, while other configuration files +belong to the specific SASL implementation that Postfix will use. This document +covers both the Postfix and non-Postfix configuration. You can read more about the following topics: @@ -901,6 +900,15 @@ Information sent by the client (that is, you) is shown in bboolldd font. AAUUTTHH PPLLAAIINN AAHHRRllcc33QQAAddGGVVzzddHHBBhhcc33MM== 235 Authentication successful +To test this over a connection that is encrypted with TLS, use openssl s_client +instead of telnet: + + % ooppeennssssll ss__cclliieenntt --ccoonnnneecctt sseerrvveerr..eexxaammppllee..ccoomm::2255 --ssttaarrttttllss ssmmttpp + ... + 220 server.example.com ESMTP Postfix + EEHHLLOO cclliieenntt..eexxaammppllee..ccoomm + ...see above example for more... + Instead of AHRlc3QAdGVzdHBhc3M=, specify the base64-encoded form of \0username\0password (the \0 is a null byte). The example above is for a user named `test' with password `testpass'. diff --git a/postfix/WISHLIST b/postfix/WISHLIST index 064ad644a..83ae66556 100644 --- a/postfix/WISHLIST +++ b/postfix/WISHLIST @@ -2,6 +2,16 @@ Wish list: Remove this file from the stable release. + When an alias is a member of an :include: list with owner- + alias, local(8) needs an option to deliver alias or alias->user + indirectly. What happens when an :include: list with owner- + alias includes another list? + + Don't allow empty result values in pcre and regexp maps. + Postfix doesn't allow them anywhere else (check this). + + Make PCRE_MAX_CAPTURE configurable. + Add some checks for tokens starting with #. A challenge is to report sensible context from the guts of some low-level parser, without introducing a great deal of clumsiness. @@ -12,8 +22,12 @@ Wish list: state->milter_reject_text when expanding {rcpt_addr} or {rcpt_host}. - Find out why post_mail() etc. block when the qmgr fifo - is full. This causes delays in the queue manager. + Find out why post_mail() etc. block when the qmgr fifo is + full (answer: trigger_timeout). How can this cause delays + in the queue manager? When a recipient bounces during + (transport, nexthop, address) resolution, it is redirected + to the error or retry mailer; and bounce-after-delivery is + asynchrounous so it can't block the queue manager, either. Add smtpd_sender_login_maps to proxy_read_maps, and make sure that defaults are set before proxy_read_maps is diff --git a/postfix/html/BACKSCATTER_README.html b/postfix/html/BACKSCATTER_README.html index 5c16db14e..7ab4ea1e4 100644 --- a/postfix/html/BACKSCATTER_README.html +++ b/postfix/html/BACKSCATTER_README.html @@ -76,7 +76,8 @@ to=<yyyyyy@your.domain.here> proto=ESMTP helo=<zzzzzz>

What you see are lots of "user unknown" errors with "from=<>". -These are error reports from MAILER-DAEMONs elsewhere on the Internet. +These are error reports from MAILER-DAEMONs elsewhere on the Internet, +about email that was sent with a false sender address in your domain.

How do I block backscatter mail to random diff --git a/postfix/html/SASL_README.html b/postfix/html/SASL_README.html index 25458d65a..07132e92d 100644 --- a/postfix/html/SASL_README.html +++ b/postfix/html/SASL_README.html @@ -42,8 +42,8 @@ SMTP server. Once a client is authenticated, a server can give it

Postfix does not implement SASL itself, but instead uses existing implementations as building blocks. This means that some SASL-related -configuration will involve files that belong to Postfix, while other -configuration will involve files that belong to the specific SASL +configuration files will belong to Postfix, while other +configuration files belong to the specific SASL implementation that Postfix will use. This document covers both the Postfix and non-Postfix configuration.

@@ -1460,6 +1460,19 @@ the client (that is, you) is shown in bold font. +

To test this over a connection that is encrypted with TLS, use +openssl s_client instead of telnet: + +

+
+% openssl s_client -connect server.example.com:25 -starttls smtp
+...
+220 server.example.com ESMTP Postfix
+EHLO client.example.com
+...see above example for more...
+
+
+

Instead of AHRlc3QAdGVzdHBhc3M=, specify the base64-encoded form of \0username\0password (the \0 is a null byte). The example above is for a user named `test' diff --git a/postfix/html/ldap_table.5.html b/postfix/html/ldap_table.5.html index 1c0e35f2c..1948ce898 100644 --- a/postfix/html/ldap_table.5.html +++ b/postfix/html/ldap_table.5.html @@ -344,21 +344,53 @@ LDAP_TABLE(5) LDAP_TABLE(5) result_attribute = mailbox, maildrop + Don't rely on the default value ("maildrop"). Set + the result_attribute explicitly in all ldap table + configuration files. This is particularly relevant + when no result_attribute is applicable, e.g. cases + in which leaf_result_attribute and/or termi- + nal_result_attribute are used instead. The default + value is harmless if "maildrop" is also listed as a + leaf or terminal result attribute, but it is best + to not leave this to chance. + special_result_attribute (default: empty) The attribute(s) of directory entries that can con- - tain DNs or URLs. If found, a recursive subsequent - search is done using their values. + tain DNs or RFC 2255 LDAP URLs. If found, a recur- + sive search is performed to retrieve the entry ref- + erenced by the DN, or the entries matched by the + URL query. special_result_attribute = memberdn DN recursion retrieves the same result_attributes as the main query, including the special attributes - for further recursion. URI processing retrieves - only those attributes that are included in the URI - definition and are *also* listed in - "result_attribute". If the URI lists any of the - map's special result attributes, these are also - retrieved and used recursively. + for further recursion. + + URL processing retrieves only those attributes that + are included in both the URL definition and as + result attributes (ordinary, special, leaf or ter- + minal) in the Postfix table definition. If the URL + lists any of the table's special result attributes, + these are retrieved and used recursively. A URL + that does not specify any attribute selection, is + equivalent (RFC 2255) to a URL that selects all + attributes, in which case the selected attributes + will be the full set of result attributes in the + Postfix table. + + If an LDAP URL attribute-descriptor or the corre- + sponding Postfix LDAP table result attribute (but + not both) uses RFC 2255 sub-type options + ("attr;option"), the attribute requested from the + LDAP server will include the sub-type option. In + all other cases, the URL attribute and the table + attribute must match exactly. Attributes with + options in both the URL and the Postfix table are + requested only when the options are identical. LDAP + attribute-descriptor options are very rarely used, + most LDAP users will not need to concern themselves + with this level of nuanced detail. terminal_result_attribute (default: empty) When one or more terminal result attributes are @@ -371,8 +403,15 @@ LDAP_TABLE(5) LDAP_TABLE(5) the group is expanded, possibly via mailing-list manager or other special processing. + result_attribute = terminal_result_attribute = maildrop + When using terminal and/or leaf result attributes, + the result_attribute is best set to an empty value + when it is not used, or else explicitly set to the + desired value, even if it is the default value + "maildrop". + This feature is available with Postfix 2.4 or later. @@ -404,6 +443,12 @@ LDAP_TABLE(5) LDAP_TABLE(5) terminal_result_attribute = maildrop leaf_result_attribute = mail + When using terminal and/or leaf result attributes, + the result_attribute is best set to an empty value + when it is not used, or else explicitly set to the + desired value, even if it is the default value + "maildrop". + This feature is available with Postfix 2.4 or later. diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index a41f426fb..7c7645ab8 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -274,7 +274,7 @@ This feature is available in Postfix 2.1 and later.

address_verify_poll_count -(default: ${stress?1}${stress:3})
+(default: normal: 3, overload: 1)

How many times to query the verify(8) service for the completion @@ -747,8 +747,8 @@ the sender.

Note: automatic BCC recipients are produced only for new mail. To avoid mailer loops, automatic BCC recipients are not generated -for mail that Postfix forwards internally, nor for mail that Postfix -generates itself.

+after Postfix forwards mail internally, or after Postfix generates +mail itself.

@@ -4439,7 +4439,7 @@ configuration parameter. See there for details.

parameter. See there for details.

This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

@@ -4451,7 +4451,7 @@ compiled and linked with OpenSSL 0.9.9 or later.

parameter. See there for details.

This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

@@ -6617,7 +6617,7 @@ reporting PREGREET, HANGUP or DNSBL results. -

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

@@ -6631,7 +6631,7 @@ parameter uses the same address syntax as the postscreen(8) server decisions.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

@@ -6680,7 +6680,7 @@ an hour ago.

Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

@@ -6698,7 +6698,7 @@ unit).

Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

@@ -6722,7 +6722,7 @@ parameter. Specify one of the following:

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

@@ -6765,7 +6765,7 @@ examining DNSBL lookup results.

In either case, postscreen(8) will not whitelist the SMTP client IP address.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

@@ -6780,7 +6780,7 @@ text..." response, in an attempt to confuse bad SMTP clients so that they speak before their turn (pre-greet). Specify an empty value to disable this feature.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

@@ -6798,7 +6798,7 @@ an optional one-letter suffix that specifies the time unit).

Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

@@ -6827,7 +6827,7 @@ results. -

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

@@ -6839,7 +6839,7 @@ results. real SMTP server process. When this queue is full, all clients will receive a 421 reponse.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

@@ -6852,7 +6852,7 @@ a decision whether they will receive service from a real SMTP server process. When this queue is full, all non-whitelisted clients will receive a 421 reponse.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

@@ -6865,7 +6865,7 @@ will not be subjected to postscreen(8) checks. T the same address syntax as the mynetworks parameter. This feature never uses the remote SMTP client hostname.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

@@ -7435,8 +7435,8 @@ the sender.

Note: automatic BCC recipients are produced only for new mail. To avoid mailer loops, automatic BCC recipients are not generated -for mail that Postfix forwards internally, nor for mail that Postfix -generates itself.

+after Postfix forwards mail internally, or after Postfix generates +mail itself.

Example: @@ -7990,8 +7990,8 @@ the sender.

Note: automatic BCC recipients are produced only for new mail. To avoid mailer loops, automatic BCC recipients are not generated -for mail that Postfix forwards internally, nor for mail that Postfix -generates itself.

+after Postfix forwards mail internally, or after Postfix generates +mail itself.

Example: @@ -9662,7 +9662,7 @@ This file may also contain the Postfix SMTP client ECDSA private key.

This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

@@ -9680,7 +9680,7 @@ access to the system superuser account ("root"), and no access to anyone else.

This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

@@ -11359,8 +11359,8 @@ except that initial whitespace and the trailing <CR><LF> are removed. The result value is executed by the Postfix SMTP server.

-

Postfix already implements a number of workarounds for malformed -client commands.

+

There is no need to use smtpd_command_filter for the following +cases:

    @@ -11368,15 +11368,18 @@ client commands.

    "user@ipaddress".

  • Postfix already accepts the correct form -"user@[ipaddress]".

    +"user@[ipaddress]". Use virtual_alias_maps or canonical_maps +to translate these into domain names if necessary.

    -
  • Use "strict_rfc821_envelopes = no" to accept "User Name -<user@example.com>". Postfix will ignore the "User Name" -part before delivering the mail.

    +
  • Use "strict_rfc821_envelopes = no" to accept "RCPT TO:<User +Name <user@example.com>>". Postfix will ignore the "User +Name" part and deliver to the <user@example.com> address. +

-

Examples:

+

Examples of problems that can be solved with the smtpd_command_filter +feature:

 /etc/postfix/main.cf:
@@ -11704,13 +11707,15 @@ This feature is available in Postfix 2.2 and later.
 
 
 
smtpd_hard_error_limit -(default: normal: 20, stress: 1)
+(default: normal: 20, overload: 1)

The maximal number of errors a remote SMTP client is allowed to make without delivering mail. The Postfix SMTP server disconnects when the limit is exceeded. Normally the default limit is 20, but -it changes under overload to just 1 with Postfix 2.6 and later. +it changes under overload to just 1. With Postfix 2.5 and earlier, +the SMTP server always allows up to 20 errors by default. +

@@ -11866,7 +11871,7 @@ before it is flushed upon receipt of EHLO, RSET, or end of DATA.
smtpd_junk_command_limit -(default: normal: 100, stress: 1)
+(default: normal: 100, overload: 1)

The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote @@ -11875,8 +11880,8 @@ increment the error counter with each junk command. The junk command count is reset after mail is delivered. See also the smtpd_error_sleep_time and smtpd_soft_error_limit configuration parameters. Normally the default limit is 100, but it changes under -overload to just 1 with Postfix 2.6 and later. -

+overload to just 1. With Postfix 2.5 and earlier, the SMTP server +always allows up to 100 junk commands by default.

@@ -12863,7 +12868,7 @@ Examples: connections to. In a future version there may be different classes of SMTP service.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

@@ -12902,13 +12907,14 @@ during TLS startup and shutdown handshake procedures.

smtpd_timeout -(default: normal: 300s, stress: 10s)
+(default: normal: 300s, overload: 10s)

The time limit for sending a Postfix SMTP server response and for receiving a remote SMTP client request. Normally the default limit -is 300s, but it changes under overload to just 10s with Postfix 2.6 -and later. +is 300s, but it changes under overload to just 10s. With Postfix +2.5 and earlier, the SMTP server always uses a time limit of 300s +by default.

@@ -13278,7 +13284,7 @@ This file may also contain the Postfix SMTP server private ECDSA key.

This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

@@ -13296,7 +13302,7 @@ access to the system superuser account ("root"), and no access to anyone else.

This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

@@ -13330,7 +13336,7 @@ users.

This feature is available in Postfix 2.6 and later, when it is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

@@ -14118,7 +14124,7 @@ under the SECG name "secp256r1", but OpenSSL does not recognize the latter name.

This feature is available in Postfix 2.6 and later, when it is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

@@ -14141,7 +14147,7 @@ of RFC 4492. You should not gen classified as TOP SECRET.

This feature is available in Postfix 2.6 and later, when it is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

@@ -14154,7 +14160,11 @@ defines the meaning of the "export" setting in smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. This is the cipherlist for the opportunistic ("may") TLS client security level and is the default cipherlist for the SMTP server. You are -strongly encouraged to not change this setting.

+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and +later the cipherlist may start with an "aNULL:" prefix, which restores +the 0.9.8-compatible ordering of the aNULL ciphers to the top of the +list when they are enabled. This prefix is not needed with previous +OpenSSL releases.

This feature is available in Postfix 2.3 and later.

@@ -14167,7 +14177,11 @@ strongly encouraged to not change this setting.

The OpenSSL cipherlist for "HIGH" grade ciphers. This defines the meaning of the "high" setting in smtpd_tls_mandatory_ciphers, smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. You are -strongly encouraged to not change this setting.

+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and +later the cipherlist may start with an "aNULL:" prefix, which restores +the 0.9.8-compatible ordering of the aNULL ciphers to the top of the +list when they are enabled. This prefix is not needed with previous +OpenSSL releases.

This feature is available in Postfix 2.3 and later.

@@ -14180,7 +14194,11 @@ strongly encouraged to not change this setting.

The OpenSSL cipherlist for "LOW" or higher grade ciphers. This defines the meaning of the "low" setting in smtpd_tls_mandatory_ciphers, smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. You are -strongly encouraged to not change this setting.

+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and +later the cipherlist may start with an "aNULL:" prefix, which restores +the 0.9.8-compatible ordering of the aNULL ciphers to the top of the +list when they are enabled. This prefix is not needed with previous +OpenSSL releases.

This feature is available in Postfix 2.3 and later.

@@ -14196,7 +14214,10 @@ defines the meaning of the "medium" setting in

This feature is available in Postfix 2.3 and later.

diff --git a/postfix/html/smtp-sink.1.html b/postfix/html/smtp-sink.1.html index 60aceedd4..18768e945 100644 --- a/postfix/html/smtp-sink.1.html +++ b/postfix/html/smtp-sink.1.html @@ -54,6 +54,16 @@ SMTP-SINK(1) SMTP-SINK(1) attempt to block the client before it sends ".". Specify a zero delay value to abort immediately. + -b soft-bounce-reply + Use soft-bounce-reply for soft reject responses. + The default reply is "450 4.3.0 Error: command + failed". + + -B hard-bounce-reply + Use hard-bounce-reply for hard reject responses. + The default reply is "500 5.3.0 Error: command + failed". + -c Display running counters that are updated whenever an SMTP session ends, a QUIT command is executed, or when "." is received. diff --git a/postfix/makedefs b/postfix/makedefs index dd486cc9b..7b56dd9e1 100644 --- a/postfix/makedefs +++ b/postfix/makedefs @@ -421,6 +421,11 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543 [1-6].*) CCARGS="$CCARGS -DNO_IPV6";; *) CCARGS="$CCARGS -DBIND_8_COMPAT -DNO_NETINFO";; esac + # Darwin 10.3.0 no longer has . + case $RELEASE in + ?.*) CCARGS="$CCARGS -DRESOLVE_H_NEEDS_NAMESER8_COMPAT_H";; + *) CCARGS="$CCARGS -DRESOLVE_H_NEEDS_NAMESER_COMPAT_H";; + esac # kqueue and/or poll are broken up to and including MacOS X 10.5 CCARGS="$CCARGS -DNO_KQUEUE" # # Darwin 8.11.1 has kqueue support, but let's play safe diff --git a/postfix/man/man1/smtp-sink.1 b/postfix/man/man1/smtp-sink.1 index ca86ae39a..7013c9299 100644 --- a/postfix/man/man1/smtp-sink.1 +++ b/postfix/man/man1/smtp-sink.1 @@ -51,6 +51,12 @@ abort prematurely with a 550 reply status. Do not read further input from the client; this is an attempt to block the client before it sends ".". Specify a zero delay value to abort immediately. +.IP "\fB-b \fIsoft-bounce-reply\fR" +Use \fIsoft-bounce-reply\fR for soft reject responses. The +default reply is "450 4.3.0 Error: command failed". +.IP "\fB-B \fIhard-bounce-reply\fR" +Use \fIhard-bounce-reply\fR for hard reject responses. The +default reply is "500 5.3.0 Error: command failed". .IP \fB-c\fR Display running counters that are updated whenever an SMTP session ends, a QUIT command is executed, or when "." is diff --git a/postfix/man/man5/ldap_table.5 b/postfix/man/man5/ldap_table.5 index 043ab1b79..b81421d52 100644 --- a/postfix/man/man5/ldap_table.5 +++ b/postfix/man/man5/ldap_table.5 @@ -332,10 +332,19 @@ address. .nf result_attribute = mailbox, maildrop .fi + +Don't rely on the default value ("maildrop"). Set the +result_attribute explicitly in all ldap table configuration +files. This is particularly relevant when no result_attribute +is applicable, e.g. cases in which leaf_result_attribute and/or +terminal_result_attribute are used instead. The default value +is harmless if "maildrop" is also listed as a leaf or terminal +result attribute, but it is best to not leave this to chance. .IP "\fBspecial_result_attribute (default: empty)\fR" The attribute(s) of directory entries that can contain DNs -or URLs. If found, a recursive subsequent search is done -using their values. +or RFC 2255 LDAP URLs. If found, a recursive search +is performed to retrieve the entry referenced by the DN, or +the entries matched by the URL query. .nf special_result_attribute = memberdn @@ -343,11 +352,27 @@ using their values. DN recursion retrieves the same result_attributes as the main query, including the special attributes for further -recursion. URI processing retrieves only those attributes -that are included in the URI definition and are *also* -listed in "result_attribute". If the URI lists any of the -map's special result attributes, these are also retrieved -and used recursively. +recursion. + +URL processing retrieves only those attributes that are included +in both the URL definition and as result attributes (ordinary, +special, leaf or terminal) in the Postfix table definition. +If the URL lists any of the table's special result attributes, +these are retrieved and used recursively. A URL that does not +specify any attribute selection, is equivalent (RFC 2255) to a +URL that selects all attributes, in which case the selected +attributes will be the full set of result attributes in the +Postfix table. + +If an LDAP URL attribute-descriptor or the corresponding Postfix +LDAP table result attribute (but not both) uses RFC 2255 sub-type +options ("attr;option"), the attribute requested from the LDAP server +will include the sub-type option. In all other cases, the URL +attribute and the table attribute must match exactly. Attributes +with options in both the URL and the Postfix table are requested +only when the options are identical. LDAP attribute-descriptor +options are very rarely used, most LDAP users will not +need to concern themselves with this level of nuanced detail. .IP "\fBterminal_result_attribute (default: empty)\fR" When one or more terminal result attributes are found in an LDAP entry, all other result attributes are ignored and only the terminal @@ -358,9 +383,15 @@ where the group is expanded, possibly via mailing-list manager or other special processing. .nf + result_attribute = terminal_result_attribute = maildrop .fi +When using terminal and/or leaf result attributes, the +result_attribute is best set to an empty value when it is not +used, or else explicitly set to the desired value, even if it is +the default value "maildrop". + This feature is available with Postfix 2.4 or later. .IP "\fBleaf_result_attribute (default: empty)\fR" When one or more special result attributes are found in a non-terminal @@ -386,6 +417,11 @@ referenced via a DN (or LDAP URI) go in "leaf_result_attribute". leaf_result_attribute = mail .fi +When using terminal and/or leaf result attributes, the +result_attribute is best set to an empty value when it is not +used, or else explicitly set to the desired value, even if it is +the default value "maildrop". + This feature is available with Postfix 2.4 or later. .IP "\fBscope (default: sub)\fR" The LDAP search scope: \fBsub\fR, \fBbase\fR, or \fBone\fR. diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index aeadd20bd..3a6f8dae2 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -157,7 +157,7 @@ be refreshed. Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). .PP This feature is available in Postfix 2.1 and later. -.SH address_verify_poll_count (default: ${stress?1}${stress:3}) +.SH address_verify_poll_count (default: normal: 3, overload: 1) How many times to query the \fBverify\fR(8) service for the completion of an address verification request in progress. .PP @@ -422,8 +422,8 @@ the sender. .PP Note: automatic BCC recipients are produced only for new mail. To avoid mailer loops, automatic BCC recipients are not generated -for mail that Postfix forwards internally, nor for mail that Postfix -generates itself. +after Postfix forwards mail internally, or after Postfix generates +mail itself. .SH anvil_rate_time_unit (default: 60s) The time unit over which client connection rates and other rates are calculated. @@ -2419,13 +2419,13 @@ The LMTP-specific version of the smtp_tls_eccert_file configuration parameter. See there for details. .PP This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later. +compiled and linked with OpenSSL 1.0.0 or later. .SH lmtp_tls_eckey_file (default: empty) The LMTP-specific version of the smtp_tls_eckey_file configuration parameter. See there for details. .PP This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later. +compiled and linked with OpenSSL 1.0.0 or later. .SH lmtp_tls_enforce_peername (default: yes) The LMTP-specific version of the smtp_tls_enforce_peername configuration parameter. See there for details. @@ -3720,7 +3720,7 @@ action, or forward the connection to a real SMTP server process. Drop the connection immediately with a 521 SMTP reply, without reporting PREGREET, HANGUP or DNSBL results. .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH postscreen_blacklist_networks (default: empty) Network addresses that are permanently blacklisted; see the postscreen_blacklist_action parameter for possible actions. This @@ -3728,7 +3728,7 @@ parameter uses the same address syntax as the mynetworks parameter. The blacklist has higher precedence than whitelists. This feature never uses the remote SMTP client hostname. .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH postscreen_cache_cleanup_interval (default: 12h) The amount of time between \fBpostscreen\fR(8) cache cleanup runs. Cache cleanup increases the load on the cache database and should @@ -3745,11 +3745,11 @@ seconds. Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH postscreen_cache_map (default: btree:$data_directory/ps_whitelist) Persistent storage for the \fBpostscreen\fR(8) server decisions. .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH postscreen_cache_retention_time (default: 1d) The amount of time that \fBpostscreen\fR(8) will cache an expired temporary whitelist entry before it is removed. This prevents clients @@ -3759,7 +3759,7 @@ an hour ago. Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH postscreen_cache_ttl (default: 1d) The amount of time that \fBpostscreen\fR(8) will cache a decision for a specific SMTP client IP address. During this time, the client IP @@ -3771,7 +3771,7 @@ unit). Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH postscreen_dnsbl_action (default: continue) The action that \fBpostscreen\fR(8) takes when an SMTP client is listed at the DNS blocklist domains specified with the postscreen_dnsbl_sites @@ -3781,7 +3781,7 @@ Forward the connection to a real SMTP server process. .IP "drop" Drop the connection with a 521 SMTP reply. .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH postscreen_dnsbl_sites (default: empty) Optional list of DNS blocklist domains. When the list is non-enpty, the \fBdnsblog\fR(8) daemon will query these domains with the IP addresses @@ -3804,7 +3804,7 @@ examining DNSBL lookup results. In either case, \fBpostscreen\fR(8) will not whitelist the SMTP client IP address. .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH postscreen_greet_banner (default: $smtpd_banner) The \fItext\fR in the optional "220-\fItext\fR..." server response that @@ -3813,7 +3813,7 @@ text..." response, in an attempt to confuse bad SMTP clients so that they speak before their turn (pre-greet). Specify an empty value to disable this feature. .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH postscreen_greet_wait (default: 4s) The amount of time that \fBpostscreen\fR(8) will wait for an SMTP client to send a command before its turn, and for DNS blocklist @@ -3825,7 +3825,7 @@ an optional one-letter suffix that specifies the time unit). Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks). .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH postscreen_hangup_action (default: continue) The action that \fBpostscreen\fR(8) takes when an SMTP client disconnects without sending data, within the time specified with the @@ -3839,27 +3839,27 @@ forward the broken connection to a real SMTP server process. Drop the connection immediately, without reporting DNSBL lookup results. .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH postscreen_post_queue_limit (default: $default_process_limit) The number of clients that can be waiting for service from a real SMTP server process. When this queue is full, all clients will receive a 421 reponse. .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH postscreen_pre_queue_limit (default: $default_process_limit) The number of non-whitelisted clients that can be waiting for a decision whether they will receive service from a real SMTP server process. When this queue is full, all non-whitelisted clients will receive a 421 reponse. .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH postscreen_whitelist_networks (default: $mynetworks) Network addresses that are permanently whitelisted, and that will not be subjected to \fBpostscreen\fR(8) checks. This parameter uses the same address syntax as the mynetworks parameter. This feature never uses the remote SMTP client hostname. .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH prepend_delivered_header (default: command, file, forward) The message delivery contexts where the Postfix \fBlocal\fR(8) delivery agent prepends a Delivered-To: message header with the address @@ -4156,8 +4156,8 @@ the sender. .PP Note: automatic BCC recipients are produced only for new mail. To avoid mailer loops, automatic BCC recipients are not generated -for mail that Postfix forwards internally, nor for mail that Postfix -generates itself. +after Postfix forwards mail internally, or after Postfix generates +mail itself. .PP Example: .PP @@ -4526,8 +4526,8 @@ the sender. .PP Note: automatic BCC recipients are produced only for new mail. To avoid mailer loops, automatic BCC recipients are not generated -for mail that Postfix forwards internally, nor for mail that Postfix -generates itself. +after Postfix forwards mail internally, or after Postfix generates +mail itself. .PP Example: .PP @@ -5591,7 +5591,7 @@ smtp_tls_eccert_file = /etc/postfix/ecdsa-ccert.pem .ft R .PP This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later. +compiled and linked with OpenSSL 1.0.0 or later. .SH smtp_tls_eckey_file (default: $smtp_tls_eccert_file) File with the Postfix SMTP client ECDSA private key in PEM format. This file may be combined with the Postfix SMTP client ECDSA @@ -5603,7 +5603,7 @@ access to the system superuser account ("root"), and no access to anyone else. .PP This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later. +compiled and linked with OpenSSL 1.0.0 or later. .SH smtp_tls_enforce_peername (default: yes) With mandatory TLS encryption, require that the remote SMTP server hostname matches the information in the remote SMTP server @@ -6986,20 +6986,22 @@ except that initial whitespace and the trailing are removed. The result value is executed by the Postfix SMTP server. .PP -Postfix already implements a number of workarounds for malformed -client commands. +There is no need to use smtpd_command_filter for the following +cases: .IP \(bu Use "resolve_numeric_domain = yes" to accept "\fIuser@ipaddress\fR". .IP \(bu Postfix already accepts the correct form -"\fIuser@[ipaddress]\fR". +"\fIuser@[ipaddress]\fR". Use virtual_alias_maps or canonical_maps +to translate these into domain names if necessary. .IP \(bu -Use "strict_rfc821_envelopes = no" to accept "\fIUser Name -\fR". Postfix will ignore the "User Name" -part before delivering the mail. +Use "strict_rfc821_envelopes = no" to accept "RCPT TO:<\fIUser +Name >\fR". Postfix will ignore the "User +Name" part and deliver to the \fR address. .PP -Examples: +Examples of problems that can be solved with the smtpd_command_filter +feature: .PP .nf .na @@ -7224,11 +7226,12 @@ commands listed in this parameter, commands that follow the "Label:" format of message headers will also cause a disconnect. .PP This feature is available in Postfix 2.2 and later. -.SH smtpd_hard_error_limit (default: normal: 20, stress: 1) +.SH smtpd_hard_error_limit (default: normal: 20, overload: 1) The maximal number of errors a remote SMTP client is allowed to make without delivering mail. The Postfix SMTP server disconnects when the limit is exceeded. Normally the default limit is 20, but -it changes under overload to just 1 with Postfix 2.6 and later. +it changes under overload to just 1. With Postfix 2.5 and earlier, +the SMTP server always allows up to 20 errors by default. .SH smtpd_helo_required (default: no) Require that a remote SMTP client introduces itself with the HELO or EHLO command before sending the MAIL command or other commands @@ -7334,14 +7337,15 @@ smtpd_helo_restrictions = permit_mynetworks, reject_unknown_helo_hostname .SH smtpd_history_flush_threshold (default: 100) The maximal number of lines in the Postfix SMTP server command history before it is flushed upon receipt of EHLO, RSET, or end of DATA. -.SH smtpd_junk_command_limit (default: normal: 100, stress: 1) +.SH smtpd_junk_command_limit (default: normal: 100, overload: 1) The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote SMTP client can send before the Postfix SMTP server starts to increment the error counter with each junk command. The junk command count is reset after mail is delivered. See also the smtpd_error_sleep_time and smtpd_soft_error_limit configuration parameters. Normally the default limit is 100, but it changes under -overload to just 1 with Postfix 2.6 and later. +overload to just 1. With Postfix 2.5 and earlier, the SMTP server +always allows up to 100 junk commands by default. .SH smtpd_milters (default: empty) A list of Milter (mail filter) applications for new mail that arrives via the Postfix \fBsmtpd\fR(8) server. See the MILTER_README @@ -7991,7 +7995,7 @@ The internal service that \fBpostscreen\fR(8) forwards allowed connections to. In a future version there may be different classes of SMTP service. .PP -This feature is available in Postfix 2.7. +This feature is available in Postfix 2.8. .SH smtpd_soft_error_limit (default: 10) The number of errors a remote SMTP client is allowed to make without delivering mail before the Postfix SMTP server slows down all its @@ -8007,11 +8011,12 @@ The time limit for Postfix SMTP server write and read operations during TLS startup and shutdown handshake procedures. .PP This feature is available in Postfix 2.2 and later. -.SH smtpd_timeout (default: normal: 300s, stress: 10s) +.SH smtpd_timeout (default: normal: 300s, overload: 10s) The time limit for sending a Postfix SMTP server response and for receiving a remote SMTP client request. Normally the default limit -is 300s, but it changes under overload to just 10s with Postfix 2.6 -and later. +is 300s, but it changes under overload to just 10s. With Postfix +2.5 and earlier, the SMTP server always uses a time limit of 300s +by default. .PP Note: if you set SMTP time limits to very large values you may have to update the global ipc_timeout parameter. @@ -8330,7 +8335,7 @@ smtpd_tls_eccert_file = /etc/postfix/ecdsa-scert.pem .ft R .PP This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later. +compiled and linked with OpenSSL 1.0.0 or later. .SH smtpd_tls_eckey_file (default: $smtpd_tls_eccert_file) File with the Postfix SMTP server ECDSA private key in PEM format. This file may be combined with the Postfix SMTP server ECDSA certificate @@ -8342,7 +8347,7 @@ access to the system superuser account ("root"), and no access to anyone else. .PP This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later. +compiled and linked with OpenSSL 1.0.0 or later. .SH smtpd_tls_eecdh_grade (default: see "postconf -d" output) The Postfix SMTP server security grade for ephemeral elliptic-curve Diffie-Hellman (EECDH) key exchange. @@ -8366,7 +8371,7 @@ elliptic curve crypto-systems, the "strong" curve is sufficient for most users. .PP This feature is available in Postfix 2.6 and later, when it is -compiled and linked with OpenSSL 0.9.9 or later. +compiled and linked with OpenSSL 1.0.0 or later. .SH smtpd_tls_exclude_ciphers (default: empty) List of ciphers or cipher types to exclude from the SMTP server cipher list at all TLS security levels. Excluding valid ciphers @@ -8941,7 +8946,7 @@ under the SECG name "secp256r1", but OpenSSL does not recognize the latter name. .PP This feature is available in Postfix 2.6 and later, when it is -compiled and linked with OpenSSL 0.9.9 or later. +compiled and linked with OpenSSL 1.0.0 or later. .SH tls_eecdh_ultra_curve (default: secp384r1) The elliptic curve used by the SMTP server for maximally strong ephemeral ECDH key exchange. This curve is used by the Postfix SMTP @@ -8958,28 +8963,40 @@ This default "ultra" curve is specified in NSA "Suite B" Cryptography classified as TOP SECRET. .PP This feature is available in Postfix 2.6 and later, when it is -compiled and linked with OpenSSL 0.9.9 or later. +compiled and linked with OpenSSL 1.0.0 or later. .SH tls_export_cipherlist (default: ALL:+RC4:@STRENGTH) The OpenSSL cipherlist for "EXPORT" or higher grade ciphers. This defines the meaning of the "export" setting in smtpd_tls_mandatory_ciphers, smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. This is the cipherlist for the opportunistic ("may") TLS client security level and is the default cipherlist for the SMTP server. You are -strongly encouraged to not change this setting. +strongly encouraged to not change this setting. With OpenSSL 1.0.0 and +later the cipherlist may start with an "aNULL:" prefix, which restores +the 0.9.8-compatible ordering of the aNULL ciphers to the top of the +list when they are enabled. This prefix is not needed with previous +OpenSSL releases. .PP This feature is available in Postfix 2.3 and later. .SH tls_high_cipherlist (default: ALL:!EXPORT:!LOW:!MEDIUM:+RC4:@STRENGTH) The OpenSSL cipherlist for "HIGH" grade ciphers. This defines the meaning of the "high" setting in smtpd_tls_mandatory_ciphers, smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. You are -strongly encouraged to not change this setting. +strongly encouraged to not change this setting. With OpenSSL 1.0.0 and +later the cipherlist may start with an "aNULL:" prefix, which restores +the 0.9.8-compatible ordering of the aNULL ciphers to the top of the +list when they are enabled. This prefix is not needed with previous +OpenSSL releases. .PP This feature is available in Postfix 2.3 and later. .SH tls_low_cipherlist (default: ALL:!EXPORT:+RC4:@STRENGTH) The OpenSSL cipherlist for "LOW" or higher grade ciphers. This defines the meaning of the "low" setting in smtpd_tls_mandatory_ciphers, smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. You are -strongly encouraged to not change this setting. +strongly encouraged to not change this setting. With OpenSSL 1.0.0 and +later the cipherlist may start with an "aNULL:" prefix, which restores +the 0.9.8-compatible ordering of the aNULL ciphers to the top of the +list when they are enabled. This prefix is not needed with previous +OpenSSL releases. .PP This feature is available in Postfix 2.3 and later. .SH tls_medium_cipherlist (default: ALL:!EXPORT:!LOW:+RC4:@STRENGTH) @@ -8989,7 +9006,10 @@ smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. This is the default cipherlist for mandatory TLS encryption in the TLS client (with anonymous ciphers disabled when verifying server certificates). You are strongly encouraged to not change this -setting. +setting. With OpenSSL 1.0.0 and later the cipherlist may start with an +"aNULL:" prefix, which restores the 0.9.8-compatible ordering of the +aNULL ciphers to the top of the list when they are enabled. This prefix +is not needed with previous OpenSSL releases. .PP This feature is available in Postfix 2.3 and later. .SH tls_null_cipherlist (default: eNULL:!aNULL) diff --git a/postfix/proto/BACKSCATTER_README.html b/postfix/proto/BACKSCATTER_README.html index bdb557b22..1fd55311b 100644 --- a/postfix/proto/BACKSCATTER_README.html +++ b/postfix/proto/BACKSCATTER_README.html @@ -76,7 +76,8 @@ to=<yyyyyy@your.domain.here> proto=ESMTP helo=<zzzzzz>

What you see are lots of "user unknown" errors with "from=<>". -These are error reports from MAILER-DAEMONs elsewhere on the Internet. +These are error reports from MAILER-DAEMONs elsewhere on the Internet, +about email that was sent with a false sender address in your domain.

How do I block backscatter mail to random diff --git a/postfix/proto/SASL_README.html b/postfix/proto/SASL_README.html index 909092f42..91a83888a 100644 --- a/postfix/proto/SASL_README.html +++ b/postfix/proto/SASL_README.html @@ -42,8 +42,8 @@ SMTP server. Once a client is authenticated, a server can give it

Postfix does not implement SASL itself, but instead uses existing implementations as building blocks. This means that some SASL-related -configuration will involve files that belong to Postfix, while other -configuration will involve files that belong to the specific SASL +configuration files will belong to Postfix, while other +configuration files belong to the specific SASL implementation that Postfix will use. This document covers both the Postfix and non-Postfix configuration.

@@ -1460,6 +1460,19 @@ the client (that is, you) is shown in bold font. +

To test this over a connection that is encrypted with TLS, use +openssl s_client instead of telnet: + +

+
+% openssl s_client -connect server.example.com:25 -starttls smtp
+...
+220 server.example.com ESMTP Postfix
+EHLO client.example.com
+...see above example for more...
+
+
+

Instead of AHRlc3QAdGVzdHBhc3M=, specify the base64-encoded form of \0username\0password (the \0 is a null byte). The example above is for a user named `test' diff --git a/postfix/proto/ldap_table b/postfix/proto/ldap_table index 43fcbd6db..709d06fdf 100644 --- a/postfix/proto/ldap_table +++ b/postfix/proto/ldap_table @@ -320,10 +320,19 @@ # .nf # result_attribute = mailbox, maildrop # .fi +# +# Don't rely on the default value ("maildrop"). Set the +# result_attribute explicitly in all ldap table configuration +# files. This is particularly relevant when no result_attribute +# is applicable, e.g. cases in which leaf_result_attribute and/or +# terminal_result_attribute are used instead. The default value +# is harmless if "maildrop" is also listed as a leaf or terminal +# result attribute, but it is best to not leave this to chance. # .IP "\fBspecial_result_attribute (default: empty)\fR" # The attribute(s) of directory entries that can contain DNs -# or URLs. If found, a recursive subsequent search is done -# using their values. +# or RFC 2255 LDAP URLs. If found, a recursive search +# is performed to retrieve the entry referenced by the DN, or +# the entries matched by the URL query. # # .nf # special_result_attribute = memberdn @@ -331,11 +340,27 @@ # # DN recursion retrieves the same result_attributes as the # main query, including the special attributes for further -# recursion. URI processing retrieves only those attributes -# that are included in the URI definition and are *also* -# listed in "result_attribute". If the URI lists any of the -# map's special result attributes, these are also retrieved -# and used recursively. +# recursion. +# +# URL processing retrieves only those attributes that are included +# in both the URL definition and as result attributes (ordinary, +# special, leaf or terminal) in the Postfix table definition. +# If the URL lists any of the table's special result attributes, +# these are retrieved and used recursively. A URL that does not +# specify any attribute selection, is equivalent (RFC 2255) to a +# URL that selects all attributes, in which case the selected +# attributes will be the full set of result attributes in the +# Postfix table. +# +# If an LDAP URL attribute-descriptor or the corresponding Postfix +# LDAP table result attribute (but not both) uses RFC 2255 sub-type +# options ("attr;option"), the attribute requested from the LDAP server +# will include the sub-type option. In all other cases, the URL +# attribute and the table attribute must match exactly. Attributes +# with options in both the URL and the Postfix table are requested +# only when the options are identical. LDAP attribute-descriptor +# options are very rarely used, most LDAP users will not +# need to concern themselves with this level of nuanced detail. # .IP "\fBterminal_result_attribute (default: empty)\fR" # When one or more terminal result attributes are found in an LDAP # entry, all other result attributes are ignored and only the terminal @@ -346,9 +371,15 @@ # other special processing. # # .nf +# result_attribute = # terminal_result_attribute = maildrop # .fi # +# When using terminal and/or leaf result attributes, the +# result_attribute is best set to an empty value when it is not +# used, or else explicitly set to the desired value, even if it is +# the default value "maildrop". +# # This feature is available with Postfix 2.4 or later. # .IP "\fBleaf_result_attribute (default: empty)\fR" # When one or more special result attributes are found in a non-terminal @@ -374,6 +405,11 @@ # leaf_result_attribute = mail # .fi # +# When using terminal and/or leaf result attributes, the +# result_attribute is best set to an empty value when it is not +# used, or else explicitly set to the desired value, even if it is +# the default value "maildrop". +# # This feature is available with Postfix 2.4 or later. # .IP "\fBscope (default: sub)\fR" # The LDAP search scope: \fBsub\fR, \fBbase\fR, or \fBone\fR. diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index ad076c7c6..70ea5a641 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -301,7 +301,7 @@ seconds.

This feature is available in Postfix 2.7.

-%PARAM address_verify_poll_count ${stress?1}${stress:3} +%PARAM address_verify_poll_count normal: 3, overload: 1

How many times to query the verify(8) service for the completion @@ -642,8 +642,8 @@ the sender.

Note: automatic BCC recipients are produced only for new mail. To avoid mailer loops, automatic BCC recipients are not generated -for mail that Postfix forwards internally, nor for mail that Postfix -generates itself.

+after Postfix forwards mail internally, or after Postfix generates +mail itself.

%PARAM berkeley_db_create_buffer_size 16777216 @@ -3376,8 +3376,8 @@ the sender.

Note: automatic BCC recipients are produced only for new mail. To avoid mailer loops, automatic BCC recipients are not generated -for mail that Postfix forwards internally, nor for mail that Postfix -generates itself.

+after Postfix forwards mail internally, or after Postfix generates +mail itself.

Example: @@ -3656,8 +3656,8 @@ the sender.

Note: automatic BCC recipients are produced only for new mail. To avoid mailer loops, automatic BCC recipients are not generated -for mail that Postfix forwards internally, nor for mail that Postfix -generates itself.

+after Postfix forwards mail internally, or after Postfix generates +mail itself.

Example: @@ -5137,16 +5137,18 @@ server delays all responses by (number of errors) seconds.

-%PARAM smtpd_hard_error_limit normal: 20, stress: 1 +%PARAM smtpd_hard_error_limit normal: 20, overload: 1

The maximal number of errors a remote SMTP client is allowed to make without delivering mail. The Postfix SMTP server disconnects when the limit is exceeded. Normally the default limit is 20, but -it changes under overload to just 1 with Postfix 2.6 and later. +it changes under overload to just 1. With Postfix 2.5 and earlier, +the SMTP server always allows up to 20 errors by default. +

-%PARAM smtpd_junk_command_limit normal: 100, stress: 1 +%PARAM smtpd_junk_command_limit normal: 100, overload: 1

The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote @@ -5155,8 +5157,8 @@ increment the error counter with each junk command. The junk command count is reset after mail is delivered. See also the smtpd_error_sleep_time and smtpd_soft_error_limit configuration parameters. Normally the default limit is 100, but it changes under -overload to just 1 with Postfix 2.6 and later. -

+overload to just 1. With Postfix 2.5 and earlier, the SMTP server +always allows up to 100 junk commands by default.

%PARAM smtpd_recipient_overshoot_limit 1000 @@ -6091,13 +6093,14 @@ smtpd_sender_restrictions = reject_unknown_sender_domain, check_sender_access hash:/etc/postfix/access -%PARAM smtpd_timeout normal: 300s, stress: 10s +%PARAM smtpd_timeout normal: 300s, overload: 10s

The time limit for sending a Postfix SMTP server response and for receiving a remote SMTP client request. Normally the default limit -is 300s, but it changes under overload to just 10s with Postfix 2.6 -and later. +is 300s, but it changes under overload to just 10s. With Postfix +2.5 and earlier, the SMTP server always uses a time limit of 300s +by default.

@@ -11013,7 +11016,11 @@ attribute. See smtp_tls_policy_maps for notes and examples.

The OpenSSL cipherlist for "HIGH" grade ciphers. This defines the meaning of the "high" setting in smtpd_tls_mandatory_ciphers, smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. You are -strongly encouraged to not change this setting.

+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and +later the cipherlist may start with an "aNULL:" prefix, which restores +the 0.9.8-compatible ordering of the aNULL ciphers to the top of the +list when they are enabled. This prefix is not needed with previous +OpenSSL releases.

This feature is available in Postfix 2.3 and later.

@@ -11025,7 +11032,10 @@ smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. This is the default cipherlist for mandatory TLS encryption in the TLS client (with anonymous ciphers disabled when verifying server certificates). You are strongly encouraged to not change this -setting.

+setting. With OpenSSL 1.0.0 and later the cipherlist may start with an +"aNULL:" prefix, which restores the 0.9.8-compatible ordering of the +aNULL ciphers to the top of the list when they are enabled. This prefix +is not needed with previous OpenSSL releases.

This feature is available in Postfix 2.3 and later.

@@ -11034,7 +11044,11 @@ setting.

The OpenSSL cipherlist for "LOW" or higher grade ciphers. This defines the meaning of the "low" setting in smtpd_tls_mandatory_ciphers, smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. You are -strongly encouraged to not change this setting.

+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and +later the cipherlist may start with an "aNULL:" prefix, which restores +the 0.9.8-compatible ordering of the aNULL ciphers to the top of the +list when they are enabled. This prefix is not needed with previous +OpenSSL releases.

This feature is available in Postfix 2.3 and later.

@@ -11045,7 +11059,11 @@ defines the meaning of the "export" setting in smtpd_tls_mandatory_ciphers, smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. This is the cipherlist for the opportunistic ("may") TLS client security level and is the default cipherlist for the SMTP server. You are -strongly encouraged to not change this setting.

+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and +later the cipherlist may start with an "aNULL:" prefix, which restores +the 0.9.8-compatible ordering of the aNULL ciphers to the top of the +list when they are enabled. This prefix is not needed with previous +OpenSSL releases.

This feature is available in Postfix 2.3 and later.

@@ -11571,7 +11589,7 @@ under the SECG name "secp256r1", but OpenSSL does not recognize the latter name.

This feature is available in Postfix 2.6 and later, when it is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

%PARAM tls_eecdh_ultra_curve secp384r1 @@ -11590,7 +11608,7 @@ of RFC 4492. You should not generally change this setting.

classified as TOP SECRET.

This feature is available in Postfix 2.6 and later, when it is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

%PARAM smtpd_tls_eecdh_grade see "postconf -d" output @@ -11620,7 +11638,7 @@ users.

This feature is available in Postfix 2.6 and later, when it is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

%PARAM smtpd_tls_eccert_file @@ -11636,7 +11654,7 @@ smtpd_tls_eccert_file = /etc/postfix/ecdsa-scert.pem

This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

%PARAM smtpd_tls_eckey_file $smtpd_tls_eccert_file @@ -11650,7 +11668,7 @@ access to the system superuser account ("root"), and no access to anyone else.

This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

%PARAM smtp_tls_eccert_file @@ -11667,7 +11685,7 @@ smtp_tls_eccert_file = /etc/postfix/ecdsa-ccert.pem

This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

%PARAM smtp_tls_eckey_file $smtp_tls_eccert_file @@ -11681,7 +11699,7 @@ access to the system superuser account ("root"), and no access to anyone else.

This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

%PARAM lmtp_tls_eccert_file @@ -11689,7 +11707,7 @@ compiled and linked with OpenSSL 0.9.9 or later.

parameter. See there for details.

This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

%PARAM lmtp_tls_eckey_file @@ -11697,7 +11715,7 @@ compiled and linked with OpenSSL 0.9.9 or later.

parameter. See there for details.

This feature is available in Postfix 2.6 and later, when Postfix is -compiled and linked with OpenSSL 0.9.9 or later.

+compiled and linked with OpenSSL 1.0.0 or later.

%PARAM smtp_header_checks @@ -12459,7 +12477,7 @@ patch for Postfix 2.6.

Persistent storage for the postscreen(8) server decisions.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM smtpd_service smtpd @@ -12467,7 +12485,7 @@ patch for Postfix 2.6.

connections to. In a future version there may be different classes of SMTP service.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM postscreen_post_queue_limit $default_process_limit @@ -12475,7 +12493,7 @@ classes of SMTP service.

real SMTP server process. When this queue is full, all clients will receive a 421 reponse.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM postscreen_pre_queue_limit $default_process_limit @@ -12484,7 +12502,7 @@ a decision whether they will receive service from a real SMTP server process. When this queue is full, all non-whitelisted clients will receive a 421 reponse.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM postscreen_cache_ttl 1d @@ -12498,7 +12516,7 @@ unit).

Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM postscreen_cache_retention_time 1d @@ -12510,7 +12528,7 @@ an hour ago.

Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM postscreen_cache_cleanup_interval 12h @@ -12529,7 +12547,7 @@ seconds.

Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM postscreen_greet_wait 4s @@ -12543,7 +12561,7 @@ an optional one-letter suffix that specifies the time unit).

Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM postscreen_dnsbl_sites @@ -12570,7 +12588,7 @@ parameter. Specify one of the following:

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM postscreen_greet_action continue @@ -12598,7 +12616,7 @@ examining DNSBL lookup results.

In either case, postscreen(8) will not whitelist the SMTP client IP address.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM postscreen_hangup_action continue @@ -12623,7 +12641,7 @@ results. -

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM postscreen_whitelist_networks $mynetworks @@ -12632,7 +12650,7 @@ will not be subjected to postscreen(8) checks. This parameter uses the same address syntax as the mynetworks parameter. This feature never uses the remote SMTP client hostname.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM postscreen_blacklist_networks @@ -12642,7 +12660,7 @@ parameter uses the same address syntax as the mynetworks parameter. The blacklist has higher precedence than whitelists. This feature never uses the remote SMTP client hostname.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM postscreen_greet_banner $smtpd_banner @@ -12653,7 +12671,7 @@ text..." response, in an attempt to confuse bad SMTP clients so that they speak before their turn (pre-greet). Specify an empty value to disable this feature.

-

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM postscreen_blacklist_action continue @@ -12679,7 +12697,7 @@ reporting PREGREET, HANGUP or DNSBL results. -

This feature is available in Postfix 2.7.

+

This feature is available in Postfix 2.8.

%PARAM smtpd_command_filter @@ -12695,8 +12713,8 @@ except that initial whitespace and the trailing <CR><LF> are removed. The result value is executed by the Postfix SMTP server.

-

Postfix already implements a number of workarounds for malformed -client commands.

+

There is no need to use smtpd_command_filter for the following +cases:

    @@ -12704,15 +12722,18 @@ client commands.

    "user@ipaddress".

  • Postfix already accepts the correct form -"user@[ipaddress]".

    +"user@[ipaddress]". Use virtual_alias_maps or canonical_maps +to translate these into domain names if necessary.

    -
  • Use "strict_rfc821_envelopes = no" to accept "User Name -<user@example.com>". Postfix will ignore the "User Name" -part before delivering the mail.

    +
  • Use "strict_rfc821_envelopes = no" to accept "RCPT TO:<User +Name <user@example.com>>". Postfix will ignore the "User +Name" part and deliver to the <user@example.com> address. +

-

Examples:

+

Examples of problems that can be solved with the smtpd_command_filter +feature:

 /etc/postfix/main.cf:
diff --git a/postfix/src/dns/dns.h b/postfix/src/dns/dns.h
index b19d5f0cd..f26153862 100644
--- a/postfix/src/dns/dns.h
+++ b/postfix/src/dns/dns.h
@@ -22,6 +22,9 @@
 #ifdef RESOLVE_H_NEEDS_NAMESER8_COMPAT_H
 #include 
 #endif
+#ifdef RESOLVE_H_NEEDS_NAMESER_COMPAT_H
+#include 
+#endif
 #include 
 
  /*
diff --git a/postfix/src/global/dict_ldap.c b/postfix/src/global/dict_ldap.c
index 935f194ab..95bc1f655 100644
--- a/postfix/src/global/dict_ldap.c
+++ b/postfix/src/global/dict_ldap.c
@@ -833,6 +833,91 @@ static void dict_ldap_conn_find(DICT_LDAP *dict_ldap)
     vstring_free(keybuf);
 }
 
+/* attr_sub_type - Is one of two attributes a sub-type of another */
+
+static int attrdesc_subtype(const char *a1, const char *a2)
+{
+
+    /*
+     * RFC 2251 section 4.1.4: LDAP attribute names are case insensitive
+     */
+    while (*a1 && TOLOWER(*a1) == TOLOWER(*a2))
+	++a1, ++a2;
+
+    /*
+     * Names equal to end of a1, is a2 equal or a subtype?
+     */
+    if (*a1 == 0 && (*a2 == 0 || *a2 == ';'))
+	return (1);
+
+    /*
+     * Names equal to end of a2, is a1 a subtype?
+     */
+    if (*a2 == 0 && *a1 == ';')
+	return (-1);
+
+    /*
+     * Distinct attributes
+     */
+    return (0);
+}
+
+/* url_attrs - attributes we want from LDAP URL */
+
+static char **url_attrs(DICT_LDAP *dict_ldap, LDAPURLDesc * url)
+{
+    static ARGV *attrs;
+    char  **a1;
+    char  **a2;
+    int     arel;
+
+    /*
+     * If the LDAP URI specified no attributes, all entry attributes are
+     * returned, leading to unnecessarily large LDAP results, particularly
+     * since dynamic groups are most useful for large groups.
+     * 
+     * Since we only make use of the various mumble_results attributes, we ask
+     * only for these, thus making large queries much faster.
+     * 
+     * In one test case, a query returning 75K users took 16 minutes when all
+     * attributes are returned, and just under 3 minutes with only the
+     * desired result attribute.
+     */
+    if (url->lud_attrs == 0 || *url->lud_attrs == 0)
+	return (dict_ldap->result_attributes->argv);
+
+    /*
+     * When the LDAP URI explicitly specifies a set of attributes, we use the
+     * interection of the URI attributes and our result attributes. This way
+     * LDAP URIs can hide certain attributes that should not be part of the
+     * query. There is no point in retrieving attributes not listed in our
+     * result set, we won't make any use of those.
+     */
+    if (attrs)
+	argv_truncate(attrs, 0);
+    else
+	attrs = argv_alloc(2);
+
+    /*
+     * Retrieve only those attributes that are of interest to us.
+     * 
+     * If the URL attribute and the attribute we want differ only in the
+     * "options" part of the attribute descriptor, select the more specific
+     * attribute descriptor.
+     */
+    for (a1 = url->lud_attrs; *a1; ++a1) {
+	for (a2 = dict_ldap->result_attributes->argv; *a2; ++a2) {
+	    arel = attrdesc_subtype(*a1, *a2);
+	    if (arel > 0)
+		argv_add(attrs, *a2, ARGV_END);
+	    else if (arel < 0)
+		argv_add(attrs, *a1, ARGV_END);
+	}
+    }
+
+    return ((attrs->argc > 0) ? attrs->argv : 0);
+}
+
 /*
  * dict_ldap_get_values: for each entry returned by a search, get the values
  * of all its attributes. Recurses to resolve any DN or URL values found.
@@ -852,6 +937,7 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage *res,
     LDAPMessage *entry = 0;
     BerElement *ber;
     char   *attr;
+    char  **attrs;
     struct berval **vals;
     int     valcount;
     LDAPURLDesc *url;
@@ -946,7 +1032,7 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage *res,
 
 	    /*
 	     * The "result_attributes" list enumerates all the requested
-	     * attributes, first the ordinary result attribtutes and then the
+	     * attributes, first the ordinary result attributes and then the
 	     * special result attributes that hold DN or LDAP URL values.
 	     * 
 	     * The number of ordinary attributes is "num_attributes".
@@ -955,8 +1041,8 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage *res,
 	     * index on the "result_attributes" list.
 	     */
 	    for (i = 0; dict_ldap->result_attributes->argv[i]; i++)
-		if (strcasecmp(dict_ldap->result_attributes->argv[i],
-			       attr) == 0)
+		if (attrdesc_subtype(dict_ldap->result_attributes->argv[i],
+				     attr) > 0)
 		    break;
 
 	    /*
@@ -968,8 +1054,8 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage *res,
 		    || (!is_leaf &&
 			i < dict_ldap->num_terminal + dict_ldap->num_leaf)) {
 		    if (msg_verbose)
-			msg_info("%s[%d]: skipping %ld value(s) of %s "
-				 "attribute %s", myname, recursion, i,
+			msg_info("%s[%d]: skipping %d value(s) of %s "
+				 "attribute %s", myname, recursion, valcount,
 				 is_terminal ? "non-terminal" : "leaf-only",
 				 attr);
 		} else {
@@ -991,25 +1077,42 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage *res,
 		    if (dict_errno != 0)
 			continue;
 		    if (msg_verbose)
-			msg_info("%s[%d]: search returned %ld value(s) for"
+			msg_info("%s[%d]: search returned %d value(s) for"
 				 " requested result attribute %s",
-				 myname, recursion, i, attr);
+				 myname, recursion, valcount, attr);
 		}
 	    } else if (recursion < dict_ldap->recursion_limit
 		       && dict_ldap->result_attributes->argv[i]) {
 		/* Special result attribute */
 		for (i = 0; i < valcount; i++) {
 		    if (ldap_is_ldap_url(vals[i]->bv_val)) {
-			if (msg_verbose)
-			    msg_info("%s[%d]: looking up URL %s", myname,
-				     recursion, vals[i]->bv_val);
 			rc = ldap_url_parse(vals[i]->bv_val, &url);
 			if (rc == 0) {
-			    rc = search_st(dict_ldap->ld, url->lud_dn,
-					   url->lud_scope, url->lud_filter,
-					 url->lud_attrs, dict_ldap->timeout,
-					   &resloop);
+			    if ((attrs = url_attrs(dict_ldap, url)) != 0) {
+				if (msg_verbose)
+				    msg_info("%s[%d]: looking up URL %s",
+					     myname, recursion,
+					     vals[i]->bv_val);
+				rc = search_st(dict_ldap->ld, url->lud_dn,
+					       url->lud_scope,
+					       url->lud_filter,
+					       attrs, dict_ldap->timeout,
+					       &resloop);
+			    }
 			    ldap_free_urldesc(url);
+			    if (attrs == 0) {
+				if (msg_verbose)
+				    msg_info("%s[%d]: skipping URL %s: no "
+					     "pertinent attributes", myname,
+					     recursion, vals[i]->bv_val);
+				continue;
+			    }
+			} else {
+			    msg_warn("%s[%d]: malformed URL %s: %s(%d)",
+				     myname, recursion, vals[i]->bv_val,
+				     ldap_err2string(rc), rc);
+			    dict_errno = DICT_ERR_RETRY;
+			    break;
 			}
 		    } else {
 			if (msg_verbose)
@@ -1046,12 +1149,10 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage *res,
 		    if (dict_errno != 0)
 			break;
 		}
-		if (dict_errno != 0)
-		    continue;
-		if (msg_verbose)
-		    msg_info("%s[%d]: search returned %ld value(s) for"
+		if (msg_verbose && dict_errno == 0)
+		    msg_info("%s[%d]: search returned %d value(s) for"
 			     " special result attribute %s",
-			     myname, recursion, i, attr);
+			     myname, recursion, valcount, attr);
 	    } else if (recursion >= dict_ldap->recursion_limit
 		       && dict_ldap->result_attributes->argv[i]) {
 		msg_warn("%s[%d]: %s: Recursion limit exceeded"
@@ -1088,6 +1189,16 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
     if (msg_verbose)
 	msg_info("%s: In dict_ldap_lookup", myname);
 
+    /*
+     * Don't frustrate future attempts to make Postfix UTF-8 transparent.
+     */
+    if (!valid_utf_8(name, strlen(name))) {
+	if (msg_verbose)
+	    msg_info("%s: %s: Skipping lookup of non-UTF-8 key '%s'",
+		     myname, dict_ldap->parser->name, name);
+	return (0);
+    }
+
     /*
      * Optionally fold the key.
      */
@@ -1105,7 +1216,8 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
      */
     if (db_common_check_domain(dict_ldap->ctx, name) == 0) {
 	if (msg_verbose)
-	    msg_info("%s: Skipping lookup of '%s'", myname, name);
+	    msg_info("%s: %s: Skipping lookup of key '%s': domain mismatch",
+		     myname, dict_ldap->parser->name, name);
 	return (0);
     }
 #define INIT_VSTR(buf, len) do { \
diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h
index 90b3b7a75..8861b8245 100644
--- a/postfix/src/global/mail_params.h
+++ b/postfix/src/global/mail_params.h
@@ -2921,20 +2921,31 @@ extern bool var_smtp_cname_overr;
  /*
   * TLS cipherlists
   */
+#ifdef USE_TLS
+#include 
+#if OPENSSL_VERSION_NUMBER >= 0x1000000fL
+#define PREFER_aNULL "aNULL:-aNULL:"
+#else
+#define PREFER_aNULL ""
+#endif
+#else
+#define PREFER_aNULL ""
+#endif
+
 #define VAR_TLS_HIGH_CLIST	"tls_high_cipherlist"
-#define DEF_TLS_HIGH_CLIST	"ALL:!EXPORT:!LOW:!MEDIUM:+RC4:@STRENGTH"
+#define DEF_TLS_HIGH_CLIST	PREFER_aNULL "ALL:!EXPORT:!LOW:!MEDIUM:+RC4:@STRENGTH"
 extern char *var_tls_high_clist;
 
 #define VAR_TLS_MEDIUM_CLIST	"tls_medium_cipherlist"
-#define DEF_TLS_MEDIUM_CLIST	"ALL:!EXPORT:!LOW:+RC4:@STRENGTH"
+#define DEF_TLS_MEDIUM_CLIST	PREFER_aNULL "ALL:!EXPORT:!LOW:+RC4:@STRENGTH"
 extern char *var_tls_medium_clist;
 
 #define VAR_TLS_LOW_CLIST	"tls_low_cipherlist"
-#define DEF_TLS_LOW_CLIST	"ALL:!EXPORT:+RC4:@STRENGTH"
+#define DEF_TLS_LOW_CLIST	PREFER_aNULL "ALL:!EXPORT:+RC4:@STRENGTH"
 extern char *var_tls_low_clist;
 
 #define VAR_TLS_EXPORT_CLIST	"tls_export_cipherlist"
-#define DEF_TLS_EXPORT_CLIST	"ALL:+RC4:@STRENGTH"
+#define DEF_TLS_EXPORT_CLIST	PREFER_aNULL "ALL:+RC4:@STRENGTH"
 extern char *var_tls_export_clist;
 
 #define VAR_TLS_NULL_CLIST	"tls_null_cipherlist"
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index 92835492f..0ca1913e3 100644
--- a/postfix/src/global/mail_version.h
+++ b/postfix/src/global/mail_version.h
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE	"20100323"
+#define MAIL_RELEASE_DATE	"20100601"
 #define MAIL_VERSION_NUMBER	"2.8"
 
 #ifdef SNAPSHOT
diff --git a/postfix/src/local/recipient.c b/postfix/src/local/recipient.c
index f36d21023..f6f34502c 100644
--- a/postfix/src/local/recipient.c
+++ b/postfix/src/local/recipient.c
@@ -250,6 +250,10 @@ int     deliver_recipient(LOCAL_STATE state, USER_ATTR usr_attr)
 
     /*
      * Address extension management.
+     * 
+     * XXX Fix 20100422, finalized 20100529: it is too error-prone to
+     * distinguish between "no extension" and "no valid extension", so we
+     * drop an invalid extension from the recipient address local-part.
      */
     state.msg_attr.user = mystrdup(state.msg_attr.local);
     if (*var_rcpt_delim) {
@@ -259,6 +263,9 @@ int     deliver_recipient(LOCAL_STATE state, USER_ATTR usr_attr)
 	    msg_warn("%s: address with illegal extension: %s",
 		     state.msg_attr.queue_id, state.msg_attr.local);
 	    state.msg_attr.extension = 0;
+	    /* XXX Can't myfree + mystrdup, must truncate instead. */
+	    state.msg_attr.local[strlen(state.msg_attr.user)] = 0;
+	    /* Truncating is safe. The code below rejects null usernames. */
 	}
     } else
 	state.msg_attr.extension = 0;
diff --git a/postfix/src/milter/milter.c b/postfix/src/milter/milter.c
index 5ec673248..ee38b0f23 100644
--- a/postfix/src/milter/milter.c
+++ b/postfix/src/milter/milter.c
@@ -901,7 +901,7 @@ int     main(int argc, char **argv)
 		msg_warn("no milters");
 		continue;
 	    }
-	    resp = milter_rcpt_event(milters, (const char **) args);
+	    resp = milter_rcpt_event(milters, 0, (const char **) args);
 	} else if (strcmp(cmd, "unknown") == 0 && argv->argc > 0) {
 	    if (milters == 0) {
 		msg_warn("no milters");
diff --git a/postfix/src/smtp/smtp_proto.c b/postfix/src/smtp/smtp_proto.c
index e9586c844..20e020492 100644
--- a/postfix/src/smtp/smtp_proto.c
+++ b/postfix/src/smtp/smtp_proto.c
@@ -1204,21 +1204,39 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
 	     * Build the XFORWARD command. With properly sanitized
 	     * information, the command length stays within the 512 byte
 	     * command line length limit.
+	     * 
+	     * XXX smtpd_xforward_preset() initializes some fields as "unknown"
+	     * and some as null; historically, pickup(8) does not send any of
+	     * these, and the queue manager presets absent fields to "not
+	     * available" except for the rewrite context which is preset to
+	     * local by way of migration aid.  These definitions need to be
+	     * centralized for maintainability.
 	     */
+#ifndef CAN_FORWARD_CLIENT_NAME
+#define _ATTR_AVAIL_AND_KNOWN_(val) \
+	(DEL_REQ_ATTR_AVAIL(val) && strcasecmp((val), "unknown"))
+#define CAN_FORWARD_CLIENT_NAME	_ATTR_AVAIL_AND_KNOWN_
+#define CAN_FORWARD_CLIENT_ADDR	_ATTR_AVAIL_AND_KNOWN_
+#define CAN_FORWARD_CLIENT_PORT	_ATTR_AVAIL_AND_KNOWN_
+#define CAN_FORWARD_PROTO_NAME	_ATTR_AVAIL_AND_KNOWN_
+#define CAN_FORWARD_HELO_NAME	DEL_REQ_ATTR_AVAIL
+#define CAN_FORWARD_RWR_CONTEXT	DEL_REQ_ATTR_AVAIL
+#endif
+
 	case SMTP_STATE_XFORWARD_NAME_ADDR:
 	    vstring_strcpy(next_command, XFORWARD_CMD);
 	    if ((session->features & SMTP_FEATURE_XFORWARD_NAME)
-		&& DEL_REQ_ATTR_AVAIL(request->client_name)) {
+		&& CAN_FORWARD_CLIENT_NAME(request->client_name)) {
 		vstring_strcat(next_command, " " XFORWARD_NAME "=");
 		xtext_quote_append(next_command, request->client_name, "");
 	    }
 	    if ((session->features & SMTP_FEATURE_XFORWARD_ADDR)
-		&& DEL_REQ_ATTR_AVAIL(request->client_addr)) {
+		&& CAN_FORWARD_CLIENT_ADDR(request->client_addr)) {
 		vstring_strcat(next_command, " " XFORWARD_ADDR "=");
 		xtext_quote_append(next_command, request->client_addr, "");
 	    }
 	    if ((session->features & SMTP_FEATURE_XFORWARD_PORT)
-		&& DEL_REQ_ATTR_AVAIL(request->client_port)) {
+		&& CAN_FORWARD_CLIENT_PORT(request->client_port)) {
 		vstring_strcat(next_command, " " XFORWARD_PORT "=");
 		xtext_quote_append(next_command, request->client_port, "");
 	    }
@@ -1231,17 +1249,17 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
 	case SMTP_STATE_XFORWARD_PROTO_HELO:
 	    vstring_strcpy(next_command, XFORWARD_CMD);
 	    if ((session->features & SMTP_FEATURE_XFORWARD_PROTO)
-		&& DEL_REQ_ATTR_AVAIL(request->client_proto)) {
+		&& CAN_FORWARD_PROTO_NAME(request->client_proto)) {
 		vstring_strcat(next_command, " " XFORWARD_PROTO "=");
 		xtext_quote_append(next_command, request->client_proto, "");
 	    }
 	    if ((session->features & SMTP_FEATURE_XFORWARD_HELO)
-		&& DEL_REQ_ATTR_AVAIL(request->client_helo)) {
+		&& CAN_FORWARD_HELO_NAME(request->client_helo)) {
 		vstring_strcat(next_command, " " XFORWARD_HELO "=");
 		xtext_quote_append(next_command, request->client_helo, "");
 	    }
 	    if ((session->features & SMTP_FEATURE_XFORWARD_DOMAIN)
-		&& DEL_REQ_ATTR_AVAIL(request->rewrite_context)) {
+		&& CAN_FORWARD_RWR_CONTEXT(request->rewrite_context)) {
 		vstring_strcat(next_command, " " XFORWARD_DOMAIN "=");
 		xtext_quote_append(next_command,
 		     strcmp(request->rewrite_context, MAIL_ATTR_RWR_LOCAL) ?
@@ -1979,19 +1997,19 @@ int     smtp_xfer(SMTP_STATE *state)
     send_name_addr =
 	var_smtp_send_xforward
 	&& (((session->features & SMTP_FEATURE_XFORWARD_NAME)
-	     && DEL_REQ_ATTR_AVAIL(request->client_name))
+	     && CAN_FORWARD_CLIENT_NAME(request->client_name))
 	    || ((session->features & SMTP_FEATURE_XFORWARD_ADDR)
-		&& DEL_REQ_ATTR_AVAIL(request->client_addr))
+		&& CAN_FORWARD_CLIENT_ADDR(request->client_addr))
 	    || ((session->features & SMTP_FEATURE_XFORWARD_PORT)
-		&& DEL_REQ_ATTR_AVAIL(request->client_port)));
+		&& CAN_FORWARD_CLIENT_PORT(request->client_port)));
     session->send_proto_helo =
 	var_smtp_send_xforward
 	&& (((session->features & SMTP_FEATURE_XFORWARD_PROTO)
-	     && DEL_REQ_ATTR_AVAIL(request->client_proto))
+	     && CAN_FORWARD_PROTO_NAME(request->client_proto))
 	    || ((session->features & SMTP_FEATURE_XFORWARD_HELO)
-		&& DEL_REQ_ATTR_AVAIL(request->client_helo))
+		&& CAN_FORWARD_HELO_NAME(request->client_helo))
 	    || ((session->features & SMTP_FEATURE_XFORWARD_DOMAIN)
-		&& DEL_REQ_ATTR_AVAIL(request->rewrite_context)));
+		&& CAN_FORWARD_RWR_CONTEXT(request->rewrite_context)));
     if (send_name_addr)
 	recv_state = send_state = SMTP_STATE_XFORWARD_NAME_ADDR;
     else if (session->send_proto_helo)
diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c
index a83330fbd..3f5a8c583 100644
--- a/postfix/src/smtpd/smtpd_check.c
+++ b/postfix/src/smtpd/smtpd_check.c
@@ -3696,7 +3696,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
 			 name);
 	    else {
 		cpp += 1;
-		if (strcasecmp(state->name, "unknown") != 0)
+		if (strcasecmp(state->reverse_name, "unknown") != 0)
 		    status = reject_rbl_domain(state, *cpp, state->reverse_name,
 					       SMTPD_NAME_REV_CLIENT);
 	    }
diff --git a/postfix/src/smtpstone/smtp-sink.c b/postfix/src/smtpstone/smtp-sink.c
index dfa3fab2d..af3e06abb 100644
--- a/postfix/src/smtpstone/smtp-sink.c
+++ b/postfix/src/smtpstone/smtp-sink.c
@@ -45,6 +45,12 @@
 /*	further input from the client; this is an attempt to block
 /*	the client before it sends ".".  Specify a zero delay value
 /*	to abort immediately.
+/* .IP "\fB-b \fIsoft-bounce-reply\fR"
+/*	Use \fIsoft-bounce-reply\fR for soft reject responses.  The
+/*	default reply is "450 4.3.0 Error: command failed".
+/* .IP "\fB-B \fIhard-bounce-reply\fR"
+/*	Use \fIhard-bounce-reply\fR for hard reject responses.  The
+/*	default reply is "500 5.3.0 Error: command failed".
 /* .IP \fB-c\fR
 /*	Display running counters that are updated whenever an SMTP
 /*	session ends, a QUIT command is executed, or when "." is
@@ -326,9 +332,14 @@ typedef struct SINK_STATE {
 #define DEF_MAX_CLIENT_COUNT	256
 #endif
 
+#define SOFT_ERROR_RESP		"450 4.3.0 Error: command failed"
+#define HARD_ERROR_RESP		"500 5.3.0 Error: command failed"
+
 static int var_tmout = 100;
 static int var_max_line_length = 2048;
 static char *var_myhostname;
+static char *soft_error_resp = SOFT_ERROR_RESP;
+static char *hard_error_resp = HARD_ERROR_RESP;
 static int command_read(SINK_STATE *);
 static int data_read(SINK_STATE *);
 static void disconnect(SINK_STATE *);
@@ -360,9 +371,6 @@ static VSTRING *start_string;		/* dump content prefix */
 
 static INET_PROTO_INFO *proto_info;
 
-#define SOFT_ERROR_RESP		"450 4.3.0 Error: command failed"
-#define HARD_ERROR_RESP		"500 5.3.0 Error: command failed"
-
 #define STR(x)	vstring_str(x)
 
 /* do_stats - show counters */
@@ -378,7 +386,7 @@ static void do_stats(void)
 
 static void hard_err_resp(SINK_STATE *state)
 {
-    smtp_printf(state->stream, HARD_ERROR_RESP);
+    smtp_printf(state->stream, hard_error_resp);
     smtp_flush(state->stream);
 }
 
@@ -386,7 +394,7 @@ static void hard_err_resp(SINK_STATE *state)
 
 static void soft_err_resp(SINK_STATE *state)
 {
-    smtp_printf(state->stream, SOFT_ERROR_RESP);
+    smtp_printf(state->stream, soft_error_resp);
     smtp_flush(state->stream);
 }
 
@@ -737,9 +745,9 @@ static void dot_resp_hard(SINK_STATE *state)
 {
     if (enable_lmtp) {
 	while (state->rcpts-- > 0)	/* XXX this could block */
-	    smtp_printf(state->stream, HARD_ERROR_RESP);
+	    smtp_printf(state->stream, hard_error_resp);
     } else {
-	smtp_printf(state->stream, HARD_ERROR_RESP);
+	smtp_printf(state->stream, hard_error_resp);
     }
     smtp_flush(state->stream);
 }
@@ -750,9 +758,9 @@ static void dot_resp_soft(SINK_STATE *state)
 {
     if (enable_lmtp) {
 	while (state->rcpts-- > 0)	/* XXX this could block */
-	    smtp_printf(state->stream, SOFT_ERROR_RESP);
+	    smtp_printf(state->stream, soft_error_resp);
     } else {
-	smtp_printf(state->stream, SOFT_ERROR_RESP);
+	smtp_printf(state->stream, soft_error_resp);
     }
     smtp_flush(state->stream);
 }
@@ -1367,7 +1375,7 @@ static void connect_event(int unused_event, char *unused_context)
 
 static void usage(char *myname)
 {
-    msg_fatal("usage: %s [-468acCeEFLpPv] [-A abort_delay] [-d dump-template] [-D dump-template] [-f commands] [-h hostname] [-m max_concurrency] [M message_quit_count] [-n quit_count] [-q commands] [-r commands] [-R root-dir] [-s commands] [-S start-string] [-u user_privs] [-w delay] [host]:port backlog", myname);
+    msg_fatal("usage: %s [-468acCeEFLpPv] [-A abort_delay] [-b soft_bounce_reply] [-B hard_bounce_reply] [-d dump-template] [-D dump-template] [-f commands] [-h hostname] [-m max_concurrency] [-M message_quit_count] [-n quit_count] [-q commands] [-r commands] [-R root-dir] [-s commands] [-S start-string] [-u user_privs] [-w delay] [host]:port backlog", myname);
 }
 
 MAIL_VERSION_STAMP_DECLARE;
@@ -1399,7 +1407,7 @@ int     main(int argc, char **argv)
     /*
      * Parse JCL.
      */
-    while ((ch = GETOPT(argc, argv, "468aA:cCd:D:eEf:Fh:Ln:m:M:pPq:Q:r:R:s:S:t:T:u:vw:W:")) > 0) {
+    while ((ch = GETOPT(argc, argv, "468aA:b:B:cCd:D:eEf:Fh:Ln:m:M:pPq:Q:r:R:s:S:t:T:u:vw:W:")) > 0) {
 	switch (ch) {
 	case '4':
 	    protocols = INET_PROTO_NAME_IPV4;
@@ -1417,6 +1425,20 @@ int     main(int argc, char **argv)
 	    if (!alldig(optarg) || (abort_delay = atoi(optarg)) < 0)
 		usage(argv[0]);
 	    break;
+	case 'b':
+	    if (optarg[0] != '4' || strspn(optarg, "0123456789") != 3) {
+		msg_error("bad soft error reply: %s", optarg);
+		usage(argv[0]);
+	    } else
+		soft_error_resp = optarg;
+	    break;
+	case 'B':
+	    if (optarg[0] != '5' || strspn(optarg, "0123456789") != 3) {
+		msg_error("bad hard error reply: %s", optarg);
+		usage(argv[0]);
+	    } else
+		hard_error_resp = optarg;
+	    break;
 	case 'c':
 	    count++;
 	    break;
diff --git a/postfix/src/tls/tls_certkey.c b/postfix/src/tls/tls_certkey.c
index caf9af44a..913b67e23 100644
--- a/postfix/src/tls/tls_certkey.c
+++ b/postfix/src/tls/tls_certkey.c
@@ -158,7 +158,7 @@ int     tls_set_my_certificate_key_info(SSL_CTX *ctx,
 	return (-1);			/* logged */
     if (*dcert_file && !set_cert_stuff(ctx, "DSA", dcert_file, dkey_file))
 	return (-1);				/* logged */
-#if OPENSSL_VERSION_NUMBER >= 0x00909000 && !defined(OPENSSL_NO_ECDH)
+#if OPENSSL_VERSION_NUMBER >= 0x1000000fL && !defined(OPENSSL_NO_ECDH)
     if (*eccert_file && !set_cert_stuff(ctx, "ECDSA", eccert_file, eckey_file))
 	return (-1);				/* logged */
 #else
diff --git a/postfix/src/tls/tls_client.c b/postfix/src/tls/tls_client.c
index 455561e12..7fd32d478 100644
--- a/postfix/src/tls/tls_client.c
+++ b/postfix/src/tls/tls_client.c
@@ -725,7 +725,7 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
     int     protomask;
     const char *cipher_list;
     SSL_SESSION *session;
-    SSL_CIPHER *cipher;
+    const SSL_CIPHER *cipher;
     X509   *peercert;
     TLS_SESS_STATE *TLScontext;
     TLS_APPL_STATE *app_ctx = props->ctx;
diff --git a/postfix/src/tls/tls_dh.c b/postfix/src/tls/tls_dh.c
index bc5db4f0d..da17be73a 100644
--- a/postfix/src/tls/tls_dh.c
+++ b/postfix/src/tls/tls_dh.c
@@ -205,7 +205,7 @@ DH     *tls_tmp_dh_cb(SSL *unused_ssl, int export, int keylength)
 
 int     tls_set_eecdh_curve(SSL_CTX *server_ctx, const char *grade)
 {
-#if OPENSSL_VERSION_NUMBER >= 0x00909000 && !defined(OPENSSL_NO_ECDH)
+#if OPENSSL_VERSION_NUMBER >= 0x1000000fL && !defined(OPENSSL_NO_ECDH)
     int     nid;
     EC_KEY *ecdh;
     const char *curve;
diff --git a/postfix/src/tls/tls_server.c b/postfix/src/tls/tls_server.c
index 26ea2afe4..9ed6d20ed 100644
--- a/postfix/src/tls/tls_server.c
+++ b/postfix/src/tls/tls_server.c
@@ -554,7 +554,7 @@ TLS_SESS_STATE *tls_server_start(const TLS_SERVER_START_PROPS *props)
 {
     int     sts;
     TLS_SESS_STATE *TLScontext;
-    SSL_CIPHER *cipher;
+    const SSL_CIPHER *cipher;
     X509   *peer;
     char    buf[CCERT_BUFSIZ];
     const char *cipher_list;
diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in
index 653919c85..87c006ca7 100644
--- a/postfix/src/util/Makefile.in
+++ b/postfix/src/util/Makefile.in
@@ -32,7 +32,7 @@ SRCS	= alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
 	write_buf.c write_wait.c sane_basename.c format_tv.c allspace.c \
 	allascii.c load_file.c killme_after.c vstream_tweak.c upass_connect.c \
 	upass_listen.c upass_trigger.c edit_file.c inet_windowsize.c \
-	unix_pass_fd_fix.c dict_cache.c
+	unix_pass_fd_fix.c dict_cache.c valid_utf_8.c
 OBJS	= alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
 	attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
 	attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
@@ -66,7 +66,7 @@ OBJS	= alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
 	write_buf.o write_wait.o sane_basename.o format_tv.o allspace.o \
 	allascii.o load_file.o killme_after.o vstream_tweak.o upass_connect.o \
 	upass_listen.o upass_trigger.o edit_file.o inet_windowsize.o \
-	unix_pass_fd_fix.o dict_cache.o
+	unix_pass_fd_fix.o dict_cache.o valid_utf_8.o
 HDRS	= argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
 	chroot_uid.h cidr_match.h clean_env.h connect.h ctable.h dict.h \
 	dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \
@@ -104,7 +104,7 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
 	attr_scan0 host_port attr_scan_plain attr_print_plain htable \
 	unix_recv_fd unix_send_fd stream_recv_fd stream_send_fd hex_code \
 	myaddrinfo myaddrinfo4 inet_proto sane_basename format_tv \
-	test_send_fd test_recv_fd
+	test_send_fd test_recv_fd valid_utf_8
 
 LIB_DIR	= ../../lib
 INC_DIR	= ../../include
@@ -414,6 +414,11 @@ format_tv: $(LIB)
 	$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
 	mv junk $@.o
 
+valid_utf_8: $(LIB)
+	mv $@.o junk
+	$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
+	mv junk $@.o
+
 tests: valid_hostname_test mac_expand_test dict_test unescape_test \
 	hex_quote_test ctable_test inet_addr_list_test base64_code_test \
 	attr_scan64_test attr_scan0_test dict_pcre_test host_port_test \
@@ -1638,6 +1643,10 @@ valid_hostname.o: valid_hostname.c
 valid_hostname.o: valid_hostname.h
 valid_hostname.o: vbuf.h
 valid_hostname.o: vstring.h
+valid_utf_8.o: stringops.h
+valid_utf_8.o: valid_utf_8.c
+valid_utf_8.o: vbuf.h
+valid_utf_8.o: vstring.h
 vbuf.o: sys_defs.h
 vbuf.o: vbuf.c
 vbuf.o: vbuf.h
diff --git a/postfix/src/util/dict_db.c b/postfix/src/util/dict_db.c
index e4b301d10..9e82f9b81 100644
--- a/postfix/src/util/dict_db.c
+++ b/postfix/src/util/dict_db.c
@@ -675,7 +675,7 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
 	msg_fatal("set DB cache size %d: %m", dict_db_cache_size);
     if (type == DB_HASH && db->set_h_nelem(db, DICT_DB_NELM) != 0)
 	msg_fatal("set DB hash element count %d: %m", DICT_DB_NELM);
-#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0)
+#if DB_VERSION_MAJOR == 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0)
     if ((errno = db->open(db, 0, db_path, 0, type, db_flags, 0644)) != 0)
 	msg_fatal("open database %s: %m", db_path);
 #elif (DB_VERSION_MAJOR == 3 || DB_VERSION_MAJOR == 4)
diff --git a/postfix/src/util/match_list.c b/postfix/src/util/match_list.c
index 8bb6dc5a8..7832e95ea 100644
--- a/postfix/src/util/match_list.c
+++ b/postfix/src/util/match_list.c
@@ -116,6 +116,11 @@ static ARGV *match_list_parse(ARGV *list, char *string, int init_match)
      * prepend the negation operator to each item from the file.
      */
     while ((start = mystrtok(&bp, delim)) != 0) {
+	if (*start == '#') {
+	    msg_warn("%s: comment at end of line is not supported: %s %s",
+		      myname, start, bp);
+	    break;
+	}
 	for (match = init_match, item = start; *item == '!'; item++)
 	    match = !match;
 	if (*item == 0)
diff --git a/postfix/src/util/stringops.h b/postfix/src/util/stringops.h
index 8f96aa4b7..85d2a747e 100644
--- a/postfix/src/util/stringops.h
+++ b/postfix/src/util/stringops.h
@@ -41,6 +41,7 @@ extern int allprint(const char *);
 extern int allspace(const char *);
 extern int allascii(const char *);
 extern const char *split_nameval(char *, char **, char **);
+extern int valid_utf_8(const char *, ssize_t);
 
 /* LICENSE
 /* .ad
diff --git a/postfix/src/util/sys_defs.h b/postfix/src/util/sys_defs.h
index 026901cb6..f000c2d7b 100644
--- a/postfix/src/util/sys_defs.h
+++ b/postfix/src/util/sys_defs.h
@@ -208,7 +208,6 @@
 #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
@@ -1502,6 +1501,20 @@ typedef int pid_t;
 #else
 #define PRINTFPTRLIKE(x,y)
 #endif
+#endif
+
+ /*
+  * Compiler optimization hint. This makes sense only for code in a
+  * performance-critical loop.
+  */
+#ifndef EXPECTED
+#if defined(__GNUC__) && (__GNUC__ > 2)
+#define EXPECTED(x)	__builtin_expect(!!(x), 1)
+#define UNEXPECTED(x)	__builtin_expect(!!(x), 0)
+#else
+#define EXPECTED(x)	(x)
+#define UNEXPECTED(x)	(x)
+#endif
 #endif
 
  /*
diff --git a/postfix/src/util/valid_utf_8.c b/postfix/src/util/valid_utf_8.c
new file mode 100644
index 000000000..f953e63c8
--- /dev/null
+++ b/postfix/src/util/valid_utf_8.c
@@ -0,0 +1,139 @@
+/*++
+/* NAME
+/*	valid_utf_8 3
+/* SUMMARY
+/*	predicate if string is valid UTF-8
+/* SYNOPSIS
+/*	#include 
+/*
+/*	int	valid_utf_8(str, len)
+/*	const char *str;
+/*	ssize_t	len;
+/* DESCRIPTION
+/*	valid_utf_8() determines if a string satisfies the UTF-8
+/*	definition in RFC 3629. That is, it contains proper encodings
+/*	of code points U+0000..U+10FFFF, excluding over-long encodings
+/*	and excluding U+D800..U+DFFF surrogates.
+/*
+/*	A zero-length string is considered valid.
+/* DIAGNOSTICS
+/*	The result value is zero when the caller specifies a negative
+/*	length, or a string that violates RFC 3629, for example a
+/*	string that is truncated in the middle of a multi-byte
+/*	sequence.
+/* BUGS
+/*	But wait, there is more. Code points in the range U+FDD0..U+FDEF
+/*	and ending in FFFE or FFFF are non-characters in UNICODE. This
+/*	function does not block these.
+/* SEE ALSO
+/*	RFC 3629
+/* LICENSE
+/* .ad
+/* .fi
+/*	The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*	Wietse Venema
+/*	IBM T.J. Watson Research
+/*	P.O. Box 704
+/*	Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include 
+
+/* Utility library. */
+
+#include 
+
+/* valid_utf_8 - validate string according to RFC 3629 */
+
+int     valid_utf_8(const char *str, ssize_t len)
+{
+    const unsigned char *end = (const unsigned char *) str + len;
+    const unsigned char *cp;
+    unsigned char c0, ch;
+
+    if (len < 0)
+	return (0);
+    if (len <= 0)
+	return (1);
+
+    /*
+     * Optimized for correct input, time, space, and for CPUs that have a
+     * decent number of registers.
+     */
+    for (cp = (const unsigned char *) str; cp < end; cp++) {
+	/* Single-byte encodings. */
+	if (EXPECTED((c0 = *cp) <= 0x7f) /* we know that c0 >= 0x0 */ ) {
+	     /* void */ ;
+	}
+	/* Two-byte encodings. */
+	else if (EXPECTED(c0 <= 0xdf) /* we know that c0 >= 0x80 */ ) {
+	    /* Exclude over-long encodings. */
+	    if (UNEXPECTED(c0 < 0xc2)
+		|| UNEXPECTED(cp + 1 >= end)
+	    /* Require UTF-8 tail byte. */
+		|| UNEXPECTED((ch = *++cp) < 0x80) || UNEXPECTED(ch > 0xbf))
+		return (0);
+	}
+	/* Three-byte encodings. */
+	else if (EXPECTED(c0 <= 0xef) /* we know that c0 >= 0xe0 */ ) {
+	    if (UNEXPECTED(cp + 2 >= end)
+	    /* Exclude over-long encodings. */
+		|| UNEXPECTED((ch = *++cp) < (c0 == 0xe0 ? 0xa0 : 0x80))
+	    /* Exclude U+D800..U+DFFF. */
+		|| UNEXPECTED(ch > (c0 == 0xed ? 0x9f : 0xbf))
+	    /* Require UTF-8 tail byte. */
+		|| UNEXPECTED((ch = *++cp) < 0x80) || UNEXPECTED(ch > 0xbf))
+		return (0);
+	}
+	/* Four-byte encodings. */
+	else if (EXPECTED(c0 <= 0xf4) /* we know that c0 >= 0xf0 */ ) {
+	    if (UNEXPECTED(cp + 3 >= end)
+	    /* Exclude over-long encodings. */
+		|| UNEXPECTED((ch = *++cp) < (c0 == 0xf0 ? 0x90 : 0x80))
+	    /* Exclude code points above U+10FFFF. */
+		|| UNEXPECTED(ch > (c0 == 0xf4 ? 0x8f : 0xbf))
+	    /* Require UTF-8 tail byte. */
+		|| UNEXPECTED((ch = *++cp) < 0x80) || UNEXPECTED(ch > 0xbf)
+	    /* Require UTF-8 tail byte. */
+		|| UNEXPECTED((ch = *++cp) < 0x80) || UNEXPECTED(ch > 0xbf))
+		return (0);
+	}
+	/* Invalid: c0 >= 0xf5 */
+	else {
+	    return (0);
+	}
+    }
+    return (1);
+}
+
+ /*
+  * Stand-alone test program. Each string is a line without line terminator.
+  */
+#ifdef TEST
+#include 
+#include 
+#include 
+#include 
+
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+int     main(void)
+{
+    VSTRING *buf = vstring_alloc(1);
+
+    while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
+	vstream_printf("%c", (LEN(buf) && !valid_utf_8(STR(buf), LEN(buf))) ?
+		       '!' : ' ');
+	vstream_fwrite(VSTREAM_OUT, STR(buf), LEN(buf));
+	vstream_printf("\n");
+    }
+    vstream_fflush(VSTREAM_OUT);
+    vstring_free(buf);
+    exit(0);
+}
+
+#endif