From: Wietse Venema 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.
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. To test this over a connection that is encrypted with TLS, use
+ Instead of
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. 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
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...
+
+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.
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:
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.
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.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.This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
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.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.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 inThis 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 hasWhat 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.
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: 1How 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: 1The 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: 1The 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: 10sThe 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.pemThis 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.pemThis 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:
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