diff --git a/postfix/HISTORY b/postfix/HISTORY index d1aa037c4..d0327940d 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -6980,21 +6980,23 @@ Apologies for any names omitted. 20020919 - Feature: reject_rbl for client address blacklisting + Feature: "reject_rbl " for client address blacklisting by LaMont Jones, including $name expansion for per-domain customized response messages. The obsolete reject_maps_rbl is now a wrapper that uses the new code. 20020921 - Internal: added caching and reject reporting that can be - used for both reject_rbl and for the upcoming reject_rhsbl. + Internal: added caching and factored out common code that + will be used for both reject_rbl and for the upcoming + reject_rhsbl restriction. 20020922 - Feature: reject_rhsbl for sender domain blacklisting. - Provides the same per-domain customized response message - mechanisms with $name expansion as reject_rbl. + Feature: "reject_rhsbl " for sender domain + blacklisting. Provides the same per-domain customized + response message mechanisms with $name expansion as + reject_rbl. Safety: the smtpd_expansion_filter parameter controls what characters are allowed in the expansion of $name macros in @@ -7006,6 +7008,16 @@ Apologies for any names omitted. result (i.e. the name does exist) will no longer cause ${name?text} to succeed. File: util/mac_expand.c. +20020923 + + Cleanup. Renamed the RBL features according to a scheme + that was suggested by Liviu Daia in October 2001. The + names are reject_rbl_client and reject_rhsbl_sender, + respectively. Added domain name based reject_rhsbl_client + and reject_rhsbl_recipient restrictions for completeness. + The reject_rbl restriction name is still recognized for + compatibility with systems maintained by LaMont Jones. + Open problems: Low: smtpd should log queue ID with reject/warn/hold/discard diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 3e6d36232..96b0afbcb 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -12,33 +12,43 @@ snapshot release). Patches change the patchlevel and the release date. Snapshots change only the release date, unless they include the same bugfixes as a patch release. -Incompatible changes with Postfix snapshot 1.1.11-20020922 +Incompatible changes with Postfix snapshot 1.1.11-20020923 ========================================================== Subtle change in ${name:result} macro expansions: the expansion -no longer happens when $name is an empty string. +no longer happens when $name is an empty string. This probably +makes more sense than the old behavior. -Major changes with Postfix snapshot 1.1.11-20020922 +The default RBL "reject" server reply now includes an indication +of *what* is being rejected: Client host, Helo command, Sender +address, or Recipient address. + +Major changes with Postfix snapshot 1.1.11-20020923 =================================================== -Complete rewrite of RBL internals to avoid unnecessary code -duplication and to implement caching of results. +Complete rewrite of the RBL blacklisting code. The names of RBL +restrictions are now based on a suggestion that was made by Liviu +Daia in October 2001. See conf/sample-smtpd.cf or html/uce.html +for details. -Feature: "reject_rbl rbl.domain.tld" for client IP address -blacklisting. The old "reject_maps_rbl" is now implemented as a -wrapper around the reject_rbl code. Based on code by LaMont Jones. +Feature: "reject_rbl_client rbl.domain.tld" for client IP address +blacklisting. Based on code by LaMont Jones. The old "reject_maps_rbl" +is now implemented as a wrapper around the reject_rbl_client code. -Feature: "reject_rhsbl rbl.domain.tld" for sender domain based -blacklisting. +Feature: "reject_rhsbl_sender rbl.domain.tld" for sender domain +blacklisting. Also: reject_rhsbl_client and reject_rhsbl_recipient +for client and recipient domain blacklisting. "rbl_reply_maps" configuration parameter for lookup tables with -template responses per RBL server. The template responses support -$name expansion of client, helo, sender, recipient and RBL server -attributes. See sample-smtpd.cf for details. Based on code by LaMont -Jones. +template responses per RBL server. Based on code by LaMont Jones. +If no reply template is found the default template is used as +specified with the default_rbl_reply configuration parameter. The +template responses support $name expansion of client, helo, sender, +recipient and RBL related attributes. "smtpd_expansion_filter" configuration parameter to control what -characters are allowed in the expansion of $name macros. +characters are allowed in the expansion of template reply $name +macros. Characters outside the allowed set are replaced by "_". Incompatible changes with Postfix snapshot 1.1.11-20020917 ========================================================== diff --git a/postfix/conf/sample-smtpd.cf b/postfix/conf/sample-smtpd.cf index 671b3aa74..d2c1ff794 100644 --- a/postfix/conf/sample-smtpd.cf +++ b/postfix/conf/sample-smtpd.cf @@ -9,29 +9,29 @@ # # The smtpd_sender_login_maps parameter specifies the (SASL) login -# name that owns a sender (MAIL FROM) address. -# +# name that owns a sender (MAIL FROM) address. +# # Specify zero or more maptype:mapname entries. Maps are created with # postmap(1) or with equivalent means. The maps are searched in the # specified order. Regexp tables are allowed. -# +# # Each map entry specifies a sender address and the login name that # owns the address. The search order is: -# +# # 1) user@domain owner -# +# # This form has the highest precedence. -# +# # 2) user owner -# +# # This matches user@site when site is equal to $myorigin, when site # is listed in $mydestination, or when it is listed in $inet_interfaces. -# +# # 3) @domain owner -# +# # This matches every address in the specified domain, and has the # lowest precedence. -# +# #smtpd_sender_login_maps = # @@ -66,21 +66,26 @@ smtpd_banner = $myhostname ESMTP $mail_name # reject_unknown_client: reject the request if the client hostname is unknown. # permit_mynetworks: permit if the client address matches $mynetworks. # check_client_access maptype:mapname -# maptype:mapname: look up client name, parent domains, client address, +# look up client name, parent domains, client address, # or networks obtained by stripping octets. # Reject if result is REJECT or "[45]xx text" # Permit if result is OK or all numerical. -# reject_maps_rbl: reject if the reverse client network address -# is listed under $maps_rbl_domains. +# reject_rbl_client domain.tld: reject if the reverse client network +# address is listed in an A record under domain.tld. +# reject_rhsbl_client domain.tld: reject if the client hostname is listed +# in an A record under domain.tld. # reject: reject the request. Place this at the end of a restriction. # permit: permit the request. Place this at the end of a restriction. # warn_if_reject: next restriction logs a warning instead of rejecting. +# +# You may also list any helo or client restrictions here (see below). +# smtpd_etrn_restrictions = # The smtpd_history_flush_threshold specifies how many lines the SMTP # server command history is allowed to contain before it is flushed # to postmaster upon receipt of EHLO, RSET, or end of DATA. -# +# smtpd_history_flush_threshold = 100 # The smtpd_noop_commands parameter specifies a list of commands that @@ -111,9 +116,9 @@ smtpd_timeout = 300s # are specified within <>, and that MAIL FROM and RCPT TO addresses # do not contain RFC822-style comments or phrases. It's great to # stop SPAM mailers. But it also trips up broken peecee clients. -# +# # By default, Postfix SMTPD allows RFC822 syntax in MAIL FROM and RCPT TO. -# +# strict_rfc821_envelopes = no # @@ -156,16 +161,16 @@ smtpd_hard_error_limit = 20 # # By default (mynetworks_style = subnet), Postfix "trusts" SMTP # clients in the same IP subnetworks as the local machine. -# +# # Specify "mynetworks_style = class" when Postfix should "trust" SMTP # clients in the same IP class A/B/C networks as the local machine. # Don't do this with a dialup site - it would cause Postfix to "trust" # your entire provider's network. Instead, specify an explicit # mynetworks list by hand, as described below. -# +# # Specify "mynetworks_style = host" when Postfix should "trust" # only the local machine. -# +# #mynetworks_style = class mynetworks_style = subnet #mynetworks_style = host @@ -194,11 +199,14 @@ mynetworks_style = subnet # reject_unknown_client: reject the request if the client hostname is unknown. # permit_mynetworks: permit if the client address matches $mynetworks. # check_client_access maptype:mapname -# maptype:mapname: look up client name, parent domains, client address, +# look up client name, parent domains, client address, # or networks obtained by stripping octets. # Reject if result is REJECT or "[45]xx text" # Permit if result is OK or all numerical. -# reject_maps_rbl: reject if the client is listed under $maps_rbl_domains. +# reject_rbl_client domain.tld: reject if the reversed client IP address +# is listed in an A record under domain.tld. +# reject_rhsbl_client domain.tld: reject if the client hostname is listed +# in an A record under domain.tld. # reject: reject the request. Place this at the end of a restriction. # permit: permit the request. Place this at the end of a restriction. # warn_if_reject: next restriction logs a warning instead of rejecting. @@ -206,12 +214,15 @@ mynetworks_style = subnet # Restrictions are applied in the order as specified; the first # restriction that matches wins. # +# You may also list any helo, sender or recipient restrictions here. +# These will have effect only when smtpd_delay_reject=yes, so that all +# restrictions are evaluated at the time of the RCPT TO command. +# # Specify a list of restrictions, separated by commas and/or whitespace. # Continue long lines by starting the next line with whitespace. # #smtpd_client_restrictions = permit_mynetworks, reject_unknown_client -#smtpd_client_restrictions = reject_maps_rbl, reject_unknown_client -smtpd_client_restrictions = +smtpd_client_restrictions = # The smtpd_helo_required parameter optionally turns on the requirement # that SMTP clients must introduce themselves at the beginning of an @@ -227,16 +238,13 @@ smtpd_helo_required = no # are available: # # permit_mynetworks: permit if the client address matches $mynetworks. -# reject_unknown_client: reject the request if the client hostname is unknown. -# reject_maps_rbl: reject if the client is listed under $maps_rbl_domains. # reject_invalid_hostname: reject HELO hostname with bad syntax. # reject_unknown_hostname: reject HELO hostname without DNS A or MX record. # reject_non_fqdn_hostname: reject HELO hostname that is not in FQDN form # check_helo_access maptype:mapname -# maptype:mapname: look up HELO hostname or parent domains. +# look up HELO hostname or parent domains. # Reject if result is REJECT or "[45]xx text" # Permit if result is OK or all numerical. -# check_client_access maptype:mapname: see smtpd_client_restrictions. # reject: reject the request. Place this at the end of a restriction. # permit: permit the request. Place this at the end of a restriction. # warn_if_reject: next restriction logs a warning instead of rejecting. @@ -244,37 +252,37 @@ smtpd_helo_required = no # Restrictions are applied in the order as specified; the first # restriction that matches wins. # +# You may also list any client, sender or recipient restrictions here. +# Sender and recipient restrictions will have effect only when +# smtpd_delay_reject=yes, so that all restrictions are evaluated at +# the time of the RCPT TO command. +# # Specify a list of restrictions, separated by commas and/or whitespace. # Continue long lines by starting the next line with whitespace. # #smtpd_helo_restrictions = permit_mynetworks, reject_invalid_hostname #smtpd_helo_restrictions = permit_mynetworks, reject_unknown_hostname -smtpd_helo_restrictions = +smtpd_helo_restrictions = # The smtpd_sender_restrictions parameter specifies optional restrictions # on sender addresses that SMTP clients can send in MAIL FROM commands. -# +# # The default is to permit any sender address. The following # restrictions are available: # # permit_mynetworks: permit if the client address matches $mynetworks. -# reject_unknown_client: reject the request if the client hostname is unknown. -# reject_maps_rbl: reject if the client is listed under $maps_rbl_domains. -# reject_invalid_hostname: reject HELO hostname with bad syntax. -# reject_unknown_hostname: reject HELO hostname without DNS A or MX record. # reject_unknown_sender_domain: reject sender domain without A or MX record. +# reject_rhsbl_sender domain.tld: reject sender domain name if it is listed +# in an A record under domain.tld. # check_sender_access maptype:mapname -# maptype:mapname: look up sender address, parent domain, or localpart@. +# look up sender address, parent domain, or localpart@. # Reject if result is REJECT or "[45]xx text" # Permit if result is OK or all numerical. -# check_client_access maptype:mapname: see smtpd_client_restrictions. -# check_helo_access maptype:mapname: see smtpd_helo_restrictions. # reject_sender_login_mismatch: reject if $smtpd_sender_login_maps specifies # a MAIL FROM address owner, but the client is not (SASL) logged in as # that MAIL FROM address owner; or if the client is (SASL) logged in, but # the client login name doesn't own the MAIL FROM address according to # $smtpd_sender_login_maps (see above). -# reject_non_fqdn_hostname: reject HELO hostname that is not in FQDN form # reject_non_fqdn_sender: reject sender address that is not in FQDN form # reject: reject the request. Place this at the end of a restriction. # permit: permit the request. Place this at the end of a restriction. @@ -283,16 +291,21 @@ smtpd_helo_restrictions = # Restrictions are applied in the order as specified; the first # restriction that matches wins. # +# You may also list any helo, client or recipient restrictions here. +# Recipient restrictions will have effect only when smtpd_delay_reject=yes, +# so that all restrictions are evaluated at the time of the RCPT TO +# command. +# # Specify a list of restrictions, separated by commas and/or whitespace. # Continue long lines by starting the next line with whitespace. # #smtpd_sender_restrictions = reject_unknown_sender_domain #smtpd_sender_restrictions = reject_unknown_sender_domain, hash:/etc/postfix/access -smtpd_sender_restrictions = +smtpd_sender_restrictions = # The smtpd_recipient_restrictions parameter specifies restrictions on # recipient addresses that SMTP clients can send in RCPT TO commands. -# +# # By default, Postfix relays mail # - from trusted clients whose IP address matches $mynetworks, # - from trusted clients matching $relay_domains or subdomains thereof, @@ -306,29 +319,27 @@ smtpd_sender_restrictions = # - destinations that match $mydestination # - destinations that match $virtual_maps. # These destinations do not need to be listed in $relay_domains. -# +# # The following restrictions are available (* is part of default setting): # # *permit_mynetworks: permit if the client address matches $mynetworks. -# reject_unknown_client: reject the request if the client hostname is unknown. -# reject_maps_rbl: reject if the client is listed under $maps_rbl_domains. -# reject_invalid_hostname: reject HELO hostname with bad syntax. -# reject_unknown_hostname: reject HELO hostname without DNS A or MX record. # reject_unknown_sender_domain: reject sender domain without A or MX record. -# *check_relay_domains: permit only mail -# - to destinations matching $inet_interfaces, $mydestination, +# reject_rhsbl_recipient domain.tld: reject recipient domain name if it is +# listed in an A record under domain.tld. +# *check_relay_domains: permit only mail +# - to destinations matching $inet_interfaces, $mydestination, # or $virtual_maps, # - from trusted clients matching $relay_domains or subdomain thereof, # - from untrusted clients to destinations matching $relay_domains or # subdomain thereof (except addresses with sender-specified routing), # Reject anything else. -# permit_auth_destination: permit mail -# - to destinations matching $inet_interfaces, $mydestination, +# permit_auth_destination: permit mail +# - to destinations matching $inet_interfaces, $mydestination, # or $virtual_maps. # - to destinations matching $relay_domains or subdomain thereof, # except for addresses with sender-specified routing. -# reject_unauth_destination: reject mail unless it is sent -# - to destinations matching $inet_interfaces, $mydestination, +# reject_unauth_destination: reject mail unless it is sent +# - to destinations matching $inet_interfaces, $mydestination, # or $virtual_maps. # - to destinations matching $relay_domains or subdomain thereof, # except for addresses with sender-specified routing. @@ -338,19 +349,9 @@ smtpd_sender_restrictions = # require that the primary MX hosts match a list of network blocks. # reject_unknown_recipient_domain: reject domains without A or MX record. # check_recipient_access maptype:mapname -# maptype:mapname: look up recipient address, parent domain, or localpart@. +# look up recipient address, parent domain, or localpart@. # Reject if result is REJECT or "[45]xx text" # Permit if result is OK or all numerical. -# check_client_access maptype:mapname: see smtpd_client_restrictions. -# check_helo_access maptype:mapname: see smtpd_helo_restrictions. -# check_sender_access maptype:mapname: see smtpd_sender_restrictions. -# reject_sender_login_mismatch: reject if $smtpd_sender_login_maps specifies -# a MAIL FROM address owner, but the client is not (SASL) logged in as -# that MAIL FROM address owner; or if the client is (SASL) logged in, but -# the client login name doesn't own the MAIL FROM address according to -# $smtpd_sender_login_maps (see above). -# reject_non_fqdn_hostname: reject HELO hostname that is not in FQDN form -# reject_non_fqdn_sender: reject sender address that is not in FQDN form # reject_non_fqdn_recipient: reject recipient address that is not in FQDN form # reject: reject the request. Place this at the end of a restriction. # permit: permit the request. Place this at the end of a restriction. @@ -359,6 +360,8 @@ smtpd_sender_restrictions = # Restrictions are applied in the order as specified; the first # restriction that matches wins. # +# You may also list any helo, client or sender restrictions here. +# # Specify a list of restrictions, separated by commas and/or whitespace. # Continue long lines by starting the next line with whitespace. # @@ -376,7 +379,7 @@ smtpd_recipient_restrictions = permit_mynetworks,check_relay_domains # forward mail with sender-specified routing (user[@%!]remote[@%!]site) # from untrusted clients to destinations that are blessed by the # relay_domains parameter. -# +# # By default, untrusted clients are not allowed to specify routing. # This closes a nasty open relay loophole where a backup MX host can # be tricked into forwarding junk mail to a primary MX host which @@ -388,35 +391,22 @@ smtpd_recipient_restrictions = permit_mynetworks,check_relay_domains # allow_untrusted_routing = no -# The maps_rbl_domains parameter specifies an optional list of DNS -# domains that publish the network addresses of blacklisted hosts. -# -# By default, RBL blacklist lookups are disabled. See the -# smtpd_client_restrictions parameter. -# -# The real-time blackhole list works as follows: reverse the client -# network address, and reject service if it is listed below any of -# the following domains. -# -#maps_rbl_domains = blackholes.mail-abuse.org relays.mail-abuse.org -maps_rbl_domains = blackholes.mail-abuse.org - # The relay_domains parameter restricts what client hostname domains # (and subdomains thereof) this mail system will relay mail from, # and restricts what destination domains (and subdomains thereof) # this system will relay mail to. -# +# # By default, Postfix relays mail -# - from trusted clients whose IP address matches $mynetworks, +# - from trusted clients whose IP address matches $mynetworks, # - from trusted clients matching $relay_domains or subdomains thereof, # - from untrusted clients to destinations that match $relay_domains # or subdomains thereof, except addresses with sender-specified routing. -# The default relay_domains value is $mydestination. -# -# In addition to the above, the Postfix SMTP server by default accepts mail +# The default relay_domains value is $mydestination. +# +# In addition to the above, the Postfix SMTP server by default accepts mail # that Postfix is final destination for: -# - destinations that match $inet_interfaces, -# - destinations that match $mydestination +# - destinations that match $inet_interfaces, +# - destinations that match $mydestination # - destinations that match $virtual_maps. # These destinations do not need to be listed in $relay_domains. # @@ -444,6 +434,44 @@ relay_domains = $mydestination # access_map_reject_code = 550 +# The default_rbl_reply parameter specifies the SMTP server response +# when an SMTP client request is rejected by a reject_rbl or reject_rhsbl +# restriction. +# +# The template is subject to exactly one level of $name substitution: +# +# $client: client hostname and IP address, formatted as name[address]. +# $client_name: client hostname or unknown. +# $client_address: client IP address. +# $helo_name: hostname given in HELO or EHLO command or empty string. +# $sender: sender address or <> in case of the null address. +# $sender_name: sender address localpart or <> in case of the null address. +# $sender_domain: sender address domain or empty string. +# $recipient: recipient address or <> in case of the null address. +# $recipient_name: recipient address localpart or <> in case of null address. +# $recipient_domain: recipient address domain or empty string. +# $rbl_what: the entity that is blacklisted (an IP address, a hostname, +# a domain name, or an email address whose domain was blacklisted). +# $rbl_reason: reason why $rbl_what is blacklisted or empty string. +# $rbl_domain: RBL domain where $rbl_what is blacklisted. +# $rbl_class: the blacklisted entity type: Client host, Helo command, +# Sender address, or Recipient address. +# $rbl_code: numerical server reply code, as specified with the +# maps_rbl_reject_code configuration parameter. +# +# The smtpd_expansion_filter configuration parameter controls what +# characters may appear in $name expansions. +# +# Instead of $name you can also specify ${name} or $(name). +# +# Conditional expansion: +# +# ${name?text} expands to `text' if $name is not empty. +# ${name:text} expands to `text' if $name is empty. +# +default_rbl_reply = $rbl_code Service unavailable; $rbl_class [$rbl_what] + blocked using $rbl_domain${rbl_reason?; $rbl_reason} + # The defer_code parameter specifies the SMTP server response code # when an SMTP client request is rejected by the "defer" restriction. # @@ -460,12 +488,21 @@ defer_code = 450 invalid_hostname_reject_code = 501 # The maps_rbl_reject_code parameter specifies the SMTP server response -# when a client violates the maps_rbl_domains restriction. +# when an SMTP client request is blocked by a reject_rbl or reject_rhsbl +# restriction. # # Do not change this unless you have a complete understanding of RFC 821. # maps_rbl_reject_code = 550 +# The rbl_reply_maps parameter specifies tables with RBL response +# templates, indexed by RBL domain name. By default, Postfix uses +# the default template as specified with the default_rbl_reply +# configuration parameter. See there for a discussion of the syntax +# of RBL reply templates. +# +rbl_reply_maps = + # The reject_code parameter specifies the SMTP server response code # when an SMTP client matches a reject restriction. # @@ -480,6 +517,15 @@ reject_code = 550 # relay_domains_reject_code = 550 +# The smtpd_expansion_filter parameter specifies what characters are +# allowed in $name expansions of RBL reply templates. Characters not +# in the allowed set are replaced by "_". Use C like escapes to +# specify special characters such as whitespace. +# +# This parameter is not subjected to the usual main.cf macro expansion. +# +smtpd_expansion_filter = \t\40!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ + # The unknown_address_reject_code parameter specifies the SMTP server # response when a client violates the reject_unknown_sender_domain # or reject_unknown_recipient_domain restrictions. diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html index d5b4000f6..a040d0ae3 100644 --- a/postfix/html/smtpd.8.html +++ b/postfix/html/smtpd.8.html @@ -296,46 +296,52 @@ SMTPD(8) SMTPD(8) UCE control responses access_map_reject_code - Server response when a client violates an access + Response code when a client violates an access database restriction. + default_rbl_reply + Default template reply when a request is RBL black- + listed. This template is used by the reject_rbl_* + and reject_rhsbl_* restrictions. See also: + rbl_reply_maps and smtpd_expansion_filter. + defer_code - Server response when a client request is rejected - by the defer restriction. + Response code when a client request is rejected by + the defer restriction. invalid_hostname_reject_code - Server response when a client violates the + Response code when a client violates the reject_invalid_hostname restriction. maps_rbl_reject_code - Server response when a client violates the - maps_rbl_domains restriction. + Response code when a request is RBL blacklisted. rbl_reply_maps - Table with template responses, indexed by RBL - domain name. These templates are used by the - reject_rbl and reject_rhsbl restrictions. See also: - smtpd_expansion_filter. + Table with template responses for RBL blacklisted + requests, indexed by RBL domain name. These tem- + plates are used by the reject_rbl_* and + reject_rhsbl_* restrictions. See also: + default_rbl_reply and smtpd_expansion_filter. reject_code - Response code when the client matches a reject + Response code when the client matches a reject restriction. relay_domains_reject_code - Server response when a client attempts to violate - the mail relay policy. + Response code when a client attempts to violate the + mail relay policy. unknown_address_reject_code - Server response when a client violates the + Response code when a client violates the reject_unknown_address restriction. unknown_client_reject_code - Server response when a client without address to - name mapping violates the reject_unknown_clients + Response code when a client without address to name + mapping violates the reject_unknown_clients restriction. unknown_hostname_reject_code - Server response when a client violates the + Response code when a client violates the reject_unknown_hostname restriction. SEE ALSO @@ -344,7 +350,7 @@ SMTPD(8) SMTPD(8) syslogd(8) system logging LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) diff --git a/postfix/html/uce.html b/postfix/html/uce.html index d934484ef..7856acc09 100644 --- a/postfix/html/uce.html +++ b/postfix/html/uce.html @@ -325,10 +325,24 @@ specified; the first restriction that matches wins.

+In addition to restrictions that are specific to the client hostname +or IP address, you may list here any restrictions based on the +information passed with the +HELO/EHLO command, on the +sender address or on the +recipient address. The HELO/EHLO, sender or recipient restrictions +take effect only if smtpd_delay_reject = yes so that all +restrictions are evaluated after the RCPT TO command. + +

+

Examples:
smtpd_client_restrictions = hash:/etc/postfix/access, -reject_maps_rbl +reject_rbl_client relays.mail-abuse.org + +
smtpd_client_restrictions = hash:/etc/postfix/access, +reject_rhsbl_client dsn.rfc-ignorant.org
smtpd_client_restrictions = permit_mynetworks, reject_unknown_client @@ -358,6 +372,30 @@ href="basic.html#mynetworks"> $mynetworks.

+ + +

reject_rbl_client domain.tld
Reject the +request when the reversed client network address is listed with an +A record under domain.tld. + +The maps_rbl_reject_code parameter specifies the response +code for rejected requests (default: 554), the default_rbl_reply parameter +specifies the default server reply, and the +rbl_reply_maps parameter specifies tables with server replies +indexed by RBL domain. + +

+ + + +

reject_rhsbl_client domain.tld
Reject the +request when the client hostname is listed with an A record under +domain.tld. See above for additional RBL related configuration +parameters. + +

+

check_client_access maptype:mapname @@ -369,71 +407,6 @@ significant octets.

-

- -
REJECT -
Reject the request. The access_map_reject_code parameter -specifies the response code (default: 554). - -

- -

[45]XX text -
Reject the request. Send the numerical code and text to the SMTP client. - -

- -

OK -
RELAY -
all-numerical -
Permit the request. - -

- -

HOLD -
Place the message on the hold queue. Mail on hold can -be inspected with the postcat command, -and can be destroyed or taken off hold with the postsuper command. - - Note: this action currently affects all recipients of a message. - -

- -

DISCARD -
Claim successful delivery and silently discard the message. - - Note: this action currently affects all recipients of a message. - -

- -

FILTER transport:nexthop
-After the message is queued, send the entire message through -a content filter. This requires different cleanup servers -before and after the filter, with header/body checks turned -off in the second cleanup server. More details about content -filtering are in the Postfix FILTER_README file. This feature -overrides the main.cf content_filter setting. - - Note: this action currently affects all recipients of a message. - -

- -

Other
Treat the result as another list of UCE restrictions. - -
- -

- - - -

reject_maps_rbl
Reject the request when the reversed -client network address is listed under any of the domains listed -in $maps_rbl_domains. The -maps_rbl_reject_code parameter specifies the response code for -rejected requests (default: 554). - -

-

permit
defer @@ -523,9 +496,15 @@ specified; the first restriction that matches wins.

-In addition to restrictions that are specific to HELO (EHLO) -command parameters, you can also specify restrictions based -on the client hostname or network address. +In addition to restrictions that are specific to HELO (EHLO) command +parameters, you may list here any restrictions on the client hostname , client address , sender address or recipient address. The +sender or recipient restrictions take effect only if smtpd_delay_reject += yes so that all restrictions are evaluated after the RCPT TO +command.

@@ -586,24 +565,7 @@ specifies the response code to rejected requests (default:

maptype:mapname
Search the named access database for the HELO hostname -or parent domains in the specified table. Reject the request if -the result is REJECT or "[45]XX text". Permit -the request when the result is OK or RELAY or -all-numerical. Otherwise, treat the result as another list of UCE -restrictions. The access_map_reject_code parameter specifies -the response code for REJECT results (default: 554). - -

- -

reject_maps_rbl - -
reject_unknown_client - -
permit_mynetworks - -
check_client_access maptype:mapname - -
See client hostname/address restrictions. +or parent domains.

@@ -699,8 +661,13 @@ specified; the first restriction that matches wins. In addition to restrictions that are specific to sender mail addresses, you can also specify restrictions based on the information -passed with the HELO/EHLO command, and on the client hostname or -network address. +passed with the HELO/EHLO +command , on the client +hostname or network +address , or on the +recipient address . The recipient restrictions take effect +only if smtpd_delay_reject = yes so that all restrictions +are evaluated after the RCPT TO command.

@@ -725,18 +692,27 @@ is always 450 in case of a temporary DNS error.

+ + +

reject_rhsbl_sender domain.tld
Reject the +request when the sender mail address domain is listed with an A +record under domain.tld. + +The maps_rbl_reject_code parameter specifies the response +code for rejected requests (default: 554), the default_rbl_reply parameter +specifies the default server reply, and the +rbl_reply_maps parameter specifies tables with server replies +indexed by RBL domain. +

+

check_sender_access maptype:mapname
maptype:mapname
Search the named access database for the sender mail address, -parent domain, or localpart@. Reject the request if the -result is REJECT or "[45]XX text". Permit the -request if the result is OK or RELAY or all-numerical. -Otherwise, treat the result as another list of UCE restrictions. The -access_map_reject_code parameter specifies the result code for -rejected requests (default: 554). +sender domain and parent domain, or localpart@.

@@ -762,32 +738,6 @@ client login name doesn't own the MAIL FROM address according to

-

permit_naked_ip_address - -
reject_invalid_hostname - -
reject_unknown_hostname - -
reject_non_fqdn_hostname - -
check_helo_access maptype:mapname - -
See HELO (EHLO) hostname restrictions. - -

- -

reject_maps_rbl - -
reject_unknown_client - -
permit_mynetworks - -
check_client_access maptype:mapname - -
See client hostname/address restrictions. - -

-

permit
defer @@ -870,9 +820,12 @@ specified; the first restriction that matches wins.

In addition to restrictions that are specific to recipient mail -addresses, you can also specify restrictions based on the sender mail -address, on the information passed with the HELO/EHLO command, and -on the client hostname or network address. +addresses, you can also specify restrictions based on the sender mail address, on the +information passed with the +HELO/EHLO command , and on the +client hostname or +network address .

@@ -997,12 +950,7 @@ href="basic.html#inet_interfaces"> $inet_interfaces.

maptype:mapname
Search the named access database for the resolved destination -address, parent domain, or localpart@. Reject the request if the -result is REJECT or "[45]XX text". Permit the -request if the result is OK or RELAY or all-numerical. -Otherwise, treat the result as another list of UCE restrictions. The -access_map_reject_code parameter specifies the result code for -rejected requests (default: 554). +address, recipient domain or parent domain, or localpart@.

@@ -1016,6 +964,21 @@ is always 450 in case of a temporary DNS error.

+ + +

reject_rhsbl_recipient domain.tld
Reject the +request when the recipient mail address domain is listed with an A +record under domain.tld. + +The maps_rbl_reject_code parameter specifies the response +code for rejected requests (default: 554), the default_rbl_reply parameter +specifies the default server reply, and the +rbl_reply_maps parameter specifies tables with server replies +indexed by RBL domain. + +

+

reject_non_fqdn_recipient
Reject the request when @@ -1025,45 +988,6 @@ response code to rejected requests (default: 504).

-

reject_unknown_sender_domain - -
reject_non_fqdn_sender - -
check_sender_access maptype:mapname - -
reject_sender_login_mismatch - - -
See sender address restrictions. - -

- -

permit_naked_ip_address - -
reject_invalid_hostname - -
reject_unknown_hostname - -
reject_non_fqdn_hostname - -
check_helo_access maptype:mapname - -
See HELO (EHLO) hostname restrictions. - -

- -

reject_maps_rbl - -
reject_unknown_client - -
permit_mynetworks - -
check_client_access maptype:mapname - -
See client hostname/address restrictions. - -

-

permit
defer @@ -1111,8 +1035,10 @@ specified; the first restriction that matches wins. In addition to restrictions that are specific to ETRN domain names, you can also specify restrictions based on the information passed -with the HELO/EHLO command, and on the client hostname or network -address. +with the HELO/EHLO command +, and on the client +hostname or network +address .

@@ -1142,30 +1068,6 @@ the result code for rejected requests (default: 554).

-

permit_naked_ip_address - -
reject_invalid_hostname - -
reject_unknown_hostname - -
check_helo_access maptype:mapname - -
See HELO (EHLO) hostname restrictions. - -

- -

reject_maps_rbl - -
reject_unknown_client - -
permit_mynetworks - -
check_client_access maptype:mapname - -
See client hostname/address restrictions. - -

-

permit
defer @@ -1253,6 +1155,109 @@ to speed up deliveries.
+ + +
default_rbl_reply + +
The default reply template that is used when an SMTP client +request is blocked by a reject_rbl or reject_rhsbl +restriction. The reply template is subjected to exactly one level +of $name macro substitution as described below. The +smtpd_expansion_filter configuration parameter specifies +the set of characters that are allowed in $name macro expansions. +Characters outside the allowed set are replaced by "_". + +

+ +

+ +
Default: + +
default_rbl_reply = $rbl_code Service unavailable; $rbl_class [$rbl_what] blocked using $rbl_domain${rbl_reason?; $rbl_reason} + +

+ +Instead of the form $name you can also specify ${name} +or $(name). + +

+ +

Macro expansion syntax: + +
+ +
$client
The client hostname and IP address, formatted as +name[address]. + +
$client_name
The client hostname, or unknown. + +
$client_address
The client IP address. + +
$helo_name
The hostname given in the HELO or EHLO command, +or the empty string when no HELO or EHLO command was given. + +
$sender
The sender address, or <> in case of the null +address. + +
$sender_name
The sender address localpart, or <> in case +of the null address. + +
$sender_domain
The sender address domain, or the empty +string when no domain is available. + +
$recipient
The recipient address, or <> in case of the +null address. + +
$recipient_name
The recipient address localpart, or <> +in case of the null address. + +
$recipient_domain
The recipient address domain, or the +empty string when no domain is available. + +
$rbl_what
The blacklisted entity: an IP address, a +hostname, a domain name, or an email address whose domain is +blacklisted. + +
$rbl_domain
The RBL domain where $rbl_what is blacklisted +with an A record. + +
$rbl_reason
The reason why $rbl_what is blacklisted, or +the empty string when no information is available. + +
$rbl_class
The blacklisted entity type: Client host, +Helo command, Sender address, or Recipient address. + +
$rbl_code
The numerical server reply code, as specified +with the maps_rbl_reject_code configuration parameter +(default: 554). + +
All other text
Copied without change, with the exception +of conditional macro expansion as described below. + +
+ +

+ +Conditional macro expansion syntax: + +

+ +
${name?text}
expands to text if +$name is not empty. + +
${name:text}
expands to text if +$name is empty. + +
+ +
+ +
+ +

+ +

+
permit_mx_backup_networks @@ -1297,15 +1302,18 @@ of listing the patterns in the main.cf file.
+

+

- + -
maps_rbl_domains +
rbl_reply_maps -
This parameter controls the behavior of the reject_maps_rbl restriction that can -appear as part of a client hostname/address restriction list. +
This parameter specifies lookup tables with RBL reply templates +indexed by RBL domain name. If no template is found, the + default_rbl_reply template is +used instead.

@@ -1313,23 +1321,27 @@ appear as part of a client hostname/address restriction list.

Default: -
maps_rbl_domains = +
rbl_reply_maps =

-Note: RBL lookups are disabled by default. +By default, Postfix always uses the +default_rbl_reply template.

Syntax: -
Zero or more DNS domains that blacklist client IP addresses. A -host is blacklisted when its reversed IP address is listed as a -subdomain under any of the domains listed in $maps_rbl_domains. +
Specify zero or more type:name lookup tables, +separated by whitespace and/or commas. For the syntax of the +template reply strings, see the +default_rbl_reply parameter description.
-

+ + +

diff --git a/postfix/man/man8/smtpd.8 b/postfix/man/man8/smtpd.8 index 1076efce6..393e85b5c 100644 --- a/postfix/man/man8/smtpd.8 +++ b/postfix/man/man8/smtpd.8 @@ -243,33 +243,38 @@ mail from or to. .ad .fi .IP \fBaccess_map_reject_code\fR -Server response when a client violates an access database restriction. +Response code when a client violates an access database restriction. +.IP \fBdefault_rbl_reply\fR +Default template reply when a request is RBL blacklisted. +This template is used by the \fBreject_rbl_*\fR and +\fBreject_rhsbl_*\fR restrictions. See also: +\fBrbl_reply_maps\fR and \fBsmtpd_expansion_filter\fR. .IP \fBdefer_code\fR -Server response when a client request is rejected by the \fBdefer\fR +Response code when a client request is rejected by the \fBdefer\fR restriction. .IP \fBinvalid_hostname_reject_code\fR -Server response when a client violates the \fBreject_invalid_hostname\fR +Response code when a client violates the \fBreject_invalid_hostname\fR restriction. .IP \fBmaps_rbl_reject_code\fR -Server response when a client violates the \fBmaps_rbl_domains\fR -restriction. +Response code when a request is RBL blacklisted. .IP \fBrbl_reply_maps\fR -Table with template responses, indexed by RBL domain name. These -templates are used by the \fBreject_rbl\fR and \fBreject_rhsbl\fR -restrictions. See also: \fBsmtpd_expansion_filter\fR. +Table with template responses for RBL blacklisted requests, indexed by +RBL domain name. These templates are used by the \fBreject_rbl_*\fR +and \fBreject_rhsbl_*\fR restrictions. See also: +\fBdefault_rbl_reply\fR and \fBsmtpd_expansion_filter\fR. .IP \fBreject_code\fR Response code when the client matches a \fBreject\fR restriction. .IP \fBrelay_domains_reject_code\fR -Server response when a client attempts to violate the mail relay +Response code when a client attempts to violate the mail relay policy. .IP \fBunknown_address_reject_code\fR -Server response when a client violates the \fBreject_unknown_address\fR +Response code when a client violates the \fBreject_unknown_address\fR restriction. .IP \fBunknown_client_reject_code\fR -Server response when a client without address to name mapping +Response code when a client without address to name mapping violates the \fBreject_unknown_clients\fR restriction. .IP \fBunknown_hostname_reject_code\fR -Server response when a client violates the \fBreject_unknown_hostname\fR +Response code when a client violates the \fBreject_unknown_hostname\fR restriction. .SH SEE ALSO .na diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 13fc88744..934b103ca 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -1202,18 +1202,26 @@ extern int var_access_map_code; #define WARN_IF_REJECT "warn_if_reject" -#define REJECT_RBL "reject_rbl" -#define REJECT_RHSBL "reject_rhsbl" +#define REJECT_RBL "reject_rbl" /* LaMont compatibility */ +#define REJECT_RBL_CLIENT "reject_rbl_client" +#define REJECT_RHSBL_CLIENT "reject_rhsbl_client" +#define REJECT_RHSBL_SENDER "reject_rhsbl_sender" +#define REJECT_RHSBL_RECIPIENT "reject_rhsbl_recipient" + #define VAR_RBL_REPLY_MAPS "rbl_reply_maps" #define DEF_RBL_REPLY_MAPS "" extern char *var_rbl_reply_maps; -#define REJECT_MAPS_RBL "reject_maps_rbl" +#define VAR_DEF_RBL_REPLY "default_rbl_reply" +#define DEF_DEF_RBL_REPLY "$rbl_code Service unavailable; $rbl_class [$rbl_what] blocked using $rbl_domain${rbl_reason?; $rbl_reason}" +extern char *var_def_rbl_reply; + +#define REJECT_MAPS_RBL "reject_maps_rbl" /* backwards compat */ #define VAR_MAPS_RBL_CODE "maps_rbl_reject_code" #define DEF_MAPS_RBL_CODE 554 extern int var_maps_rbl_code; -#define VAR_MAPS_RBL_DOMAINS "maps_rbl_domains" +#define VAR_MAPS_RBL_DOMAINS "maps_rbl_domains" /* backwards compat */ #define DEF_MAPS_RBL_DOMAINS "" extern char *var_maps_rbl_domains; diff --git a/postfix/src/global/mail_proto.h b/postfix/src/global/mail_proto.h index bb4e5caef..89b005b0c 100644 --- a/postfix/src/global/mail_proto.h +++ b/postfix/src/global/mail_proto.h @@ -98,6 +98,22 @@ extern char *mail_pathname(const char *, const char *); #define MAIL_ATTR_TRANSPORT "transport" #define MAIL_ATTR_NEXTHOP "nexthop" + /* + * Suffixes for sender_name, sender_domain etc. + */ +#define MAIL_ATTR_S_NAME "_name" +#define MAIL_ATTR_S_DOMAIN "_domain" + + /* + * Special names for RBL results. + */ +#define MAIL_ATTR_RBL_WHAT "rbl_what" +#define MAIL_ATTR_RBL_DOMAIN "rbl_domain" +#define MAIL_ATTR_RBL_REASON "rbl_reason" +#define MAIL_ATTR_RBL_TXT "rbl_txt" /* LaMont compatibility */ +#define MAIL_ATTR_RBL_CLASS "rbl_class" +#define MAIL_ATTR_RBL_CODE "rbl_code" + /* * The following attribute names are stored in queue files. Changing this * means lots of work to maintain backwards compatibility with queued mail. @@ -106,6 +122,7 @@ extern char *mail_pathname(const char *, const char *); #define MAIL_ATTR_ENC_8BIT "8bit" /* 8BITMIME equivalent */ #define MAIL_ATTR_ENC_7BIT "7bit" /* 7BIT equivalent */ #define MAIL_ATTR_ENC_NONE "" /* encoding unknown */ +#define MAIL_ATTR_CLIENT "client" /* client name[addr] */ #define MAIL_ATTR_CLIENT_NAME "client_name" /* client hostname */ #define MAIL_ATTR_CLIENT_ADDR "client_address" /* client address */ #define MAIL_ATTR_HELO_NAME "helo_name" /* SMTP helo name */ diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index e7f91836b..11f19ff1a 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change the patchlevel and the release date. Snapshots change the * release date only, unless they include the same bugfix as a patch release. */ -#define MAIL_RELEASE_DATE "20020922" +#define MAIL_RELEASE_DATE "20020923" #define VAR_MAIL_VERSION "mail_version" #define DEF_MAIL_VERSION "1.1.11-" MAIL_RELEASE_DATE diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in index 0ea8d79ab..168cb0e93 100644 --- a/postfix/src/smtpd/Makefile.in +++ b/postfix/src/smtpd/Makefile.in @@ -187,6 +187,8 @@ smtpd_check.o: ../../include/dict.h smtpd_check.o: ../../include/vstream.h smtpd_check.o: ../../include/htable.h smtpd_check.o: ../../include/ctable.h +smtpd_check.o: ../../include/mac_expand.h +smtpd_check.o: ../../include/mac_parse.h smtpd_check.o: ../../include/dns.h smtpd_check.o: ../../include/namadr_list.h smtpd_check.o: ../../include/match_list.h @@ -208,6 +210,9 @@ smtpd_check.o: ../../include/virtual8.h smtpd_check.o: ../../include/cleanup_user.h smtpd_check.o: ../../include/record.h smtpd_check.o: ../../include/rec_type.h +smtpd_check.o: ../../include/mail_proto.h +smtpd_check.o: ../../include/iostuff.h +smtpd_check.o: ../../include/attr.h smtpd_check.o: smtpd.h smtpd_check.o: ../../include/mail_stream.h smtpd_check.o: smtpd_sasl_glue.h diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index ac9c1c441..56e38bea8 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -229,33 +229,38 @@ /* .ad /* .fi /* .IP \fBaccess_map_reject_code\fR -/* Server response when a client violates an access database restriction. +/* Response code when a client violates an access database restriction. +/* .IP \fBdefault_rbl_reply\fR +/* Default template reply when a request is RBL blacklisted. +/* This template is used by the \fBreject_rbl_*\fR and +/* \fBreject_rhsbl_*\fR restrictions. See also: +/* \fBrbl_reply_maps\fR and \fBsmtpd_expansion_filter\fR. /* .IP \fBdefer_code\fR -/* Server response when a client request is rejected by the \fBdefer\fR +/* Response code when a client request is rejected by the \fBdefer\fR /* restriction. /* .IP \fBinvalid_hostname_reject_code\fR -/* Server response when a client violates the \fBreject_invalid_hostname\fR +/* Response code when a client violates the \fBreject_invalid_hostname\fR /* restriction. /* .IP \fBmaps_rbl_reject_code\fR -/* Server response when a client violates the \fBmaps_rbl_domains\fR -/* restriction. +/* Response code when a request is RBL blacklisted. /* .IP \fBrbl_reply_maps\fR -/* Table with template responses, indexed by RBL domain name. These -/* templates are used by the \fBreject_rbl\fR and \fBreject_rhsbl\fR -/* restrictions. See also: \fBsmtpd_expansion_filter\fR. +/* Table with template responses for RBL blacklisted requests, indexed by +/* RBL domain name. These templates are used by the \fBreject_rbl_*\fR +/* and \fBreject_rhsbl_*\fR restrictions. See also: +/* \fBdefault_rbl_reply\fR and \fBsmtpd_expansion_filter\fR. /* .IP \fBreject_code\fR /* Response code when the client matches a \fBreject\fR restriction. /* .IP \fBrelay_domains_reject_code\fR -/* Server response when a client attempts to violate the mail relay +/* Response code when a client attempts to violate the mail relay /* policy. /* .IP \fBunknown_address_reject_code\fR -/* Server response when a client violates the \fBreject_unknown_address\fR +/* Response code when a client violates the \fBreject_unknown_address\fR /* restriction. /* .IP \fBunknown_client_reject_code\fR -/* Server response when a client without address to name mapping +/* Response code when a client without address to name mapping /* violates the \fBreject_unknown_clients\fR restriction. /* .IP \fBunknown_hostname_reject_code\fR -/* Server response when a client violates the \fBreject_unknown_hostname\fR +/* Response code when a client violates the \fBreject_unknown_hostname\fR /* restriction. /* SEE ALSO /* cleanup(8) message canonicalization @@ -402,6 +407,7 @@ char *var_smtpd_noop_cmds; char *var_smtpd_null_key; int var_smtpd_hist_thrsh; char *var_smtpd_exp_filter; +char *var_def_rbl_reply; /* * Silly little macros. @@ -1648,6 +1654,7 @@ int main(int argc, char **argv) }; static CONFIG_RAW_TABLE raw_table[] = { VAR_SMTPD_EXP_FILTER, DEF_SMTPD_EXP_FILTER, &var_smtpd_exp_filter, 1, 0, + VAR_DEF_RBL_REPLY, DEF_DEF_RBL_REPLY, &var_def_rbl_reply, 1, 0, 0, }; diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index bfe75394f..cc4ad2d13 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -89,7 +89,7 @@ /* .IP "check_recipient_access maptype:mapname" /* Look up the resolved recipient address in the named access table, /* any parent domains of the recipient domain, and the localpart@. -/* .IP reject_rbl rbl.domain.tld +/* .IP reject_rbl_client rbl.domain.tld /* Look up the reversed client network address in the specified /* real-time blackhole DNS zone. The \fIrbl_reply_maps\fR configuration /* parameter is used to generate the template for the reject message. @@ -97,9 +97,11 @@ /* default template is used. The \fImaps_rbl_reject_code\fR /* configuration parameter specifies the reject status code used in /* the default template (default: 554). -/* .IP reject_rhsbl rbl.domain.tld -/* Look up the sender domain name in the specified real-time -/* blackhole DNS zone. The \fIrbl_reply_maps\fR configuration +/* .IP reject_rhsbl_client rbl.domain.tld +/* .IP reject_rhsbl_sender rbl.domain.tld +/* .IP reject_rhsbl_recipient rbl.domain.tld +/* Look up the client/sender/recipient domain name in the specified +/* real-time blackhole DNS zone. The \fIrbl_reply_maps\fR configuration /* parameter is used to generate the template for the reject message. /* If it is not specified, or the rbl domain cannot be found, then a /* default template is used. The \fImaps_rbl_reject_code\fR @@ -317,6 +319,7 @@ #include #include #include +#include /* Application-specific. */ @@ -458,6 +461,8 @@ typedef struct { SMTPD_STATE *state; /* general state */ SMTPD_RBL_STATE *rbl_state; /* cached RBL state */ const char *domain; /* query domain */ + const char *what; /* rejected value */ + const char *class; /* name of rejected value */ } SMTPD_RBL_EXPAND_CONTEXT; /* resolve_pagein - page in an address resolver result */ @@ -2110,7 +2115,7 @@ static void smtpd_expand_unknown(const char *name) /* smtpd_expand_addr - return address or substring thereof */ static const char *smtpd_expand_addr(VSTRING *buf, const char *addr, - const char *name, int prefix_len) + const char *name, int prefix_len) { const char *p; const char *suffix; @@ -2124,7 +2129,7 @@ static const char *smtpd_expand_addr(VSTRING *buf, const char *addr, suffix = name + prefix_len; /* - * "sender" or "recipient". + * MAIL_ATTR_SENDER or MAIL_ATTR_RECIP. */ if (*suffix == 0) { if (*addr) @@ -2138,7 +2143,7 @@ static const char *smtpd_expand_addr(VSTRING *buf, const char *addr, */ #define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0) - else if (STREQ(suffix, "_name")) { + else if (STREQ(suffix, MAIL_ATTR_S_NAME)) { if (*addr) { if ((p = strrchr(addr, '@')) != 0) { vstring_strncpy(buf, addr, p - addr); @@ -2153,7 +2158,7 @@ static const char *smtpd_expand_addr(VSTRING *buf, const char *addr, /* * "sender_domain" or "recipient_domain". */ - else if (STREQ(suffix, "_domain")) { + else if (STREQ(suffix, MAIL_ATTR_S_DOMAIN)) { if (*addr) { if ((p = strrchr(addr, '@')) != 0) { return (p + 1); @@ -2195,27 +2200,27 @@ static const char *smtpd_expand_lookup(const char *name, int unused_mode, * * Return NULL only for non-existent names. */ - if (STREQ(name, "client")) { + if (STREQ(name, MAIL_ATTR_CLIENT)) { return (state->namaddr); - } else if (STREQ(name, "client_address")) { + } else if (STREQ(name, MAIL_ATTR_CLIENT_ADDR)) { return (state->addr); - } else if (STREQ(name, "client_name")) { + } else if (STREQ(name, MAIL_ATTR_CLIENT_NAME)) { return (state->name); - } else if (STREQ(name, "helo_name")) { + } else if (STREQ(name, MAIL_ATTR_HELO_NAME)) { return (state->helo_name ? state->helo_name : ""); - } else if (STREQN(name, "sender", CONST_LEN("sender"))) { + } else if (STREQN(name, MAIL_ATTR_SENDER, CONST_LEN(MAIL_ATTR_SENDER))) { return (smtpd_expand_addr(state->expand_buf, state->sender, - name, CONST_LEN("sender"))); - } else if (STREQN(name, "recipient", CONST_LEN("recipient"))) { + name, CONST_LEN(MAIL_ATTR_SENDER))); + } else if (STREQN(name, MAIL_ATTR_RECIP, CONST_LEN(MAIL_ATTR_RECIP))) { return (smtpd_expand_addr(state->expand_buf, state->recipient, - name, CONST_LEN("recipient"))); + name, CONST_LEN(MAIL_ATTR_RECIP))); } else { smtpd_expand_unknown(name); return (0); } } -/* rbl_pagein - page in an RBL lookup result */ +/* rbl_pagein - look up an RBL lookup result */ static void *rbl_pagein(const char *query, void *unused_context) { @@ -2252,7 +2257,7 @@ static void *rbl_pagein(const char *query, void *unused_context) return ((void *) rbl); } -/* rbl_pageout - page out an RBL lookup result */ +/* rbl_pageout - discard an RBL lookup result */ static void rbl_pageout(void *data, void *unused_context) { @@ -2283,13 +2288,19 @@ static const char *rbl_expand_lookup(const char *name, int mode, /* * Be sure to return NULL only for non-existent names. */ - if (STREQ(name, "rbl_code")) { + if (STREQ(name, MAIL_ATTR_RBL_CODE)) { vstring_sprintf(state->expand_buf, "%d", var_maps_rbl_code); return (STR(state->expand_buf)); - } else if (STREQ(name, "rbl_domain")) { + } else if (STREQ(name, MAIL_ATTR_RBL_DOMAIN)) { return (rbl_exp->domain); - } else if (STREQ(name, "rbl_txt")) { + } else if (STREQ(name, MAIL_ATTR_RBL_REASON)) { return (rbl->txt); + } else if (STREQ(name, MAIL_ATTR_RBL_TXT)) {/* LaMont compat */ + return (rbl->txt); + } else if (STREQ(name, MAIL_ATTR_RBL_WHAT)) { + return (rbl_exp->what); + } else if (STREQ(name, MAIL_ATTR_RBL_CLASS)) { + return (rbl_exp->class); } else { return (smtpd_expand_lookup(name, mode, (char *) state)); } @@ -2298,7 +2309,9 @@ static const char *rbl_expand_lookup(const char *name, int mode, /* rbl_reject_reply - format reply after RBL reject */ static int rbl_reject_reply(SMTPD_STATE *state, SMTPD_RBL_STATE *rbl, - const char *rbl_domain) + const char *rbl_domain, + const char *what, + const char *reply_class) { const char *myname = "rbl_reject_reply"; VSTRING *why = 0; @@ -2307,46 +2320,48 @@ static int rbl_reject_reply(SMTPD_STATE *state, SMTPD_RBL_STATE *rbl, SMTPD_RBL_EXPAND_CONTEXT rbl_exp; int result; + /* + * Use the server-specific reply template or use the default one. + */ if (*var_rbl_reply_maps) { low_name = lowercase(mystrdup(rbl_domain)); template = maps_find(rbl_reply_maps, low_name, 0); myfree(low_name); } - if (template) { - why = vstring_alloc(10); - rbl_exp.state = state; - rbl_exp.rbl_state = rbl; - rbl_exp.domain = rbl_domain; + why = vstring_alloc(100); + rbl_exp.state = state; + rbl_exp.rbl_state = rbl; + rbl_exp.domain = rbl_domain; + rbl_exp.what = what; + rbl_exp.class = reply_class; + for (;;) { + if (template == 0) + template = var_def_rbl_reply; if (mac_expand(why, template, MAC_EXP_FLAG_NONE, STR(expand_filter), rbl_expand_lookup, - (char *) &rbl_exp) != 0) { - msg_warn("%s: bad rbl reply template: %s", myname, template); - template = 0; /* pretend not found */ - } - } - if (template) { - result = smtpd_check_reject(state, MAIL_ERROR_POLICY, STR(why)); - } else { - /* Hard-coded to avoid trouble with future ?: ternary operator. */ - result = smtpd_check_reject(state, MAIL_ERROR_POLICY, - "%d Service unavailable; [%s] blocked using %s%s%s", - var_maps_rbl_code, state->addr, - rbl_domain, rbl->txt[0] ? - ", reason: " : "", rbl->txt); + (char *) &rbl_exp) == 0) + break; + if (template == var_def_rbl_reply) + msg_fatal("%s: bad default rbl reply template: %s", + myname, var_def_rbl_reply); + msg_warn("%s: bad rbl reply template for domain %s: %s", + myname, rbl_domain, template); + template = 0; /* pretend not found */ } + result = smtpd_check_reject(state, MAIL_ERROR_POLICY, STR(why)); /* * Clean up. */ - if (why) - vstring_free(why); + vstring_free(why); return (result); } -/* reject_rbl - reject if client address in real-time blackhole list */ +/* reject_rbl_addr - reject if address in real-time blackhole list */ -static int reject_rbl(SMTPD_STATE *state, const char *rbl_domain) +static int reject_rbl_addr(SMTPD_STATE *state, const char *rbl_domain, + const char *addr, const char *reply_class) { char *myname = "reject_rbl"; ARGV *octets; @@ -2355,13 +2370,13 @@ static int reject_rbl(SMTPD_STATE *state, const char *rbl_domain) SMTPD_RBL_STATE *rbl; if (msg_verbose) - msg_info("%s: %s", myname, state->addr); + msg_info("%s: %s %s", myname, reply_class, addr); /* * IPv4 only for now */ #ifdef INET6 - if (inet_pton(AF_INET, state->addr, &a) != 1) + if (inet_pton(AF_INET, addr, &a) != 1) return SMTPD_CHECK_DUNNO; #endif @@ -2370,7 +2385,7 @@ static int reject_rbl(SMTPD_STATE *state, const char *rbl_domain) * the DNS for an A record. */ query = vstring_alloc(100); - octets = argv_split(state->addr, "."); + octets = argv_split(addr, "."); for (i = octets->argc - 1; i >= 0; i--) { vstring_strcat(query, octets->argv[i]); vstring_strcat(query, "."); @@ -2381,35 +2396,39 @@ static int reject_rbl(SMTPD_STATE *state, const char *rbl_domain) vstring_free(query); /* - * If the record exists, the client address is blacklisted. + * If the record exists, the address is blacklisted. */ if (rbl == 0) { return (SMTPD_CHECK_DUNNO); } else { - return (rbl_reject_reply(state, rbl, rbl_domain)); + return (rbl_reject_reply(state, rbl, rbl_domain, addr, reply_class)); } } -/* reject_rhsbl - reject if sender domain in real-time blackhole list */ +/* reject_rbl_domain - reject if domain in real-time blackhole list */ -static int reject_rhsbl(SMTPD_STATE *state, const char *rbl_domain) +static int reject_rbl_domain(SMTPD_STATE *state, const char *rbl_domain, + const char *what, const char *reply_class) { - char *myname = "reject_rhsbl"; + char *myname = "reject_rbl_domain"; VSTRING *query; SMTPD_RBL_STATE *rbl; const char *domain; if (msg_verbose) - msg_info("%s: %s", myname, state->sender); + msg_info("%s: %s %s", myname, reply_class, what); /* - * Extract the sender domain, tack on the RBL domain name and query the - * DNS for an A record. + * Extract the domain, tack on the RBL domain name and query the DNS for + * an A record. */ - if ((domain = strrchr(state->sender, '@')) == 0) - return (SMTPD_CHECK_DUNNO); - domain += 1; - if (domain[0] == 0 || domain[0] == '#' || domain[0] == '[') + if ((domain = strrchr(what, '@')) != 0) { + domain += 1; + if (domain[0] == '#' || domain[0] == '[') + return (SMTPD_CHECK_DUNNO); + } else + domain = what; + if (domain[0] == 0) return (SMTPD_CHECK_DUNNO); query = vstring_alloc(100); @@ -2418,12 +2437,12 @@ static int reject_rhsbl(SMTPD_STATE *state, const char *rbl_domain) vstring_free(query); /* - * If the record exists, the sender domain is blacklisted. + * If the record exists, the domain is blacklisted. */ if (rbl == 0) { return (SMTPD_CHECK_DUNNO); } else { - return (rbl_reject_reply(state, rbl, rbl_domain)); + return (rbl_reject_reply(state, rbl, rbl_domain, what, reply_class)); } } @@ -2441,7 +2460,8 @@ static int reject_maps_rbl(SMTPD_STATE *state) msg_info("%s: %s", myname, state->addr); while ((rbl_domain = mystrtok(&bp, " \t\r\n,")) != 0) { - result = reject_rbl(state, rbl_domain); + result = reject_rbl_addr(state, rbl_domain, state->addr, + SMTPD_NAME_CLIENT); if (result != SMTPD_CHECK_DUNNO) break; } @@ -2601,12 +2621,20 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, SMTPD_NAME_CLIENT, def_acl); } else if (strcasecmp(name, REJECT_MAPS_RBL) == 0) { status = reject_maps_rbl(state); - } else if (strcasecmp(name, REJECT_RBL) == 0) { + } else if (strcasecmp(name, REJECT_RBL_CLIENT) == 0 + || strcasecmp(name, REJECT_RBL) == 0) { + if (*(cpp[1]) == 0) + msg_warn("restriction %s requires domain name argument", name); + else + status = reject_rbl_addr(state, *(cpp += 1), state->addr, + SMTPD_NAME_CLIENT); + } else if (strcasecmp(name, REJECT_RHSBL_CLIENT) == 0) { if (*(cpp[1]) == 0) msg_warn("restriction %s requires domain name argument", - REJECT_RBL); - else - status = reject_rbl(state, *(cpp += 1)); + name); + else if (strcasecmp(state->name, "unknown") != 0) + status = reject_rbl_domain(state, *(cpp += 1), state->name, + SMTPD_NAME_CLIENT); } /* @@ -2682,12 +2710,12 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, } else if (strcasecmp(name, REJECT_SENDER_LOGIN_MISMATCH) == 0) { if (state->sender && *state->sender) status = reject_sender_login_mismatch(state, state->sender); - } else if (strcasecmp(name, REJECT_RHSBL) == 0) { + } else if (strcasecmp(name, REJECT_RHSBL_SENDER) == 0) { if (cpp[1] == 0) - msg_warn("restriction %s requires domain name argument", - REJECT_RHSBL); + msg_warn("restriction %s requires domain name argument", name); else if (state->sender && *state->sender) - status = reject_rhsbl(state, *(cpp += 1)); + status = reject_rbl_domain(state, *(cpp += 1), state->sender, + SMTPD_NAME_SENDER); } /* @@ -2731,6 +2759,12 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, if (state->recipient) status = reject_non_fqdn_address(state, state->recipient, state->recipient, SMTPD_NAME_RECIPIENT); + } else if (strcasecmp(name, REJECT_RHSBL_RECIPIENT) == 0) { + if (cpp[1] == 0) + msg_warn("restriction %s requires domain name argument", name); + else if (state->recipient) + status = reject_rbl_domain(state, *(cpp += 1), state->recipient, + SMTPD_NAME_RECIPIENT); } /* @@ -3241,6 +3275,7 @@ char *var_smtpd_snd_auth_maps; char *var_double_bounce_sender; char *var_rbl_reply_maps; char *var_smtpd_exp_filter; +char *var_def_rbl_reply; typedef struct { char *name; @@ -3269,6 +3304,7 @@ static STRING_TABLE string_table[] = { VAR_DOUBLE_BOUNCE, DEF_DOUBLE_BOUNCE, &var_double_bounce_sender, VAR_RBL_REPLY_MAPS, DEF_RBL_REPLY_MAPS, &var_rbl_reply_maps, VAR_SMTPD_EXP_FILTER, DEF_SMTPD_EXP_FILTER, &var_smtpd_exp_filter, + VAR_DEF_RBL_REPLY, DEF_DEF_RBL_REPLY, &var_def_rbl_reply, 0, }; diff --git a/postfix/src/smtpd/smtpd_check.ref b/postfix/src/smtpd/smtpd_check.ref index 8c1b9e325..f6c0f1d84 100644 --- a/postfix/src/smtpd/smtpd_check.ref +++ b/postfix/src/smtpd/smtpd_check.ref @@ -184,8 +184,8 @@ OK >>> client spike.porcupine.org 168.100.189.2 OK >>> client foo 127.0.0.2 -./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; [127.0.0.2] blocked using blackholes.mail-abuse.org, reason: Blackholed - see ; from= -554 Service unavailable; [127.0.0.2] blocked using blackholes.mail-abuse.org, reason: Blackholed - see +./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; Client host [127.0.0.2] blocked using blackholes.mail-abuse.org; Blackholed - see ; from= +554 Service unavailable; Client host [127.0.0.2] blocked using blackholes.mail-abuse.org; Blackholed - see >>> # >>> # Hybrids >>> # diff --git a/postfix/src/smtpd/smtpd_check.ref2 b/postfix/src/smtpd/smtpd_check.ref2 index 2bd382663..6007991d6 100644 --- a/postfix/src/smtpd/smtpd_check.ref2 +++ b/postfix/src/smtpd/smtpd_check.ref2 @@ -174,8 +174,8 @@ OK >>> client spike.porcupine.org 168.100.189.2 OK >>> client foo 127.0.0.2 -./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; [127.0.0.2] blocked using blackholes.mail-abuse.org, reason: Blackholed - see ; from= -554 Service unavailable; [127.0.0.2] blocked using blackholes.mail-abuse.org, reason: Blackholed - see +./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; Client host [127.0.0.2] blocked using blackholes.mail-abuse.org; Blackholed - see ; from= +554 Service unavailable; Client host [127.0.0.2] blocked using blackholes.mail-abuse.org; Blackholed - see >>> # >>> # unknown sender/recipient domain >>> # diff --git a/postfix/src/smtpd/smtpd_check_access b/postfix/src/smtpd/smtpd_check_access index 2681a6c09..d04bc4bad 100644 --- a/postfix/src/smtpd/smtpd_check_access +++ b/postfix/src/smtpd/smtpd_check_access @@ -36,11 +36,13 @@ blackholes.mail-abuse.org $rbl_code client=$client client_name=$client_name helo_name=$helo_name sender=$sender sender_name=$sender_name sender_domain=$sender_domain recipient=$recipient recipient_name=$recipient_name recipient_domain=$recipient_domain - rbl_code=$rbl_code rbl_domain=$rbl_domain rbl_txt=$rbl_txt + rbl_code=$rbl_code rbl_domain=$rbl_domain rbl_txt=$rbl_txt rbl_what=$rbl_what + rbl_class=$rbl_class dsn.rfc-ignorant.org $rbl_code client=$client client_address=$client_address client_name=$client_name helo_name=$helo_name sender=$sender sender_name=$sender_name sender_domain=$sender_domain recipient=$recipient recipient_name=$recipient_name recipient_domain=$recipient_domain - rbl_code=$rbl_code rbl_domain=$rbl_domain rbl_txt=$rbl_txt + rbl_code=$rbl_code rbl_domain=$rbl_domain rbl_txt=$rbl_txt rbl_what=$rbl_what + rbl_class=$rbl_class diff --git a/postfix/src/smtpd/smtpd_exp.in b/postfix/src/smtpd/smtpd_exp.in index 6e7585797..6045757fe 100644 --- a/postfix/src/smtpd/smtpd_exp.in +++ b/postfix/src/smtpd/smtpd_exp.in @@ -19,17 +19,32 @@ rcpt rname@rdomain client foo 127.0.0.2 rcpt rname@rdomain # -recipient_restrictions reject_rbl,blackholes.mail-abuse.org +recipient_restrictions reject_rbl_client,blackholes.mail-abuse.org client spike.porcupine.org 168.100.189.2 rcpt rname@rdomain client foo 127.0.0.2 rcpt rname@rdomain # -# RHSBL +# RHSBL sender domain name # -recipient_restrictions reject_rhsbl,dsn.rfc-ignorant.org +recipient_restrictions reject_rhsbl_sender,dsn.rfc-ignorant.org client spike.porcupine.org 168.100.189.2 mail sname@example.tld rcpt rname@rdomain mail sname@sdomain rcpt rname@rdomain +# +# RHSBL client domain name +# +recipient_restrictions reject_rhsbl_client,dsn.rfc-ignorant.org +client example.tld 1.2.3.4 +mail sname@sdomain +rcpt rname@rdomain +# +# RHSBL recipient domain name +# +recipient_restrictions reject_rhsbl_recipient,dsn.rfc-ignorant.org +client spike.porcupine.org 168.100.189.2 +mail sname@sdomain +rcpt rname@rdomain +rcpt rname@example.tld diff --git a/postfix/src/smtpd/smtpd_exp.ref b/postfix/src/smtpd/smtpd_exp.ref index 03c58826b..882dc2181 100644 --- a/postfix/src/smtpd/smtpd_exp.ref +++ b/postfix/src/smtpd/smtpd_exp.ref @@ -29,10 +29,10 @@ OK >>> client foo 127.0.0.2 OK >>> rcpt rname@rdomain -./smtpd_check: reject: RCPT from foo[127.0.0.2]: 554 client=foo[127.0.0.2] client_address=127.0.0.2 client_name=foo helo_name=foobar sender=sname@sdomain sender_name=sname sender_domain=sdomain recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=blackholes.mail-abuse.org rbl_txt=Blackholed - see ; from= to= -554 client=foo[127.0.0.2] client_address=127.0.0.2 client_name=foo helo_name=foobar sender=sname@sdomain sender_name=sname sender_domain=sdomain recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=blackholes.mail-abuse.org rbl_txt=Blackholed - see +./smtpd_check: reject: RCPT from foo[127.0.0.2]: 554 client=foo[127.0.0.2] client_address=127.0.0.2 client_name=foo helo_name=foobar sender=sname@sdomain sender_name=sname sender_domain=sdomain recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=blackholes.mail-abuse.org rbl_txt=Blackholed - see rbl_what=127.0.0.2 rbl_class=Client host; from= to= +554 client=foo[127.0.0.2] client_address=127.0.0.2 client_name=foo helo_name=foobar sender=sname@sdomain sender_name=sname sender_domain=sdomain recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=blackholes.mail-abuse.org rbl_txt=Blackholed - see rbl_what=127.0.0.2 rbl_class=Client host >>> # ->>> recipient_restrictions reject_rbl,blackholes.mail-abuse.org +>>> recipient_restrictions reject_rbl_client,blackholes.mail-abuse.org OK >>> client spike.porcupine.org 168.100.189.2 OK @@ -41,21 +41,47 @@ OK >>> client foo 127.0.0.2 OK >>> rcpt rname@rdomain -./smtpd_check: reject: RCPT from foo[127.0.0.2]: 554 client=foo[127.0.0.2] client_address=127.0.0.2 client_name=foo helo_name=foobar sender=sname@sdomain sender_name=sname sender_domain=sdomain recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=blackholes.mail-abuse.org rbl_txt=Blackholed - see ; from= to= -554 client=foo[127.0.0.2] client_address=127.0.0.2 client_name=foo helo_name=foobar sender=sname@sdomain sender_name=sname sender_domain=sdomain recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=blackholes.mail-abuse.org rbl_txt=Blackholed - see +./smtpd_check: reject: RCPT from foo[127.0.0.2]: 554 client=foo[127.0.0.2] client_address=127.0.0.2 client_name=foo helo_name=foobar sender=sname@sdomain sender_name=sname sender_domain=sdomain recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=blackholes.mail-abuse.org rbl_txt=Blackholed - see rbl_what=127.0.0.2 rbl_class=Client host; from= to= +554 client=foo[127.0.0.2] client_address=127.0.0.2 client_name=foo helo_name=foobar sender=sname@sdomain sender_name=sname sender_domain=sdomain recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=blackholes.mail-abuse.org rbl_txt=Blackholed - see rbl_what=127.0.0.2 rbl_class=Client host >>> # ->>> # RHSBL +>>> # RHSBL sender domain name >>> # ->>> recipient_restrictions reject_rhsbl,dsn.rfc-ignorant.org +>>> recipient_restrictions reject_rhsbl_sender,dsn.rfc-ignorant.org OK >>> client spike.porcupine.org 168.100.189.2 OK >>> mail sname@example.tld OK >>> rcpt rname@rdomain -./smtpd_check: reject: RCPT from spike.porcupine.org[168.100.189.2]: 554 client=spike.porcupine.org[168.100.189.2] client_address=168.100.189.2 client_name=spike.porcupine.org helo_name=foobar sender=sname@example.tld sender_name=sname sender_domain=example.tld recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=dsn.rfc-ignorant.org rbl_txt=Not supporting null originator (DSN); from= to= -554 client=spike.porcupine.org[168.100.189.2] client_address=168.100.189.2 client_name=spike.porcupine.org helo_name=foobar sender=sname@example.tld sender_name=sname sender_domain=example.tld recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=dsn.rfc-ignorant.org rbl_txt=Not supporting null originator (DSN) +./smtpd_check: reject: RCPT from spike.porcupine.org[168.100.189.2]: 554 client=spike.porcupine.org[168.100.189.2] client_address=168.100.189.2 client_name=spike.porcupine.org helo_name=foobar sender=sname@example.tld sender_name=sname sender_domain=example.tld recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=dsn.rfc-ignorant.org rbl_txt=Not supporting null originator (DSN) rbl_what=sname@example.tld rbl_class=Sender address; from= to= +554 client=spike.porcupine.org[168.100.189.2] client_address=168.100.189.2 client_name=spike.porcupine.org helo_name=foobar sender=sname@example.tld sender_name=sname sender_domain=example.tld recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=dsn.rfc-ignorant.org rbl_txt=Not supporting null originator (DSN) rbl_what=sname@example.tld rbl_class=Sender address >>> mail sname@sdomain OK >>> rcpt rname@rdomain OK +>>> # +>>> # RHSBL client domain name +>>> # +>>> recipient_restrictions reject_rhsbl_client,dsn.rfc-ignorant.org +OK +>>> client example.tld 1.2.3.4 +OK +>>> mail sname@sdomain +OK +>>> rcpt rname@rdomain +./smtpd_check: reject: RCPT from example.tld[1.2.3.4]: 554 client=example.tld[1.2.3.4] client_address=1.2.3.4 client_name=example.tld helo_name=foobar sender=sname@sdomain sender_name=sname sender_domain=sdomain recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=dsn.rfc-ignorant.org rbl_txt=Not supporting null originator (DSN) rbl_what=example.tld rbl_class=Client host; from= to= +554 client=example.tld[1.2.3.4] client_address=1.2.3.4 client_name=example.tld helo_name=foobar sender=sname@sdomain sender_name=sname sender_domain=sdomain recipient=rname@rdomain recipient_name=rname recipient_domain=rdomain rbl_code=554 rbl_domain=dsn.rfc-ignorant.org rbl_txt=Not supporting null originator (DSN) rbl_what=example.tld rbl_class=Client host +>>> # +>>> # RHSBL recipient domain name +>>> # +>>> recipient_restrictions reject_rhsbl_recipient,dsn.rfc-ignorant.org +OK +>>> client spike.porcupine.org 168.100.189.2 +OK +>>> mail sname@sdomain +OK +>>> rcpt rname@rdomain +OK +>>> rcpt rname@example.tld +./smtpd_check: reject: RCPT from spike.porcupine.org[168.100.189.2]: 554 client=spike.porcupine.org[168.100.189.2] client_address=168.100.189.2 client_name=spike.porcupine.org helo_name=foobar sender=sname@sdomain sender_name=sname sender_domain=sdomain recipient=rname@example.tld recipient_name=rname recipient_domain=example.tld rbl_code=554 rbl_domain=dsn.rfc-ignorant.org rbl_txt=Not supporting null originator (DSN) rbl_what=rname@example.tld rbl_class=Recipient address; from= to= +554 client=spike.porcupine.org[168.100.189.2] client_address=168.100.189.2 client_name=spike.porcupine.org helo_name=foobar sender=sname@sdomain sender_name=sname sender_domain=sdomain recipient=rname@example.tld recipient_name=rname recipient_domain=example.tld rbl_code=554 rbl_domain=dsn.rfc-ignorant.org rbl_txt=Not supporting null originator (DSN) rbl_what=rname@example.tld rbl_class=Recipient address diff --git a/postfix/src/util/mac_expand.c b/postfix/src/util/mac_expand.c index 02f64980f..922244c61 100644 --- a/postfix/src/util/mac_expand.c +++ b/postfix/src/util/mac_expand.c @@ -23,15 +23,15 @@ /* /* The following expansions are implemented: /* .IP "$name, ${name}, $(name)" -/* Unconditional expansion. If the named attribute is non-empty, the +/* Unconditional expansion. If the named attribute value is non-empty, the /* expansion is the value of the named attribute, optionally subjected /* to further $name expansions. Otherwise, the expansion is empty. /* .IP "${name?text}, $(name?text)" -/* Conditional expansion. If the named attribute is non-empty, the +/* Conditional expansion. If the named attribute value is non-empty, the /* expansion is the given text, subjected to another iteration of /* $name expansion. Otherwise, the expansion is empty. /* .IP "${name:text}, $(name:text)" -/* Conditional expansion. If the named attribute is empty or undefined, +/* Conditional expansion. If the attribute value is empty or undefined, /* the expansion is the given text, subjected to another iteration /* of $name expansion. Otherwise, the expansion is empty. /* .PP