2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-29 21:27:57 +00:00

postfix-1.1.12-20021217

This commit is contained in:
Wietse Venema 2002-12-17 00:00:00 -05:00 committed by Viktor Dukhovni
parent 489633d139
commit 9491ceed2a
40 changed files with 1402 additions and 619 deletions

View File

@ -7426,8 +7426,58 @@ Apologies for any names omitted.
File: trivial-rewrite/resolve.c.
Performance: don't do UCE checks (which may result in 4xx
SMTP reply codes) when we already know that the recipient
is undeliverable. Files: smtpd/smtpd.c, smtpd/smtpd_check.c.
SMTP reply codes, and thus, repeated delivery attempts)
when we already know that the recipient does not exist.
Files: smtpd/smtpd.c, smtpd/smtpd_check.c.
20021215
Cleanup: further simplification of transport map handling
after some really fine hair splitting with Victor Duchovni.
Files: trivial-rewrite/resolve.c, trivial-rewrite/transport.c.
20021216
Workaround: transform the address local-part into unquoted
form only when the address domain is local and the local-part
contains routing operators. Otherwise, we may damage the
address local-part by inserting space between non-operator
tokens. Some people use weird addresses and expect them to
be handled without damage. File: trivial-rewrite/resolve.c.
Robustness: scan the resolved recipient address for routing
operators in the address local-part, even when the local
MTA does not recognize ! and % as valid operators. File:
trivial-rewrite/resolve.c.
Cleanup: the address rewriting code no longer tries to
rewrite broken user@ or user@. address forms into even more
broken forms. bother. File: trivial-rewrite/rewrite.c.
Cleanup: the address resolver code now treates forms ending
in @ in a more rational manner (because the address rewriting
code no longer messes up by appending .my.domain).
Bugfix: a null address local-part before @domain now is
properly quoted just like the null address. File:
global/quote_82[12]_local.c.
20021217
Cleanup: more work on the trivial-rewrite address rewriting
and address resolving code. New regression tests for address
rewriting and resolving that make some assumptions about
main.cf settings. Files: global/Makefile.in (assumptions),
global/rewrite_clnt.in, global/rewrite_clnt.ref,
global/resolve_clnt.in, global/resolve_clnt.ref.
Safety: configurable SMTPD reject codes for recipients not
in {local,relay}_recipient,virtual_{alias,mailbox}}_maps,
aptly named unknown_mumble_reject_code. Postfix installs
with unknown_local_recipient_reject_code=450, unless the
site already ran Postfix with local_recipient_maps enabled.
Files: smtpd/smtpd.c, smtpd/smtpd_check.c, conf/post-install.
Open problems:

View File

@ -122,7 +122,9 @@ mail_owner = postfix
# machine considers itself the final destination for.
#
# These domains are routed to the delivery agent specified with the
# local_transport parameter setting.
# local_transport parameter setting. By default, that is the UNIX
# compatible delivery agent that lookups all recipients in /etc/passwd
# and /etc/aliases or their equivalent.
#
# The default is $myhostname + localhost.$mydomain. On a mail domain
# gateway, you should also include $mydomain.
@ -145,12 +147,14 @@ mail_owner = postfix
# a name matches a lookup key (the right-hand side is ignored).
# Continue long lines by starting the next line with whitespace.
#
# See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
#
#mydestination = $myhostname, localhost.$mydomain
#mydestination = $myhostname, localhost.$mydomain $mydomain
#mydestination = $myhostname, localhost.$mydomain, $mydomain,
# mail.$mydomain, www.$mydomain, ftp.$mydomain
# REJECTING UNKNOWN LOCAL USERS
# REJECTING MAIL FOR UNKNOWN LOCAL USERS
#
# The local_recipient_maps parameter specifies optional lookup tables
# with all names or addresses of users that are local with respect
@ -159,6 +163,9 @@ mail_owner = postfix
# If this parameter is defined, then the SMTP server will reject
# mail for unknown local users. This parameter is defined by default.
#
# To turn off local recipient checking in the SMTP server, specify
# local_recipient_maps = (i.e. empty).
#
# The default setting assumes that you use the default Postfix local
# delivery agent for local delivery. You need to update the
# local_recipient_maps setting if:
@ -175,11 +182,24 @@ mail_owner = postfix
# - You use the "luser_relay", "mailbox_transport", or "fallback_transport"
# feature of the Postfix local delivery agent (see sample-local.cf).
#
# Beware: if the Postfix SMTP server runs chrooted, you may have to
# copy the passwd (not shadow) database into the jail. This is
# system dependent.
# Beware: if the Postfix SMTP server runs chrooted, you probably have
# to copy the passwd (not shadow) database into the jail, and perhaps
# other files. This is system dependent.
#
local_recipient_maps = unix:passwd.byname $alias_maps
#local_recipient_maps = unix:passwd.byname $alias_maps
#local_recipient_maps =
# The unknown_local_recipient_reject_code specifies the SMTP server
# response code when a recipient domain matches $mydestination or
# $inet_interfaces, while $local_recipient_maps is non-empty and the
# recipient address or address local-part is not found.
#
# The default setting is 550 (reject mail) but it is safer to start
# with 450 (try again later) until you are certain that your
# local_recipient_maps settings are OK.
#
#unknown_local_recipient_reject_code = 550
unknown_local_recipient_reject_code = 450
# TRUST AND RELAY CONTROL
@ -282,7 +302,7 @@ local_recipient_maps = unix:passwd.byname $alias_maps
# with all addresses in the domains that match $relay_domains.
#
# If this parameter is defined, then the SMTP server will reject
# mail for unknown relay users.
# mail for unknown relay users. This feature is off by default.
#
#relay_recipient_maps = hash:/etc/postfix/relay_recipients

View File

@ -498,7 +498,7 @@ EOF
}
done
# With 10000 active queue files, the active queue directory should
# With 20000 active queue files, the active queue directory should
# be hashed, and so should the other directories, because they
# can contain even more mail.
#
@ -520,6 +520,21 @@ EOF
$POSTCONF -c $config_directory -e hash_queue_names="$found$missing" ||
exit 1
}
# Turn on safety nets for new features that could bounce mail that
# would be accepted by a previous Postfix version.
unknown_local=unknown_local_recipient_reject_code
has_lrm=`$POSTCONF -n local_recipient_maps`
has_lrjc=`$POSTCONF -n $unknown_local`
if [ -z "$has_lrm" -a -z "$has_lrjc" ]
then
echo SAFETY: editing main.cf, setting $unknown_local=450.
echo See the RELEASE_NOTES and $config_directory/main.cf for details.
$POSTCONF -e "$unknown_local = 450" || exit 1
fi
}
# A reminder if this is the first time Postfix is being installed.

View File

@ -200,7 +200,9 @@ max_use = 100
# machine considers itself the final destination for.
#
# These domains are routed to the delivery agent specified with the
# local_transport parameter setting.
# local_transport parameter setting. By default, that is the UNIX
# compatible delivery agent that lookups all recipients in /etc/passwd
# and /etc/aliases or their equivalent.
#
# The default is $myhostname + localhost.$mydomain. On a mail domain
# gateway, you should also include $mydomain.
@ -223,6 +225,11 @@ max_use = 100
# a name matches a lookup key. Continue long lines by starting the
# next line with whitespace.
#
# See sample-local.cf for a description of the local_recipient_maps
# and unknown_local_recipient_reject_code parameters. By default,
# the SMTP server rejects mail for recipients not listed with the
# local_recipient_maps parameter.
#
#mydestination = $myhostname, localhost.$mydomain $mydomain
#mydestination = $myhostname, localhost.$mydomain www.$mydomain, ftp.$mydomain
mydestination = $myhostname, localhost.$mydomain

View File

@ -434,6 +434,14 @@ allow_untrusted_routing = no
#
relay_domains = $mydestination
# The relay_recipient_maps parameter specifies optional lookup tables
# with all addresses in the domains that match $relay_domains.
#
# If this parameter is defined, then the SMTP server will reject
# mail to unknown relay users. This feature is off by default.
#
#relay_recipient_maps = hash:/etc/postfix/relay_recipients
#
# RESPONSE CODES
#

View File

@ -30,15 +30,15 @@
# Alternatively, the table can be provided as a regular-
# expression map where patterns are given as regular expres-
# sions. In that case, the lookups are done in a slightly
# different way as described in the section titled "REGULAR
# EXPRESSION TABLES".
# different way as described in section "REGULAR EXPRESSION
# TABLES".
#
# TABLE FORMAT
# The format of the transport table is as follows:
#
# pattern result
# When pattern matches the domain, use the corre-
# sponding result.
# When pattern matches the recipient address or
# domain, use the corresponding result.
#
# blank lines and comments
# Empty lines and whitespace-only lines are ignored,
@ -50,45 +50,17 @@
# line that starts with whitespace continues a logi-
# cal line.
#
# In an indexed file, a pattern of `*' matches everything.
# The pattern specifies an email address, a domain name, or
# a domain name hierarchy, as described in section "TABLE
# LOOKUP".
#
# The result is of the form transport:nexthop. The trans-
# port field specifies a mail delivery transport such as
# smtp or local. The nexthop field specifies where and how
# to deliver mail. A null transport or nexthop field means
# "do not change": use the delivery transport and nexthop
# information that would be used if no match were found.
# to deliver mail. More details are given in section "RESULT
# FORMAT".
#
# TRANSPORT FIELD
# The transport field specifies the name of a mail delivery
# transport (the first name of a mail delivery service entry
# in the Postfix master.cf file).
#
# When a null transport field is specified, Postfix uses one
# of the following transports:
#
# $local_transport
# The domain matches $mydestination or $inet_inter-
# faces.
#
# $virtual_transport
# The domain matches $virtual_mailbox_domains.
#
# $relay_transport
# The domain matches $relay_transport.
#
# $default_transport
# All other non-local, non-virtual destinations.
#
# NEXTHOP FIELD
# The interpretation of the nexthop field is transport
# dependent. In the case of SMTP, specify host:service for a
# non-default server port, and use [host] or [host]:port in
# order to disable MX (mail exchanger) DNS lookups. The []
# form can also be used with IP addresses instead of host-
# names.
#
# LOOKUP ORDER
# TABLE LOOKUP
# With lookups from indexed files such as DB or DBM, or from
# networked tables such as NIS, LDAP or SQL, patterns are
# tried in the order as listed below:
@ -113,96 +85,139 @@
# ting. Otherwise, a domain name matches itself and
# its subdomains.
#
# NOTE
# The special pattern <> represents the null address, and
# the special pattern * represents any address (i.e. it
# functions as the wild-card pattern).
# Note 1: the special pattern * represents any address (i.e.
# it functions as the wild-card pattern).
#
# Note 2: the null recipient address is looked up as the
# local mailer-daemon address (mailer-daemon@fully-quali-
# fied-domain-name).
#
# RESULT FORMAT
# A null transport and null nexthop result means "do not
# change": use the delivery transport and nexthop informa-
# tion that would be used when the entire transport table
# did not exist.
#
# A non-null transport field with a null nexthop field
# resets the nexthop information to the recipient domain.
#
# A null transport field with non-null nexthop field does
# not modify the transport information.
#
# TRANSPORT FIELD
# The transport field specifies the name of a mail delivery
# transport (the first name of a mail delivery service entry
# in the Postfix master.cf file).
#
# When a null transport field is specified, Postfix uses one
# of the following transports:
#
# $local_transport
# The domain matches $mydestination or $inet_inter-
# faces.
#
# $virtual_transport
# The domain matches $virtual_mailbox_domains.
#
# $relay_transport
# The domain matches $relay_transport.
#
# $default_transport
# All other non-local, non-virtual destinations.
#
# NEXTHOP FIELD
# The interpretation of the nexthop field is transport
# dependent. In the case of SMTP, specify host:service for a
# non-default server port, and use [host] or [host]:port in
# order to disable MX (mail exchanger) DNS lookups. The []
# form can also be used with IP addresses instead of host-
# names.
#
# EXAMPLES
# In order to deliver internal mail directly, while using a
# mail relay for all other mail, specify a null entry for
# internal destinations (do not change the delivery trans-
# port or the nexthop information) and specify a wildcard
# for all other destinations. Note that for this trick to
# work you should not specify a relayhost in the main.cf
# In order to deliver internal mail directly, while using a
# mail relay for all other mail, specify a null entry for
# internal destinations (do not change the delivery trans-
# port or the nexthop information) and specify a wildcard
# for all other destinations. Note that for this trick to
# work you should not specify a relayhost in the main.cf
# file.
#
# my.domain :
# .my.domain :
# * smtp:outbound-relay.my.domain
#
# In order to send mail for foo.org and its subdomains via
# In order to send mail for foo.org and its subdomains via
# the uucp transport to the UUCP host named foo:
#
# foo.org uucp:foo
# .foo.org uucp:foo
#
# When no nexthop host name is specified, the destination
# domain name is used instead. For example, the following
# directs mail for user@foo.org via the slow transport to a
# mail exchanger for foo.org. The slow transport could be
# something that runs at most one delivery process at a
# When no nexthop host name is specified, the destination
# domain name is used instead. For example, the following
# directs mail for user@foo.org via the slow transport to a
# mail exchanger for foo.org. The slow transport could be
# something that runs at most one delivery process at a
# time:
#
# foo.org slow:
#
# When no transport is specified, Postfix uses the transport
# that matches the address domain class (see TRANSPORT FIELD
# discussion above). The following sends all mail for
# discussion above). The following sends all mail for
# foo.org and its subdomains to host gateway.foo.org:
#
# foo.org :[gateway.foo.org]
# .foo.org :[gateway.foo.org]
#
# In the above example, the [] are used to suppress MX
# lookups. The result would likely point to your local
# In the above example, the [] are used to suppress MX
# lookups. The result would likely point to your local
# machine.
#
# In the case of delivery via SMTP, one may specify host-
# In the case of delivery via SMTP, one may specify host-
# name:service instead of just a host:
#
# foo.org smtp:bar.org:2025
#
# This directs mail for user@foo.org to host bar.org port
# 2025. Instead of a numerical port a symbolic name may be
# used. Specify [] around the hostname in order to disable
# This directs mail for user@foo.org to host bar.org port
# 2025. Instead of a numerical port a symbolic name may be
# used. Specify [] around the hostname in order to disable
# MX lookups.
#
# The error mailer can be used to bounce mail:
#
# .foo.org error:mail for *.foo.org is not deliv-
# .foo.org error:mail for *.foo.org is not deliv-
# erable
#
# This causes all mail for user@anything.foo.org to be
# This causes all mail for user@anything.foo.org to be
# bounced.
#
# REGULAR EXPRESSION TABLES
# This section describes how the table lookups change when
# This section describes how the table lookups change when
# the table is given in the form of regular expressions. For
# a description of regular expression lookup table syntax,
# a description of regular expression lookup table syntax,
# see regexp_table(5) or pcre_table(5).
#
# Each pattern is a regular expression that is applied to
# Each pattern is a regular expression that is applied to
# the entire domain being looked up. Thus, some.domain.hier-
# archy is not broken up into parent domains.
#
# Patterns are applied in the order as specified in the
# table, until a pattern is found that matches the search
# Patterns are applied in the order as specified in the
# table, until a pattern is found that matches the search
# string.
#
# Results are the same as with indexed file lookups, with
# the additional feature that parenthesized substrings from
# Results are the same as with indexed file lookups, with
# the additional feature that parenthesized substrings from
# the pattern can be interpolated as $1, $2 and so on.
#
# CONFIGURATION PARAMETERS
# The following main.cf parameters are especially relevant
# to this topic. See the Postfix main.cf file for syntax
# details and for default values. Use the postfix reload
# The following main.cf parameters are especially relevant
# to this topic. See the Postfix main.cf file for syntax
# details and for default values. Use the postfix reload
# command after a configuration change.
#
# parent_domain_matches_subdomains
# List of Postfix features that use domain.tld pat-
# terns to match sub.domain.tld (as opposed to
# List of Postfix features that use domain.tld pat-
# terns to match sub.domain.tld (as opposed to
# requiring .domain.tld patterns).
#
# transport_maps
@ -212,7 +227,7 @@
#
# local_transport
# The default mail delivery transport when the desti-
# nation matches $mydestination or $inet_interfaces.
# nation matches $mydestination or $inet_interfaces.
#
# virtual_transport
# The default mail delivery transport when the desti-
@ -224,7 +239,7 @@
#
# default_transport
# The default mail delivery transport when the desti-
# nation does not match a local, virtual or relay
# nation does not match a local, virtual or relay
# destination.
#
# mydestination
@ -243,7 +258,7 @@
# regexp_table(5) format of POSIX regular expression tables
#
# LICENSE
# The Secure Mailer license must be distributed with this
# The Secure Mailer license must be distributed with this
# software.
#
# AUTHOR(S)

View File

@ -145,18 +145,6 @@ SMTPD(8) SMTPD(8)
<b>hopcount</b><i>_</i><b>limit</b>
Limit the number of <b>Received:</b> message headers.
<b>local</b><i>_</i><b>recipient</b><i>_</i><b>maps</b>
List of maps with user names that are local to
<b>$myorigin</b> or <b>$inet</b><i>_</i><b>interfaces</b>. If this parameter is
defined, then the SMTP server rejects mail for
unknown local users.
<b>relay</b><i>_</i><b>recipient</b><i>_</i><b>maps</b>
List of maps that define all the email addresses in
the domains that match <b>$relay</b><i>_</i><b>domains</b>. If this
parameter is defined, then the SMTP server rejects
mail for unknown relay recipients.
<b>notify</b><i>_</i><b>classes</b>
List of error classes. Of special interest are:
@ -195,9 +183,35 @@ SMTPD(8) SMTPD(8)
The characters that Postfix accepts as VERP delim-
iter characters.
<b>Known</b> <b>versus</b> <b>unknown</b> <b>recipients</b>
<b>unknown</b><i>_</i><b>local</b><i>_</i><b>recipient</b><i>_</i><b>reject</b><i>_</i><b>code</b>
The response code when a client specifies a recipi-
ent whose domain matches <b>$mydestination</b> or
<b>$inet</b><i>_</i><b>interfaces</b>, while <b>$local</b><i>_</i><b>recipient</b><i>_</i><b>maps</b> is
non-empty and does not list the recipient address
or address local-part.
<b>unknown</b><i>_</i><b>relay</b><i>_</i><b>recipient</b><i>_</i><b>reject</b><i>_</i><b>code</b>
The response code when a client specifies a recipi-
ent whose domain matches <b>$relay</b><i>_</i><b>domains</b>, while
<b>$relay</b><i>_</i><b>recipient</b><i>_</i><b>maps</b> is non-empty and does not
list the recipient address.
<b>unknown</b><i>_</i><b>virtual</b><i>_</i><b>alias</b><i>_</i><b>reject</b><i>_</i><b>code</b>
The response code when a client specifies a recipi-
ent whose domain matches <b>$virtual</b><i>_</i><b>alias</b><i>_</i><b>domains</b>,
while the recipient is not listed in <b>$vir-</b>
<b>tual</b><i>_</i><b>alias</b><i>_</i><b>maps</b>.
<b>unknown</b><i>_</i><b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>reject</b><i>_</i><b>code</b>
The response code when a client specifies a recipi-
ent whose domain matches <b>$virtual</b><i>_</i><b>mailbox</b><i>_</i><b>domains</b>,
while the recipient is not listed in <b>$virtual</b><i>_</i><b>mail-</b>
<b>box</b><i>_</i><b>maps</b>.
<b>Resource</b> <b>controls</b>
<b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
Limit the amount of memory in bytes used for the
Limit the amount of memory in bytes used for the
handling of partial input lines.
<b>message</b><i>_</i><b>size</b><i>_</i><b>limit</b>
@ -205,8 +219,8 @@ SMTPD(8) SMTPD(8)
ing on-disk storage for envelope information.
<b>queue</b><i>_</i><b>minfree</b>
Minimal amount of free space in bytes in the queue
file system for the SMTP server to accept any mail
Minimal amount of free space in bytes in the queue
file system for the SMTP server to accept any mail
at all.
<b>smtpd</b><i>_</i><b>history</b><i>_</i><b>flush</b><i>_</i><b>threshold</b>
@ -221,23 +235,23 @@ SMTPD(8) SMTPD(8)
<b>smtpd</b><i>_</i><b>soft</b><i>_</i><b>error</b><i>_</i><b>limit</b>
When an SMTP client has made this number of errors,
wait <i>error_count</i> seconds before responding to any
wait <i>error_count</i> seconds before responding to any
client request.
<b>smtpd</b><i>_</i><b>hard</b><i>_</i><b>error</b><i>_</i><b>limit</b>
Disconnect after a client has made this number of
Disconnect after a client has made this number of
errors.
<b>smtpd</b><i>_</i><b>junk</b><i>_</i><b>command</b><i>_</i><b>limit</b>
Limit the number of times a client can issue a junk
command such as NOOP, VRFY, ETRN or RSET in one
SMTP session before it is penalized with tarpit
command such as NOOP, VRFY, ETRN or RSET in one
SMTP session before it is penalized with tarpit
delays.
<b>UCE</b> <b>control</b> <b>restrictions</b>
<b>parent</b><i>_</i><b>domain</b><i>_</i><b>matches</b><i>_</i><b>subdomains</b>
List of Postfix features that use <i>domain.tld</i> pat-
terns to match <i>sub.domain.tld</i> (as opposed to
List of Postfix features that use <i>domain.tld</i> pat-
terns to match <i>sub.domain.tld</i> (as opposed to
requiring <i>.domain.tld</i> patterns).
<b>smtpd</b><i>_</i><b>client</b><i>_</i><b>restrictions</b>
@ -245,19 +259,19 @@ SMTPD(8) SMTPD(8)
tem.
<b>smtpd</b><i>_</i><b>helo</b><i>_</i><b>required</b>
Require that clients introduce themselves at the
Require that clients introduce themselves at the
beginning of an SMTP session.
<b>smtpd</b><i>_</i><b>helo</b><i>_</i><b>restrictions</b>
Restrict what client hostnames are allowed in <b>HELO</b>
Restrict what client hostnames are allowed in <b>HELO</b>
and <b>EHLO</b> commands.
<b>smtpd</b><i>_</i><b>sender</b><i>_</i><b>restrictions</b>
Restrict what sender addresses are allowed in <b>MAIL</b>
Restrict what sender addresses are allowed in <b>MAIL</b>
<b>FROM</b> commands.
<b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>restrictions</b>
Restrict what recipient addresses are allowed in
Restrict what recipient addresses are allowed in
<b>RCPT</b> <b>TO</b> commands.
<b>smtpd</b><i>_</i><b>etrn</b><i>_</i><b>restrictions</b>
@ -265,73 +279,73 @@ SMTPD(8) SMTPD(8)
mands, and what clients may issue <b>ETRN</b> commands.
<b>smtpd</b><i>_</i><b>data</b><i>_</i><b>restrictions</b>
Restrictions on the <b>DATA</b> command. Currently, the
only restriction that makes sense here is
Restrictions on the <b>DATA</b> command. Currently, the
only restriction that makes sense here is
<b>reject</b><i>_</i><b>unauth</b><i>_</i><b>pipelining</b>.
<b>allow</b><i>_</i><b>untrusted</b><i>_</i><b>routing</b>
Allow untrusted clients to specify addresses with
sender-specified routing. Enabling this opens up
nasty relay loopholes involving trusted backup MX
Allow untrusted clients to specify addresses with
sender-specified routing. Enabling this opens up
nasty relay loopholes involving trusted backup MX
hosts.
<b>smtpd</b><i>_</i><b>restriction</b><i>_</i><b>classes</b>
Declares the name of zero or more parameters that
contain a list of UCE restrictions. The names of
these parameters can then be used instead of the
Declares the name of zero or more parameters that
contain a list of UCE restrictions. The names of
these parameters can then be used instead of the
restriction lists that they represent.
<b>smtpd</b><i>_</i><b>null</b><i>_</i><b>access</b><i>_</i><b>lookup</b><i>_</i><b>key</b>
The lookup key to be used in SMTPD access tables
instead of the null sender address. A null sender
The lookup key to be used in SMTPD access tables
instead of the null sender address. A null sender
address cannot be looked up.
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>domains</b> (deprecated)
List of DNS domains that publish the addresses of
List of DNS domains that publish the addresses of
blacklisted hosts. This is used with the deprecated
<b>reject</b><i>_</i><b>maps</b><i>_</i><b>rbl</b> restriction.
<b>permit</b><i>_</i><b>mx</b><i>_</i><b>backup</b><i>_</i><b>networks</b>
Only domains whose primary MX hosts match the
listed networks are eligible for the <b>per-</b>
Only domains whose primary MX hosts match the
listed networks are eligible for the <b>per-</b>
<b>mit</b><i>_</i><b>mx</b><i>_</i><b>backup</b> feature.
<b>relay</b><i>_</i><b>domains</b>
Restrict what domains this mail system will relay
mail to. The domains are routed to the delivery
Restrict what domains this mail system will relay
mail to. The domains are routed to the delivery
agent specified with the <b>relay</b><i>_</i><b>transport</b> setting.
<b>UCE</b> <b>control</b> <b>responses</b>
<b>access</b><i>_</i><b>map</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Response code when a client violates an access
Response code when a client violates an access
database restriction.
<b>default</b><i>_</i><b>rbl</b><i>_</i><b>reply</b>
Default template reply when a request is RBL black-
listed. This template is used by the <b>reject</b><i>_</i><b>rbl</b><i>_</i><b>*</b>
and <b>reject</b><i>_</i><b>rhsbl</b><i>_</i><b>*</b> restrictions. See also:
listed. This template is used by the <b>reject</b><i>_</i><b>rbl</b><i>_</i><b>*</b>
and <b>reject</b><i>_</i><b>rhsbl</b><i>_</i><b>*</b> restrictions. See also:
<b>rbl</b><i>_</i><b>reply</b><i>_</i><b>maps</b> and <b>smtpd</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>.
<b>defer</b><i>_</i><b>code</b>
Response code when a client request is rejected by
Response code when a client request is rejected by
the <b>defer</b> restriction.
<b>invalid</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Response code when a client violates the
Response code when a client violates the
<b>reject</b><i>_</i><b>invalid</b><i>_</i><b>hostname</b> restriction.
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Response code when a request is RBL blacklisted.
<b>rbl</b><i>_</i><b>reply</b><i>_</i><b>maps</b>
Table with template responses for RBL blacklisted
requests, indexed by RBL domain name. These tem-
Table with template responses for RBL blacklisted
requests, indexed by RBL domain name. These tem-
plates are used by the <b>reject</b><i>_</i><b>rbl</b><i>_</i><b>*</b> and
<b>reject</b><i>_</i><b>rhsbl</b><i>_</i><b>*</b> restrictions. See also:
<b>reject</b><i>_</i><b>rhsbl</b><i>_</i><b>*</b> restrictions. See also:
<b>default</b><i>_</i><b>rbl</b><i>_</i><b>reply</b> and <b>smtpd</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>.
<b>reject</b><i>_</i><b>code</b>
Response code when the client matches a <b>reject</b>
Response code when the client matches a <b>reject</b>
restriction.
<b>relay</b><i>_</i><b>domains</b><i>_</i><b>reject</b><i>_</i><b>code</b>
@ -339,7 +353,7 @@ SMTPD(8) SMTPD(8)
mail relay policy.
<b>unknown</b><i>_</i><b>address</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Response code when a client violates the
Response code when a client violates the
<b>reject</b><i>_</i><b>unknown</b><i>_</i><b>address</b> restriction.
<b>unknown</b><i>_</i><b>client</b><i>_</i><b>reject</b><i>_</i><b>code</b>
@ -348,7 +362,7 @@ SMTPD(8) SMTPD(8)
tion.
<b>unknown</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Response code when a client violates the
Response code when a client violates the
<b>reject</b><i>_</i><b>unknown</b><i>_</i><b>hostname</b> restriction.
<b>SEE</b> <b>ALSO</b>
@ -358,7 +372,7 @@ SMTPD(8) SMTPD(8)
syslogd(8) system logging
<b>LICENSE</b>
The Secure Mailer license must be distributed with this
The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>

View File

@ -31,15 +31,15 @@ TRANSPORT(5) TRANSPORT(5)
Alternatively, the table can be provided as a regular-
expression map where patterns are given as regular expres-
sions. In that case, the lookups are done in a slightly
different way as described in the section titled "REGULAR
EXPRESSION TABLES".
different way as described in section "REGULAR EXPRESSION
TABLES".
<b>TABLE</b> <b>FORMAT</b>
The format of the transport table is as follows:
<i>pattern</i> <i>result</i>
When <i>pattern</i> matches the domain, use the corre-
sponding <i>result</i>.
When <i>pattern</i> matches the recipient address or
domain, use the corresponding <i>result</i>.
blank lines and comments
Empty lines and whitespace-only lines are ignored,
@ -51,45 +51,17 @@ TRANSPORT(5) TRANSPORT(5)
line that starts with whitespace continues a logi-
cal line.
In an indexed file, a pattern of `<b>*</b>' matches everything.
The <i>pattern</i> specifies an email address, a domain name, or
a domain name hierarchy, as described in section "TABLE
LOOKUP".
The <i>result</i> is of the form <i>transport</i><b>:</b><i>nexthop</i>. The <i>trans-</i>
<i>port</i> field specifies a mail delivery transport such as
<b>smtp</b> or <b>local</b>. The <i>nexthop</i> field specifies where and how
to deliver mail. A null <i>transport</i> or <i>nexthop</i> field means
"do not change": use the delivery transport and nexthop
information that would be used if no match were found.
to deliver mail. More details are given in section "RESULT
FORMAT".
<b>TRANSPORT</b> <b>FIELD</b>
The transport field specifies the name of a mail delivery
transport (the first name of a mail delivery service entry
in the Postfix <b>master.cf</b> file).
When a null transport field is specified, Postfix uses one
of the following transports:
<b>$local</b><i>_</i><b>transport</b>
The domain matches <b>$mydestination</b> or <b>$inet</b><i>_</i><b>inter-</b>
<b>faces</b>.
<b>$virtual</b><i>_</i><b>transport</b>
The domain matches <b>$virtual</b><i>_</i><b>mailbox</b><i>_</i><b>domains</b>.
<b>$relay</b><i>_</i><b>transport</b>
The domain matches <b>$relay</b><i>_</i><b>transport</b>.
<b>$default</b><i>_</i><b>transport</b>
All other non-local, non-virtual destinations.
<b>NEXTHOP</b> <b>FIELD</b>
The interpretation of the nexthop field is transport
dependent. In the case of SMTP, specify <i>host</i>:<i>service</i> for a
non-default server port, and use [<i>host</i>] or [<i>host</i>]:<i>port</i> in
order to disable MX (mail exchanger) DNS lookups. The []
form can also be used with IP addresses instead of host-
names.
<b>LOOKUP</b> <b>ORDER</b>
<b>TABLE</b> <b>LOOKUP</b>
With lookups from indexed files such as DB or DBM, or from
networked tables such as NIS, LDAP or SQL, patterns are
tried in the order as listed below:
@ -114,96 +86,139 @@ TRANSPORT(5) TRANSPORT(5)
ting. Otherwise, a domain name matches itself and
its subdomains.
<b>NOTE</b>
The special pattern &lt;&gt; represents the null address, and
the special pattern <b>*</b> represents any address (i.e. it
functions as the wild-card pattern).
Note 1: the special pattern <b>*</b> represents any address (i.e.
it functions as the wild-card pattern).
Note 2: the null recipient address is looked up as the
local mailer-daemon address (mailer-daemon@fully-quali-
fied-domain-name).
<b>RESULT</b> <b>FORMAT</b>
A null <i>transport</i> and null <i>nexthop</i> result means "do not
change": use the delivery transport and nexthop informa-
tion that would be used when the entire transport table
did not exist.
A non-null <i>transport</i> field with a null <i>nexthop</i> field
resets the nexthop information to the recipient domain.
A null <i>transport</i> field with non-null <i>nexthop</i> field does
not modify the transport information.
<b>TRANSPORT</b> <b>FIELD</b>
The transport field specifies the name of a mail delivery
transport (the first name of a mail delivery service entry
in the Postfix <b>master.cf</b> file).
When a null transport field is specified, Postfix uses one
of the following transports:
<b>$local</b><i>_</i><b>transport</b>
The domain matches <b>$mydestination</b> or <b>$inet</b><i>_</i><b>inter-</b>
<b>faces</b>.
<b>$virtual</b><i>_</i><b>transport</b>
The domain matches <b>$virtual</b><i>_</i><b>mailbox</b><i>_</i><b>domains</b>.
<b>$relay</b><i>_</i><b>transport</b>
The domain matches <b>$relay</b><i>_</i><b>transport</b>.
<b>$default</b><i>_</i><b>transport</b>
All other non-local, non-virtual destinations.
<b>NEXTHOP</b> <b>FIELD</b>
The interpretation of the nexthop field is transport
dependent. In the case of SMTP, specify <i>host</i>:<i>service</i> for a
non-default server port, and use [<i>host</i>] or [<i>host</i>]:<i>port</i> in
order to disable MX (mail exchanger) DNS lookups. The []
form can also be used with IP addresses instead of host-
names.
<b>EXAMPLES</b>
In order to deliver internal mail directly, while using a
mail relay for all other mail, specify a null entry for
internal destinations (do not change the delivery trans-
port or the nexthop information) and specify a wildcard
for all other destinations. Note that for this trick to
work you should not specify a <b>relayhost</b> in the <b>main.cf</b>
In order to deliver internal mail directly, while using a
mail relay for all other mail, specify a null entry for
internal destinations (do not change the delivery trans-
port or the nexthop information) and specify a wildcard
for all other destinations. Note that for this trick to
work you should not specify a <b>relayhost</b> in the <b>main.cf</b>
file.
<b>my.domain</b> <b>:</b>
<b>.my.domain</b> <b>:</b>
<b>*</b> <b>smtp:outbound-relay.my.domain</b>
In order to send mail for <b>foo.org</b> and its subdomains via
In order to send mail for <b>foo.org</b> and its subdomains via
the <b>uucp</b> transport to the UUCP host named <b>foo</b>:
<b>foo.org</b> <b>uucp:foo</b>
<b>.foo.org</b> <b>uucp:foo</b>
When no nexthop host name is specified, the destination
domain name is used instead. For example, the following
directs mail for <i>user</i>@<b>foo.org</b> via the <b>slow</b> transport to a
mail exchanger for <b>foo.org</b>. The <b>slow</b> transport could be
something that runs at most one delivery process at a
When no nexthop host name is specified, the destination
domain name is used instead. For example, the following
directs mail for <i>user</i>@<b>foo.org</b> via the <b>slow</b> transport to a
mail exchanger for <b>foo.org</b>. The <b>slow</b> transport could be
something that runs at most one delivery process at a
time:
<b>foo.org</b> <b>slow:</b>
When no transport is specified, Postfix uses the transport
that matches the address domain class (see TRANSPORT FIELD
discussion above). The following sends all mail for
discussion above). The following sends all mail for
<b>foo.org</b> and its subdomains to host <b>gateway.foo.org</b>:
<b>foo.org</b> <b>:[gateway.foo.org]</b>
<b>.foo.org</b> <b>:[gateway.foo.org]</b>
In the above example, the [] are used to suppress MX
lookups. The result would likely point to your local
In the above example, the [] are used to suppress MX
lookups. The result would likely point to your local
machine.
In the case of delivery via SMTP, one may specify <i>host-</i>
In the case of delivery via SMTP, one may specify <i>host-</i>
<i>name</i>:<i>service</i> instead of just a host:
<b>foo.org</b> <b>smtp:bar.org:2025</b>
This directs mail for <i>user</i>@<b>foo.org</b> to host <b>bar.org</b> port
<b>2025</b>. Instead of a numerical port a symbolic name may be
used. Specify [] around the hostname in order to disable
This directs mail for <i>user</i>@<b>foo.org</b> to host <b>bar.org</b> port
<b>2025</b>. Instead of a numerical port a symbolic name may be
used. Specify [] around the hostname in order to disable
MX lookups.
The error mailer can be used to bounce mail:
<b>.foo.org</b> <b>error:mail</b> <b>for</b> <b>*.foo.org</b> <b>is</b> <b>not</b> <b>deliv-</b>
<b>.foo.org</b> <b>error:mail</b> <b>for</b> <b>*.foo.org</b> <b>is</b> <b>not</b> <b>deliv-</b>
<b>erable</b>
This causes all mail for <i>user</i>@<i>anything</i><b>.foo.org</b> to be
This causes all mail for <i>user</i>@<i>anything</i><b>.foo.org</b> to be
bounced.
<b>REGULAR</b> <b>EXPRESSION</b> <b>TABLES</b>
This section describes how the table lookups change when
This section describes how the table lookups change when
the table is given in the form of regular expressions. For
a description of regular expression lookup table syntax,
a description of regular expression lookup table syntax,
see <a href="regexp_table.5.html"><b>regexp</b><i>_</i><b>table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre</b><i>_</i><b>table</b>(5)</a>.
Each pattern is a regular expression that is applied to
Each pattern is a regular expression that is applied to
the entire domain being looked up. Thus, <i>some.domain.hier-</i>
<i>archy</i> is not broken up into parent domains.
Patterns are applied in the order as specified in the
table, until a pattern is found that matches the search
Patterns are applied in the order as specified in the
table, until a pattern is found that matches the search
string.
Results are the same as with indexed file lookups, with
the additional feature that parenthesized substrings from
Results are the same as with indexed file lookups, with
the additional feature that parenthesized substrings from
the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
<b>CONFIGURATION</b> <b>PARAMETERS</b>
The following <b>main.cf</b> parameters are especially relevant
to this topic. See the Postfix <b>main.cf</b> file for syntax
details and for default values. Use the <b>postfix</b> <b>reload</b>
The following <b>main.cf</b> parameters are especially relevant
to this topic. See the Postfix <b>main.cf</b> file for syntax
details and for default values. Use the <b>postfix</b> <b>reload</b>
command after a configuration change.
<b>parent</b><i>_</i><b>domain</b><i>_</i><b>matches</b><i>_</i><b>subdomains</b>
List of Postfix features that use <i>domain.tld</i> pat-
terns to match <i>sub.domain.tld</i> (as opposed to
List of Postfix features that use <i>domain.tld</i> pat-
terns to match <i>sub.domain.tld</i> (as opposed to
requiring <i>.domain.tld</i> patterns).
<b>transport</b><i>_</i><b>maps</b>
@ -213,7 +228,7 @@ TRANSPORT(5) TRANSPORT(5)
<b>local</b><i>_</i><b>transport</b>
The default mail delivery transport when the desti-
nation matches <b>$mydestination</b> or <b>$inet</b><i>_</i><b>interfaces</b>.
nation matches <b>$mydestination</b> or <b>$inet</b><i>_</i><b>interfaces</b>.
<b>virtual</b><i>_</i><b>transport</b>
The default mail delivery transport when the desti-
@ -225,7 +240,7 @@ TRANSPORT(5) TRANSPORT(5)
<b>default</b><i>_</i><b>transport</b>
The default mail delivery transport when the desti-
nation does not match a local, virtual or relay
nation does not match a local, virtual or relay
destination.
<b>mydestination</b>
@ -244,7 +259,7 @@ TRANSPORT(5) TRANSPORT(5)
<a href="regexp_table.5.html">regexp_table(5)</a> format of POSIX regular expression tables
<b>LICENSE</b>
The Secure Mailer license must be distributed with this
The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>

View File

@ -127,17 +127,6 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
Syntax is <i>transport</i>:<i>nexthop</i>; see <a href="transport.5.html"><b>transport</b>(5)</a> for
details. The :<i>nexthop</i> part is optional.
<b>error</b><i>_</i><b>transport</b>
Where to deliver mail for non-existent recipients
in domains that match <b>virtual</b><i>_</i><b>alias</b><i>_</i><b>domains</b> (all
recipients in simulated virtual domains must be
aliased to some other local or remote domain), or
for recipients that have moved. The default trans-
port is <b>error</b>.
Syntax is <i>transport</i>:<i>nexthop</i>; see <a href="transport.5.html"><b>transport</b>(5)</a> for
details. The :<i>nexthop</i> part is optional.
<b>virtual</b><i>_</i><b>transport</b>
Where to deliver mail for non-local domains that
match <b>$virtual</b><i>_</i><b>mailbox</b><i>_</i><b>domains</b>. The default trans-
@ -178,9 +167,6 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
List of tables with <i>domain</i> to (<i>transport,</i> <i>nexthop</i>)
mappings.
<b>transport</b><i>_</i><b>null</b><i>_</i><b>address</b><i>_</i><b>lookup</b><i>_</i><b>key</b>
Lookup key to be used for the null address.
<b>SEE</b> <b>ALSO</b>
<a href="master.8.html">master(8)</a> process manager
syslogd(8) system logging

View File

@ -33,7 +33,7 @@ or SQL, the same lookups are done as for ordinary indexed files.
Alternatively, the table can be provided as a regular-expression
map where patterns are given as regular expressions. In that case,
the lookups are done in a slightly different way as described
in the section titled "REGULAR EXPRESSION TABLES".
in section "REGULAR EXPRESSION TABLES".
.SH TABLE FORMAT
.na
.nf
@ -41,8 +41,8 @@ in the section titled "REGULAR EXPRESSION TABLES".
.fi
The format of the transport table is as follows:
.IP "\fIpattern result\fR"
When \fIpattern\fR matches the domain, use the corresponding
\fIresult\fR.
When \fIpattern\fR matches the recipient address or domain, use the
corresponding \fIresult\fR.
.IP "blank lines and comments"
Empty lines and whitespace-only lines are ignored, as
are lines whose first non-whitespace character is a `#'.
@ -50,15 +50,55 @@ are lines whose first non-whitespace character is a `#'.
A logical line starts with non-whitespace text. A line that
starts with whitespace continues a logical line.
.PP
In an indexed file, a pattern of `\fB*\fR' matches everything.
.PP
The \fIpattern\fR specifies an email address, a domain name, or
a domain name hierarchy, as described in section "TABLE LOOKUP".
The \fIresult\fR is of the form \fItransport\fB:\fInexthop\fR.
The \fItransport\fR field specifies a mail delivery transport
such as \fBsmtp\fR or \fBlocal\fR. The \fInexthop\fR field
specifies where and how to deliver mail. A null \fItransport\fR
or \fInexthop\fR field means "do not change": use the delivery
transport and nexthop information that would be used if no
match were found.
specifies where and how to deliver mail. More details are given
in section "RESULT FORMAT".
.SH TABLE LOOKUP
.ad
.fi
With lookups from indexed files such as DB or DBM, or from networked
tables such as NIS, LDAP or SQL, patterns are tried in the order as
listed below:
.IP "\fIuser+extension@domain transport\fR:\fInexthop\fR"
Mail for \fIuser+extension@domain\fR is delivered through
\fItransport\fR to
\fInexthop\fR.
.IP "\fIuser@domain transport\fR:\fInexthop\fR"
Mail for \fIuser@domain\fR is delivered through \fItransport\fR to
\fInexthop\fR.
.IP "\fIdomain transport\fR:\fInexthop\fR"
Mail for \fIdomain\fR is delivered through \fItransport\fR to
\fInexthop\fR.
.IP "\fI.domain transport\fR:\fInexthop\fR"
Mail for any subdomain of \fIdomain\fR is delivered through
\fItransport\fR to \fInexthop\fR. This applies only when the
string \fBtransport_maps\fR is not listed in the
\fBparent_domain_matches_subdomains\fR configuration setting.
Otherwise, a domain name matches itself and its subdomains.
.PP
Note 1: the special pattern \fB*\fR represents any address (i.e. it
functions as the wild-card pattern).
Note 2: the null recipient address is looked up as the local
mailer-daemon address (mailer-daemon@fully-qualified-domain-name).
.SH RESULT FORMAT
.ad
.fi
A null \fItransport\fR and null \fInexthop\fR result means "do
not change": use the delivery transport and nexthop information
that would be used when the entire transport table did not exist.
A non-null \fItransport\fR field with a null \fInexthop\fR field
resets the nexthop information to the recipient domain.
A null \fItransport\fR field with non-null \fInexthop\fR field
does not modify the transport information.
.SH TRANSPORT FIELD
.ad
.fi
@ -84,37 +124,6 @@ dependent. In the case of SMTP, specify \fIhost\fR:\fIservice\fR for a
non-default server port, and use [\fIhost\fR] or [\fIhost\fR]:\fIport\fR
in order to disable MX (mail exchanger) DNS lookups. The [] form
can also be used with IP addresses instead of hostnames.
.SH LOOKUP ORDER
.ad
.fi
With lookups from indexed files such as DB or DBM, or from networked
tables such as NIS, LDAP or SQL, patterns are tried in the order as
listed below:
.IP "\fIuser+extension@domain transport\fR:\fInexthop\fR"
Mail for \fIuser+extension@domain\fR is delivered through
\fItransport\fR to
\fInexthop\fR.
.IP "\fIuser@domain transport\fR:\fInexthop\fR"
Mail for \fIuser@domain\fR is delivered through \fItransport\fR to
\fInexthop\fR.
.IP "\fIdomain transport\fR:\fInexthop\fR"
Mail for \fIdomain\fR is delivered through \fItransport\fR to
\fInexthop\fR.
.IP "\fI.domain transport\fR:\fInexthop\fR"
Mail for any subdomain of \fIdomain\fR is delivered through
\fItransport\fR to \fInexthop\fR. This applies only when the
string \fBtransport_maps\fR is not listed in the
\fBparent_domain_matches_subdomains\fR configuration setting.
Otherwise, a domain name matches itself and its subdomains.
.PP
.SH NOTE
.na
.nf
.ad
.fi
The special pattern \fB<>\fR represents the null address, and the
special pattern \fB*\fR represents any address (i.e. it functions
as the wild-card pattern).
.SH EXAMPLES
.na
.nf

View File

@ -132,14 +132,6 @@ XVERP command is specified without explicit delimiters.
Recipient of protocol/policy/resource/software error notices.
.IP \fBhopcount_limit\fR
Limit the number of \fBReceived:\fR message headers.
.IP \fBlocal_recipient_maps\fR
List of maps with user names that are local to \fB$myorigin\fR
or \fB$inet_interfaces\fR. If this parameter is defined,
then the SMTP server rejects mail for unknown local users.
.IP \fBrelay_recipient_maps\fR
List of maps that define all the email addresses in the domains
that match \fB$relay_domains\fR. If this parameter is defined,
then the SMTP server rejects mail for unknown relay recipients.
.IP \fBnotify_classes\fR
List of error classes. Of special interest are:
.RS
@ -167,6 +159,26 @@ Change hard (5xx) reject responses into soft (4xx) reject responses.
This can be useful for testing purposes.
.IP \fBverp_delimiter_filter\fR
The characters that Postfix accepts as VERP delimiter characters.
.SH "Known versus unknown recipients"
.ad
.fi
.IP \fBunknown_local_recipient_reject_code\fR
The response code when a client specifies a recipient whose domain
matches \fB$mydestination\fR or \fB$inet_interfaces\fR, while
\fB$local_recipient_maps\fR is non-empty and does not list
the recipient address or address local-part.
.IP \fBunknown_relay_recipient_reject_code\fR
The response code when a client specifies a recipient whose domain
matches \fB$relay_domains\fR, while \fB$relay_recipient_maps\fR
is non-empty and does not list the recipient address.
.IP \fBunknown_virtual_alias_reject_code\fR
The response code when a client specifies a recipient whose domain
matches \fB$virtual_alias_domains\fR, while the recipient is not
listed in \fB$virtual_alias_maps\fR.
.IP \fBunknown_virtual_mailbox_reject_code\fR
The response code when a client specifies a recipient whose domain
matches \fB$virtual_mailbox_domains\fR, while the recipient is not
listed in \fB$virtual_mailbox_maps\fR.
.SH "Resource controls"
.ad
.fi

View File

@ -117,15 +117,6 @@ The default transport is \fBlocal\fR.
.sp
Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
for details. The :\fInexthop\fR part is optional.
.IP \fBerror_transport\fR
Where to deliver mail for non-existent recipients in domains
that match \fBvirtual_alias_domains\fR (all recipients
in simulated virtual domains must be aliased to some other
local or remote domain), or for recipients that have moved.
The default transport is \fBerror\fR.
.sp
Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
for details. The :\fInexthop\fR part is optional.
.IP \fBvirtual_transport\fR
Where to deliver mail for non-local domains that match
\fB$virtual_mailbox_domains\fR.
@ -160,8 +151,6 @@ to the destination's mail exchanger.
.IP \fBtransport_maps\fR
List of tables with \fIdomain\fR to (\fItransport, nexthop\fR)
mappings.
.IP \fBtransport_null_address_lookup_key\fR
Lookup key to be used for the null address.
.SH SEE ALSO
.na
.nf

View File

@ -27,14 +27,14 @@
# Alternatively, the table can be provided as a regular-expression
# map where patterns are given as regular expressions. In that case,
# the lookups are done in a slightly different way as described
# in the section titled "REGULAR EXPRESSION TABLES".
# in section "REGULAR EXPRESSION TABLES".
# TABLE FORMAT
# .ad
# .fi
# The format of the transport table is as follows:
# .IP "\fIpattern result\fR"
# When \fIpattern\fR matches the domain, use the corresponding
# \fIresult\fR.
# When \fIpattern\fR matches the recipient address or domain, use the
# corresponding \fIresult\fR.
# .IP "blank lines and comments"
# Empty lines and whitespace-only lines are ignored, as
# are lines whose first non-whitespace character is a `#'.
@ -42,15 +42,55 @@
# A logical line starts with non-whitespace text. A line that
# starts with whitespace continues a logical line.
# .PP
# In an indexed file, a pattern of `\fB*\fR' matches everything.
# .PP
# The \fIpattern\fR specifies an email address, a domain name, or
# a domain name hierarchy, as described in section "TABLE LOOKUP".
#
# The \fIresult\fR is of the form \fItransport\fB:\fInexthop\fR.
# The \fItransport\fR field specifies a mail delivery transport
# such as \fBsmtp\fR or \fBlocal\fR. The \fInexthop\fR field
# specifies where and how to deliver mail. A null \fItransport\fR
# or \fInexthop\fR field means "do not change": use the delivery
# transport and nexthop information that would be used if no
# match were found.
# specifies where and how to deliver mail. More details are given
# in section "RESULT FORMAT".
# .SH TABLE LOOKUP
# .ad
# .fi
# With lookups from indexed files such as DB or DBM, or from networked
# tables such as NIS, LDAP or SQL, patterns are tried in the order as
# listed below:
# .IP "\fIuser+extension@domain transport\fR:\fInexthop\fR"
# Mail for \fIuser+extension@domain\fR is delivered through
# \fItransport\fR to
# \fInexthop\fR.
# .IP "\fIuser@domain transport\fR:\fInexthop\fR"
# Mail for \fIuser@domain\fR is delivered through \fItransport\fR to
# \fInexthop\fR.
# .IP "\fIdomain transport\fR:\fInexthop\fR"
# Mail for \fIdomain\fR is delivered through \fItransport\fR to
# \fInexthop\fR.
# .IP "\fI.domain transport\fR:\fInexthop\fR"
# Mail for any subdomain of \fIdomain\fR is delivered through
# \fItransport\fR to \fInexthop\fR. This applies only when the
# string \fBtransport_maps\fR is not listed in the
# \fBparent_domain_matches_subdomains\fR configuration setting.
# Otherwise, a domain name matches itself and its subdomains.
# .PP
# Note 1: the special pattern \fB*\fR represents any address (i.e. it
# functions as the wild-card pattern).
#
# Note 2: the null recipient address is looked up as the local
# mailer-daemon address (mailer-daemon@fully-qualified-domain-name).
# .SH RESULT FORMAT
# .ad
# .fi
#
# A null \fItransport\fR and null \fInexthop\fR result means "do
# not change": use the delivery transport and nexthop information
# that would be used when the entire transport table did not exist.
#
# A non-null \fItransport\fR field with a null \fInexthop\fR field
# resets the nexthop information to the recipient domain.
#
# A null \fItransport\fR field with non-null \fInexthop\fR field
# does not modify the transport information.
# .SH TRANSPORT FIELD
# .ad
# .fi
@ -76,35 +116,6 @@
# non-default server port, and use [\fIhost\fR] or [\fIhost\fR]:\fIport\fR
# in order to disable MX (mail exchanger) DNS lookups. The [] form
# can also be used with IP addresses instead of hostnames.
# .SH LOOKUP ORDER
# .ad
# .fi
# With lookups from indexed files such as DB or DBM, or from networked
# tables such as NIS, LDAP or SQL, patterns are tried in the order as
# listed below:
# .IP "\fIuser+extension@domain transport\fR:\fInexthop\fR"
# Mail for \fIuser+extension@domain\fR is delivered through
# \fItransport\fR to
# \fInexthop\fR.
# .IP "\fIuser@domain transport\fR:\fInexthop\fR"
# Mail for \fIuser@domain\fR is delivered through \fItransport\fR to
# \fInexthop\fR.
# .IP "\fIdomain transport\fR:\fInexthop\fR"
# Mail for \fIdomain\fR is delivered through \fItransport\fR to
# \fInexthop\fR.
# .IP "\fI.domain transport\fR:\fInexthop\fR"
# Mail for any subdomain of \fIdomain\fR is delivered through
# \fItransport\fR to \fInexthop\fR. This applies only when the
# string \fBtransport_maps\fR is not listed in the
# \fBparent_domain_matches_subdomains\fR configuration setting.
# Otherwise, a domain name matches itself and its subdomains.
# .PP
# NOTE
# .ad
# .fi
# The special pattern \fB<>\fR represents the null address, and the
# special pattern \fB*\fR represents any address (i.e. it functions
# as the wild-card pattern).
# EXAMPLES
# .ad
# .fi

View File

@ -298,6 +298,27 @@ virtual8_test: virtual8_maps virtual8_map virtual8.in virtual8.ref \
diff virtual8.ref virtual8.tmp
rm -f virtual8.tmp virtual8_map.db
# Requires: Postfix running, root privileges
rewrite_clnt_test: rewrite_clnt rewrite_clnt.in rewrite_clnt.ref
./rewrite_clnt <rewrite_clnt.in >rewrite_clnt.tmp
sed "s/MYDOMAIN/`postconf -h mydomain`/" rewrite_clnt.ref | \
diff - rewrite_clnt.tmp
rm -f rewrite_clnt.tmp
# Requires: Postfix, root, myorigin=$myhostname, relayhost=$mydomain,
# no transport map
resolve_clnt_test: resolve_clnt resolve_clnt.in resolve_clnt.ref
sed -e "s/MYDOMAIN/`postconf -h mydomain`/g" \
-e "s/MYHOSTNAME/`postconf -h myhostname`/g" \
resolve_clnt.in | ./resolve_clnt >resolve_clnt.tmp
sed -e "s/MYDOMAIN/`postconf -h mydomain`/g" \
-e "s/MYHOSTNAME/`postconf -h myhostname`/g" \
-e "s/RELAYHOST/`postconf -h mydomain`/g" \
resolve_clnt.ref | diff - resolve_clnt.tmp
rm -f resolve_clnt.tmp
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck

View File

@ -96,7 +96,7 @@ extern char *var_mydomain;
* The default local delivery transport.
*/
#define VAR_LOCAL_TRANSPORT "local_transport"
#define DEF_LOCAL_TRANSPORT "local"
#define DEF_LOCAL_TRANSPORT MAIL_SERVICE_LOCAL ":$myhostname"
extern char *var_local_transport;
/*
@ -293,10 +293,6 @@ extern bool var_disable_vrfy_cmd;
/*
* trivial rewrite/resolve service: mapping tables.
*/
#define VAR_ERROR_TRANSPORT "error_transport"
#define DEF_ERROR_TRANSPORT MAIL_SERVICE_ERROR
extern char *var_error_transport;
#define VAR_VIRT_ALIAS_MAPS "virtual_alias_maps"
#define DEF_VIRT_ALIAS_MAPS "$virtual_maps" /* Compatibility! */
extern char *var_virt_alias_maps;
@ -305,6 +301,10 @@ extern char *var_virt_alias_maps;
#define DEF_VIRT_ALIAS_DOMS "$virtual_alias_maps"
extern char *var_virt_alias_doms;
#define VAR_VIRT_ALIAS_CODE "unknown_virtual_alias_reject_code"
#define DEF_VIRT_ALIAS_CODE 550
extern int var_virt_alias_code;
#define VAR_CANONICAL_MAPS "canonical_maps"
#define DEF_CANONICAL_MAPS ""
extern char *var_canonical_maps;
@ -1126,6 +1126,10 @@ extern char *var_relay_transport;
#define DEF_RELAY_RCPT_MAPS ""
extern char *var_relay_rcpt_maps;
#define VAR_RELAY_RCPT_CODE "unknown_relay_recipient_reject_code"
#define DEF_RELAY_RCPT_CODE 550
extern int var_relay_rcpt_code;
#define VAR_CLIENT_CHECKS "smtpd_client_restrictions"
#define DEF_CLIENT_CHECKS ""
extern char *var_client_checks;
@ -1279,12 +1283,16 @@ abcdefghijklmnopqrstuvwxyz{|}~"
extern char *var_smtpd_exp_filter;
/*
* Heuristic to reject most unknown recipients at the SMTP port.
* Heuristic to reject unknown local recipients at the SMTP port.
*/
#define VAR_LOCAL_RCPT_MAPS "local_recipient_maps"
#define DEF_LOCAL_RCPT_MAPS "unix:passwd.byname $alias_maps"
extern char *var_local_rcpt_maps;
#define VAR_LOCAL_RCPT_CODE "unknown_local_recipient_reject_code"
#define DEF_LOCAL_RCPT_CODE 550
extern int var_local_rcpt_code;
/*
* Other.
*/
@ -1375,6 +1383,10 @@ extern char *var_virt_mailbox_maps;
#define DEF_VIRT_MAILBOX_DOMS "$virtual_mailbox_maps"
extern char *var_virt_mailbox_doms;
#define VAR_VIRT_MAILBOX_CODE "unknown_virtual_mailbox_reject_code"
#define DEF_VIRT_MAILBOX_CODE 550
extern int var_virt_mailbox_code;
#define VAR_VIRT_UID_MAPS "virtual_uid_maps"
#define DEF_VIRT_UID_MAPS ""
extern char *var_virt_uid_maps;

View File

@ -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 "20021214"
#define MAIL_RELEASE_DATE "20021217"
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "1.1.12-" MAIL_RELEASE_DATE

View File

@ -82,7 +82,7 @@ static int is_821_dot_string(char *local_part, char *end, int flags)
* lookup tables to speed up some of the work, but hey, how large can a
* local-part be anyway?
*/
if (local_part[0] == 0 || local_part[0] == '.')
if (local_part == end || local_part[0] == 0 || local_part[0] == '.')
return (NO);
for (cp = local_part; cp < end && (ch = *(unsigned char *) cp) != 0; cp++) {
if (ch == '.' && cp[1] == '.')

View File

@ -95,7 +95,7 @@ static int is_822_dot_string(const char *local_part, const char *end, int flags)
* RFC 822 expects 7-bit data. Rather than quoting every 8-bit character
* (and still passing it on as 8-bit data) we leave 8-bit data alone.
*/
if (local_part[0] == 0 || local_part[0] == '.')
if (local_part == end || local_part[0] == 0 || local_part[0] == '.')
return (NO);
for (cp = local_part; cp < end && (ch = *(unsigned char *) cp) != 0; cp++) {
if (ch == '.' && (cp + 1) < end && cp[1] == '.')

View File

@ -70,7 +70,7 @@
/* authorized mail relay destination.
/* .IP RESOLVE_CLASS_DEFAULT
/* The address matches none of the above. Access to this domain
/* should be limited to authorized senders only.
/* should be limited to authorized senders only.
/* .PP
/* For convenience, the constant RESOLVE_CLASS_FINAL includes all
/* cases where the local machine is the final destination.
@ -178,7 +178,7 @@ void resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
*/
if (rewrite_clnt_stream == 0)
rewrite_clnt_stream = clnt_stream_create(MAIL_CLASS_PRIVATE,
var_rewrite_service, var_ipc_idle_limit);
var_rewrite_service, var_ipc_idle_limit);
for (;;) {
stream = clnt_stream_access(rewrite_clnt_stream);
@ -247,6 +247,24 @@ static NORETURN usage(char *myname)
static void resolve(char *addr, RESOLVE_REPLY *reply)
{
struct RESOLVE_FLAG_TABLE {
int flag;
const char *name;
};
struct RESOLVE_FLAG_TABLE resolve_flag_table[] = {
RESOLVE_FLAG_FINAL, "FLAG_FINAL",
RESOLVE_FLAG_ROUTED, "FLAG_ROUTED",
RESOLVE_FLAG_ERROR, "FLAG_ERROR",
RESOLVE_FLAG_FAIL, "FLAG_FAIL",
RESOLVE_CLASS_LOCAL, "CLASS_LOCAL",
RESOLVE_CLASS_ALIAS, "CLASS_ALIAS",
RESOLVE_CLASS_VIRTUAL, "CLASS_VIRTUAL",
RESOLVE_CLASS_RELAY, "CLASS_RELAY",
RESOLVE_CLASS_DEFAULT, "CLASS_DEFAULT",
0,
};
struct RESOLVE_FLAG_TABLE *fp;
resolve_clnt_query(addr, reply);
if (reply->flags & RESOLVE_FLAG_FAIL) {
vstream_printf("request failed\n");
@ -256,6 +274,16 @@ static void resolve(char *addr, RESOLVE_REPLY *reply)
vstream_printf("%-10s %s\n", "nexthop", *STR(reply->nexthop) ?
STR(reply->nexthop) : "[none]");
vstream_printf("%-10s %s\n", "recipient", STR(reply->recipient));
vstream_printf("%-10s ", "flags");
for (fp = resolve_flag_table; fp->name; fp++) {
if (reply->flags & fp->flag) {
vstream_printf("%s ", fp->name);
reply->flags &= ~fp->flag;
}
}
if (reply->flags != 0)
vstream_printf("Unknown flag 0x%x", reply->flags);
vstream_printf("\n");
vstream_fflush(VSTREAM_OUT);
}
}
@ -297,6 +325,7 @@ int main(int argc, char **argv)
vstring_free(buffer);
}
resolve_clnt_free(&reply);
exit(0);
}
#endif

View File

@ -0,0 +1,45 @@
@
@@
@a.
@..
@.@.
!
a!
!b
a!b
!@
a!@
!b@
a!b@
%
a%
%b
a%b
%@
a%@
%b@
@@
a@@
@b@
a@b@
a%b@
a%b@MYHOSTNAME
a!b@MYHOSTNAME
a@b@MYHOSTNAME
a[b]@MYHOSTNAME@MYHOSTNAME
a[b]%MYHOSTNAME@MYHOSTNAME
a[b]%MYHOSTNAME%MYHOSTNAME
MYHOSTNAME!a[b]@MYHOSTNAME
MYHOSTNAME!a[b]%MYHOSTNAME
MYHOSTNAME!MYHOSTNAME!a[b]
user@dom.ain1@dom.ain2
user%dom.ain1@dom.ain2
dom.ain1!user@dom.ain2
user@[1.2.3.4]@dom.ain2
user%[1.2.3.4]@dom.ain2
[1.2.3.4]!user@dom.ain2
user@localhost.MYDOMAIN
user@[321.1.2.3]
user@1.2.3
user@host:port

View File

@ -0,0 +1,225 @@
address
transport local
nexthop MYHOSTNAME
recipient MAILER-DAEMON@MYHOSTNAME
flags CLASS_LOCAL
address @
transport local
nexthop MYHOSTNAME
recipient MAILER-DAEMON@MYHOSTNAME
flags CLASS_LOCAL
address @@
transport local
nexthop MYHOSTNAME
recipient MAILER-DAEMON@MYHOSTNAME
flags CLASS_LOCAL
address @a.
transport smtp
nexthop RELAYHOST
recipient @a
flags CLASS_DEFAULT
address @..
transport smtp
nexthop RELAYHOST
recipient @..
flags FLAG_ERROR CLASS_DEFAULT
address @.@.
transport local
nexthop MYHOSTNAME
recipient MAILER-DAEMON@MYHOSTNAME
flags CLASS_LOCAL
address !
transport local
nexthop MYHOSTNAME
recipient MAILER-DAEMON@MYHOSTNAME
flags CLASS_LOCAL
address a!
transport smtp
nexthop RELAYHOST
recipient @a.MYDOMAIN
flags CLASS_DEFAULT
address !b
transport local
nexthop MYHOSTNAME
recipient b@MYHOSTNAME
flags CLASS_LOCAL
address a!b
transport smtp
nexthop RELAYHOST
recipient b@a.MYDOMAIN
flags CLASS_DEFAULT
address !@
transport local
nexthop MYHOSTNAME
recipient MAILER-DAEMON@MYHOSTNAME
flags CLASS_LOCAL
address a!@
transport smtp
nexthop RELAYHOST
recipient @a.MYDOMAIN
flags CLASS_DEFAULT
address !b@
transport local
nexthop MYHOSTNAME
recipient b@MYHOSTNAME
flags CLASS_LOCAL
address a!b@
transport smtp
nexthop RELAYHOST
recipient b@a.MYDOMAIN
flags CLASS_DEFAULT
address %
transport local
nexthop MYHOSTNAME
recipient MAILER-DAEMON@MYHOSTNAME
flags CLASS_LOCAL
address a%
transport local
nexthop MYHOSTNAME
recipient a@MYHOSTNAME
flags CLASS_LOCAL
address %b
transport smtp
nexthop RELAYHOST
recipient @b.MYDOMAIN
flags CLASS_DEFAULT
address a%b
transport smtp
nexthop RELAYHOST
recipient a@b.MYDOMAIN
flags CLASS_DEFAULT
address %@
transport local
nexthop MYHOSTNAME
recipient MAILER-DAEMON@MYHOSTNAME
flags CLASS_LOCAL
address a%@
transport local
nexthop MYHOSTNAME
recipient a@MYHOSTNAME
flags CLASS_LOCAL
address %b@
transport smtp
nexthop RELAYHOST
recipient @b.MYDOMAIN
flags CLASS_DEFAULT
address @@
transport local
nexthop MYHOSTNAME
recipient MAILER-DAEMON@MYHOSTNAME
flags CLASS_LOCAL
address a@@
transport local
nexthop MYHOSTNAME
recipient a@MYHOSTNAME
flags CLASS_LOCAL
address @b@
transport smtp
nexthop RELAYHOST
recipient @b.MYDOMAIN
flags CLASS_DEFAULT
address a@b@
transport smtp
nexthop RELAYHOST
recipient a@b.MYDOMAIN
flags CLASS_DEFAULT
address a%b@
transport smtp
nexthop RELAYHOST
recipient a@b.MYDOMAIN
flags CLASS_DEFAULT
address a%b@MYHOSTNAME
transport smtp
nexthop RELAYHOST
recipient a@b.MYDOMAIN
flags CLASS_DEFAULT
address a!b@MYHOSTNAME
transport smtp
nexthop RELAYHOST
recipient b@a.MYDOMAIN
flags CLASS_DEFAULT
address a@b@MYHOSTNAME
transport smtp
nexthop RELAYHOST
recipient a@b.MYDOMAIN
flags CLASS_DEFAULT
address a[b]@MYHOSTNAME@MYHOSTNAME
transport local
nexthop MYHOSTNAME
recipient a[b]@MYHOSTNAME
flags CLASS_LOCAL
address a[b]%MYHOSTNAME@MYHOSTNAME
transport local
nexthop MYHOSTNAME
recipient a[b]@MYHOSTNAME
flags CLASS_LOCAL
address a[b]%MYHOSTNAME%MYHOSTNAME
transport local
nexthop MYHOSTNAME
recipient a[b]@MYHOSTNAME
flags CLASS_LOCAL
address MYHOSTNAME!a[b]@MYHOSTNAME
transport local
nexthop MYHOSTNAME
recipient a [b]@MYHOSTNAME
flags CLASS_LOCAL
address MYHOSTNAME!a[b]%MYHOSTNAME
transport local
nexthop MYHOSTNAME
recipient a [b]@MYHOSTNAME
flags CLASS_LOCAL
address MYHOSTNAME!MYHOSTNAME!a[b]
transport local
nexthop MYHOSTNAME
recipient a [b]@MYHOSTNAME
flags CLASS_LOCAL
address user@dom.ain1@dom.ain2
transport smtp
nexthop RELAYHOST
recipient user@dom.ain1@dom.ain2
flags FLAG_ROUTED CLASS_DEFAULT
address user%dom.ain1@dom.ain2
transport smtp
nexthop RELAYHOST
recipient user%dom.ain1@dom.ain2
flags FLAG_ROUTED CLASS_DEFAULT
address dom.ain1!user@dom.ain2
transport smtp
nexthop RELAYHOST
recipient dom.ain1!user@dom.ain2
flags FLAG_ROUTED CLASS_DEFAULT
address user@[1.2.3.4]@dom.ain2
transport smtp
nexthop RELAYHOST
recipient user@[1.2.3.4]@dom.ain2
flags FLAG_ROUTED CLASS_DEFAULT
address user%[1.2.3.4]@dom.ain2
transport smtp
nexthop RELAYHOST
recipient user%[1.2.3.4]@dom.ain2
flags FLAG_ROUTED CLASS_DEFAULT
address [1.2.3.4]!user@dom.ain2
transport smtp
nexthop RELAYHOST
recipient [1.2.3.4]!user@dom.ain2
flags FLAG_ROUTED CLASS_DEFAULT
address user@localhost.MYDOMAIN
transport local
nexthop MYHOSTNAME
recipient user@localhost.MYDOMAIN
flags CLASS_LOCAL
address user@[321.1.2.3]
transport smtp
nexthop RELAYHOST
recipient user@[321.1.2.3]
flags FLAG_ERROR CLASS_DEFAULT
address user@1.2.3
transport smtp
nexthop RELAYHOST
recipient user@1.2.3
flags CLASS_DEFAULT
address user@host:port
transport smtp
nexthop RELAYHOST
recipient user@host:port
flags FLAG_ERROR CLASS_DEFAULT

View File

@ -242,6 +242,7 @@ int main(int argc, char **argv)
vstring_free(buffer);
}
vstring_free(reply);
exit(0);
}
#endif

View File

@ -0,0 +1,13 @@
x !
x a!
x !b
x a!b
x %
x a%
x %b
x a%b
x @
x a@
x a@.
x a@b
x a@b.

View File

@ -0,0 +1,39 @@
rule x
address !
result ""@
rule x
address a!
result ""@a.MYDOMAIN
rule x
address !b
result b@
rule x
address a!b
result b@a.MYDOMAIN
rule x
address %
result ""@
rule x
address a%
result a@
rule x
address %b
result ""@b.MYDOMAIN
rule x
address a%b
result a@b.MYDOMAIN
rule x
address @
result ""
rule x
address a@
result a@
rule x
address a@.
result a@.
rule x
address a@b
result a@b.MYDOMAIN
rule x
address a@b.
result a@b.

View File

@ -185,7 +185,6 @@ qmgr_message.o: ../../include/rec_type.h
qmgr_message.o: ../../include/sent.h
qmgr_message.o: ../../include/deliver_completed.h
qmgr_message.o: ../../include/opened.h
qmgr_message.o: ../../include/resolve_local.h
qmgr_message.o: ../../include/verp_sender.h
qmgr_message.o: ../../include/mail_proto.h
qmgr_message.o: ../../include/iostuff.h

View File

@ -119,7 +119,6 @@
#include <sent.h>
#include <deliver_completed.h>
#include <opened.h>
#include <resolve_local.h>
#include <verp_sender.h>
#include <mail_proto.h>
@ -768,8 +767,11 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
* system can run without a local delivery agent. They'd still have
* to configure something for mail directed to the local postmaster,
* though, but that is an RFC requirement anyway.
*
* XXX This lookup should be done in the resolver, and the mail should
* be directed to a general-purpose null delivery agent.
*/
if (at == 0 || resolve_local(at + 1)) {
if (reply.flags & RESOLVE_CLASS_LOCAL) {
if (strncasecmp(STR(reply.recipient), var_double_bounce_sender,
len) == 0
&& !var_double_bounce_sender[len]) {

View File

@ -172,7 +172,6 @@ qmgr_message.o: ../../include/rec_type.h
qmgr_message.o: ../../include/sent.h
qmgr_message.o: ../../include/deliver_completed.h
qmgr_message.o: ../../include/opened.h
qmgr_message.o: ../../include/resolve_local.h
qmgr_message.o: ../../include/verp_sender.h
qmgr_message.o: ../../include/mail_proto.h
qmgr_message.o: ../../include/iostuff.h

View File

@ -110,7 +110,6 @@
#include <sent.h>
#include <deliver_completed.h>
#include <opened.h>
#include <resolve_local.h>
#include <verp_sender.h>
#include <mail_proto.h>
@ -648,8 +647,11 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
* system can run without a local delivery agent. They'd still have
* to configure something for mail directed to the local postmaster,
* though, but that is an RFC requirement anyway.
*
* XXX This lookup should be done in the resolver, and the mail should
* be directed to a general-purpose null delivery agent.
*/
if (at == 0 || resolve_local(at + 1)) {
if (reply.flags & RESOLVE_CLASS_LOCAL) {
if (strncasecmp(STR(reply.recipient), var_double_bounce_sender,
len) == 0
&& !var_double_bounce_sender[len]) {

View File

@ -118,14 +118,6 @@
/* Recipient of protocol/policy/resource/software error notices.
/* .IP \fBhopcount_limit\fR
/* Limit the number of \fBReceived:\fR message headers.
/* .IP \fBlocal_recipient_maps\fR
/* List of maps with user names that are local to \fB$myorigin\fR
/* or \fB$inet_interfaces\fR. If this parameter is defined,
/* then the SMTP server rejects mail for unknown local users.
/* .IP \fBrelay_recipient_maps\fR
/* List of maps that define all the email addresses in the domains
/* that match \fB$relay_domains\fR. If this parameter is defined,
/* then the SMTP server rejects mail for unknown relay recipients.
/* .IP \fBnotify_classes\fR
/* List of error classes. Of special interest are:
/* .RS
@ -153,6 +145,26 @@
/* This can be useful for testing purposes.
/* .IP \fBverp_delimiter_filter\fR
/* The characters that Postfix accepts as VERP delimiter characters.
/* .SH "Known versus unknown recipients"
/* .ad
/* .fi
/* .IP \fBunknown_local_recipient_reject_code\fR
/* The response code when a client specifies a recipient whose domain
/* matches \fB$mydestination\fR or \fB$inet_interfaces\fR, while
/* \fB$local_recipient_maps\fR is non-empty and does not list
/* the recipient address or address local-part.
/* .IP \fBunknown_relay_recipient_reject_code\fR
/* The response code when a client specifies a recipient whose domain
/* matches \fB$relay_domains\fR, while \fB$relay_recipient_maps\fR
/* is non-empty and does not list the recipient address.
/* .IP \fBunknown_virtual_alias_reject_code\fR
/* The response code when a client specifies a recipient whose domain
/* matches \fB$virtual_alias_domains\fR, while the recipient is not
/* listed in \fB$virtual_alias_maps\fR.
/* .IP \fBunknown_virtual_mailbox_reject_code\fR
/* The response code when a client specifies a recipient whose domain
/* matches \fB$virtual_mailbox_domains\fR, while the recipient is not
/* listed in \fB$virtual_mailbox_maps\fR.
/* .SH "Resource controls"
/* .ad
/* .fi
@ -413,12 +425,11 @@ char *var_smtpd_null_key;
int var_smtpd_hist_thrsh;
char *var_smtpd_exp_filter;
char *var_def_rbl_reply;
char *var_def_transport;
char *var_error_transport;
char *var_local_transport;
char *var_relay_transport;
char *var_virt_transport;
char *var_relay_rcpt_maps;
int var_local_rcpt_code;
int var_virt_alias_code;
int var_virt_mailbox_code;
int var_relay_rcpt_code;
/*
* Silly little macros.
@ -1619,6 +1630,10 @@ int main(int argc, char **argv)
VAR_NON_FQDN_CODE, DEF_NON_FQDN_CODE, &var_non_fqdn_code, 0, 0,
VAR_SMTPD_JUNK_CMD, DEF_SMTPD_JUNK_CMD, &var_smtpd_junk_cmd_limit, 1, 0,
VAR_SMTPD_HIST_THRSH, DEF_SMTPD_HIST_THRSH, &var_smtpd_hist_thrsh, 1, 0,
VAR_LOCAL_RCPT_CODE, DEF_LOCAL_RCPT_CODE, &var_local_rcpt_code, 0, 0,
VAR_VIRT_ALIAS_CODE, DEF_VIRT_ALIAS_CODE, &var_virt_alias_code, 0, 0,
VAR_VIRT_MAILBOX_CODE, DEF_VIRT_MAILBOX_CODE, &var_virt_mailbox_code, 0, 0,
VAR_RELAY_RCPT_CODE, DEF_RELAY_RCPT_CODE, &var_relay_rcpt_code, 0, 0,
0,
};
static CONFIG_TIME_TABLE time_table[] = {
@ -1663,11 +1678,6 @@ int main(int argc, char **argv)
VAR_SMTPD_SND_AUTH_MAPS, DEF_SMTPD_SND_AUTH_MAPS, &var_smtpd_snd_auth_maps, 0, 0,
VAR_SMTPD_NOOP_CMDS, DEF_SMTPD_NOOP_CMDS, &var_smtpd_noop_cmds, 0, 0,
VAR_SMTPD_NULL_KEY, DEF_SMTPD_NULL_KEY, &var_smtpd_null_key, 0, 0,
VAR_DEF_TRANSPORT, DEF_DEF_TRANSPORT, &var_def_transport, 1, 0,
VAR_ERROR_TRANSPORT, DEF_ERROR_TRANSPORT, &var_error_transport, 1, 0,
VAR_LOCAL_TRANSPORT, DEF_LOCAL_TRANSPORT, &var_local_transport, 1, 0,
VAR_RELAY_TRANSPORT, DEF_RELAY_TRANSPORT, &var_relay_transport, 1, 0,
VAR_VIRT_TRANSPORT, DEF_VIRT_TRANSPORT, &var_virt_transport, 1, 0,
VAR_RELAY_RCPT_MAPS, DEF_RELAY_RCPT_MAPS, &var_relay_rcpt_maps, 0, 0,
0,
};

View File

@ -3149,9 +3149,11 @@ char *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient)
* unknown recipients in simulated virtual domains will both resolve to
* "error:user unknown".
*/
if (strcmp(STR(reply->transport), var_error_transport) == 0) {
if (strcmp(STR(reply->transport), MAIL_SERVICE_ERROR) == 0) {
(void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
"%d <%s>: %s", 550,
"%d <%s>: %s",
(reply->flags & RESOLVE_CLASS_ALIAS) ?
var_virt_alias_code : 550,
recipient, STR(reply->nexthop));
SMTPD_CHECK_RCPT_RETURN(STR(error_text));
}
@ -3170,13 +3172,10 @@ char *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient)
*/
if ((reply->flags & RESOLVE_CLASS_LOCAL)
&& *var_local_rcpt_maps
#if 0
&& strcmp(STR(reply->transport), var_local_transport) == 0
#endif
&& NOMATCH(local_rcpt_maps, CONST_STR(reply->recipient))) {
(void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
"%d <%s>: User unknown in local recipient table",
550, recipient);
var_local_rcpt_code, recipient);
SMTPD_CHECK_RCPT_RETURN(STR(error_text));
}
@ -3184,13 +3183,10 @@ char *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient)
* Reject mail to unknown addresses in virtual mailbox domains.
*/
if ((reply->flags & RESOLVE_CLASS_VIRTUAL)
#if 0
&& strcmp(STR(reply->transport), var_virt_transport) == 0
#endif
&& NOMATCHV8(virt_mailbox_maps, CONST_STR(reply->recipient))) {
(void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
"%d <%s>: User unknown in virtual mailbox table",
550, recipient);
var_virt_mailbox_code, recipient);
SMTPD_CHECK_RCPT_RETURN(STR(error_text));
}
@ -3199,13 +3195,10 @@ char *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient)
*/
if ((reply->flags & RESOLVE_CLASS_RELAY)
&& *var_relay_rcpt_maps
#if 0
&& strcmp(STR(reply->transport), var_relay_transport) == 0
#endif
&& NOMATCH(relay_rcpt_maps, CONST_STR(reply->recipient))) {
(void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
"%d <%s>: User unknown in relay recipient table",
550, recipient);
var_relay_rcpt_code, recipient);
SMTPD_CHECK_RCPT_RETURN(STR(error_text));
}
@ -3365,11 +3358,6 @@ char *var_double_bounce_sender;
char *var_rbl_reply_maps;
char *var_smtpd_exp_filter;
char *var_def_rbl_reply;
char *var_local_transport;
char *var_error_transport;
char *var_virt_transport;
char *var_relay_transport;
char *var_def_transport;
char *var_relay_rcpt_maps;
typedef struct {
@ -3408,11 +3396,6 @@ static STRING_TABLE string_table[] = {
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,
VAR_LOCAL_TRANSPORT, DEF_LOCAL_TRANSPORT, &var_local_transport,
VAR_ERROR_TRANSPORT, DEF_ERROR_TRANSPORT, &var_error_transport,
VAR_VIRT_TRANSPORT, DEF_VIRT_TRANSPORT, &var_virt_transport,
VAR_RELAY_TRANSPORT, DEF_RELAY_TRANSPORT, &var_relay_transport,
VAR_DEF_TRANSPORT, DEF_DEF_TRANSPORT, &var_def_transport,
VAR_RELAY_RCPT_MAPS, DEF_RELAY_RCPT_MAPS, &var_relay_rcpt_maps,
0,
};
@ -3465,6 +3448,10 @@ int var_defer_code;
int var_non_fqdn_code;
int var_smtpd_delay_reject;
int var_allow_untrust_route;
int var_local_rcpt_code;
int var_relay_rcpt_code;
int var_virt_mailbox_code;
int var_virt_alias_code;
static INT_TABLE int_table[] = {
"msg_verbose", 0, &msg_verbose,
@ -3480,6 +3467,10 @@ static INT_TABLE int_table[] = {
VAR_NON_FQDN_CODE, DEF_NON_FQDN_CODE, &var_non_fqdn_code,
VAR_SMTPD_DELAY_REJECT, DEF_SMTPD_DELAY_REJECT, &var_smtpd_delay_reject,
VAR_ALLOW_UNTRUST_ROUTE, DEF_ALLOW_UNTRUST_ROUTE, &var_allow_untrust_route,
VAR_LOCAL_RCPT_CODE, DEF_LOCAL_RCPT_CODE, &var_local_rcpt_code,
VAR_RELAY_RCPT_CODE, DEF_RELAY_RCPT_CODE, &var_relay_rcpt_code,
VAR_VIRT_ALIAS_CODE, DEF_VIRT_ALIAS_CODE, &var_virt_alias_code,
VAR_VIRT_MAILBOX_CODE, DEF_VIRT_MAILBOX_CODE, &var_virt_mailbox_code,
0,
};
@ -3633,23 +3624,23 @@ void resolve_clnt_query(const char *addr, RESOLVE_REPLY *reply)
domain += 1;
if (resolve_local(domain)) {
reply->flags = RESOLVE_CLASS_LOCAL;
vstring_strcpy(reply->transport, var_local_transport);
vstring_strcpy(reply->transport, MAIL_SERVICE_LOCAL);
vstring_strcpy(reply->nexthop, domain);
} else if (string_list_match(virt_alias_doms, domain)) {
reply->flags = RESOLVE_CLASS_ALIAS;
vstring_strcpy(reply->transport, var_error_transport);
vstring_strcpy(reply->transport, MAIL_SERVICE_ERROR);
vstring_strcpy(reply->nexthop, "user unknown");
} else if (string_list_match(virt_mailbox_doms, domain)) {
reply->flags = RESOLVE_CLASS_VIRTUAL;
vstring_strcpy(reply->transport, var_virt_transport);
vstring_strcpy(reply->transport, MAIL_SERVICE_VIRTUAL);
vstring_strcpy(reply->nexthop, domain);
} else if (domain_list_match(relay_domains, domain)) {
reply->flags = RESOLVE_CLASS_RELAY;
vstring_strcpy(reply->transport, var_relay_transport);
vstring_strcpy(reply->transport, MAIL_SERVICE_RELAY);
vstring_strcpy(reply->nexthop, domain);
} else {
reply->flags = RESOLVE_CLASS_DEFAULT;
vstring_strcpy(reply->transport, var_def_transport);
vstring_strcpy(reply->transport, MAIL_SERVICE_SMTP);
vstring_strcpy(reply->nexthop, domain);
}
vstring_strcpy(reply->recipient, addr);

View File

@ -71,6 +71,7 @@ resolve.o: ../../include/vstring_vstream.h
resolve.o: ../../include/split_at.h
resolve.o: ../../include/valid_hostname.h
resolve.o: ../../include/stringops.h
resolve.o: ../../include/mymalloc.h
resolve.o: ../../include/mail_params.h
resolve.o: ../../include/mail_proto.h
resolve.o: ../../include/iostuff.h
@ -127,6 +128,9 @@ transport.o: ../../include/mail_params.h
transport.o: ../../include/maps.h
transport.o: ../../include/match_parent_style.h
transport.o: ../../include/match_ops.h
transport.o: ../../include/mail_proto.h
transport.o: ../../include/iostuff.h
transport.o: ../../include/attr.h
transport.o: transport.h
trivial-rewrite.o: trivial-rewrite.c
trivial-rewrite.o: ../../include/sys_defs.h

View File

@ -63,6 +63,7 @@
#include <split_at.h>
#include <valid_hostname.h>
#include <stringops.h>
#include <mymalloc.h>
/* Global library. */
@ -117,19 +118,12 @@
* nexthop information (or vice versa) may produce surprising results. In
* particular, the free text nexthop information for the error transport is
* likely to confuse regular delivery agents; and conversely, a hostname or
* socket pathname is not a useful reason for non-delivery.
* socket pathname is not an adequate text as reason for non-delivery.
*
* In the code below, the class_domain variable specifies the domain name that
* we will use when (the class transport is the error transport and the
* class transport is replaced by a transport map lookup result) but the
* nexthop information is not updated.
*
* For the sake of completeness, we also take action when the reverse happens:
* replacing the class transport by the error transport without updating the
* nexthop information.
*
* The ability to specify "error:reason for non-delivery" in main.cf and in
* transport maps is just too convenient to take it away.
* In the code below, rcpt_domain specifies the domain name that we will use
* when the transport table specifies a non-default channel but no nexthop
* information (we use a generic text when that non-default channel is the
* error transport).
*/
#define STR vstring_str
@ -141,13 +135,6 @@ static DOMAIN_LIST *relay_domains;
static STRING_LIST *virt_alias_doms;
static STRING_LIST *virt_mailbox_doms;
/*
* Saved address domain class information.
*/
static VSTRING *saved_class_channel;
static VSTRING *saved_class_nexthop;
static VSTRING *saved_class_domain;
static MAPS *relocated_maps;
/* resolve_addr - resolve address according to rule set */
@ -157,50 +144,109 @@ void resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
{
char *myname = "resolve_addr";
VSTRING *addr_buf = vstring_alloc(100);
TOK822 *tree;
TOK822 *tree = 0;
TOK822 *saved_domain = 0;
TOK822 *domain = 0;
char *destination;
const char *blame = 0;
const char *rcpt_domain;
int addr_len;
int loop_count;
int loop_max;
char *local;
char *oper;
char *junk;
vstring_strcpy(saved_class_domain, "UNINITIALIZED SAVED_CLASS_DOMAIN");
*flags = 0;
vstring_strcpy(channel, "CHANNEL NOT UPDATED");
vstring_strcpy(nexthop, "NEXTHOP NOT UPDATED");
vstring_strcpy(nextrcpt, "NEXTRCPT NOT UPDATED");
/*
* The address is in internalized (unquoted) form, so we must externalize
* it first before we can parse it.
* The address is in internalized (unquoted) form.
*
* While quoting the address local part, do not treat @ as a special
* character. This allows us to detect extra @ characters and block
* source routed relay attempts.
* In an ideal world we would parse the externalized address form as given
* to us by the sender.
*
* But practically, we have to look at the unquoted form so that routing
* characters like @ remain visible, in order to stop user@domain@domain
* relay attempts when forwarding mail to a primary Sendmail MX host.
* However, in the real world we have to look for routing characters like
* %@! in the address local-part, even when that information is quoted
* due to the presence of special characters or whitespace. Although
* technically incorrect, this is needed to stop user@domain@domain relay
* attempts when forwarding mail to a Sendmail MX host.
*
* This suggests that we parse the address in internalized (unquoted) form.
* Unfortunately, if we do that, the unparser generates incorrect white
* space between adjacent non-operator tokens. Example: ``first last''
* needs white space, but ``stuff[stuff]'' does not. This is is not a
* problem when unparsing the result from parsing externalized forms,
* because the parser/unparser were designed for valid externalized forms
* where ``stuff[stuff]'' does not happen.
*
* As a workaround we start with the quoted form and then dequote the
* local-part only where needed. This will do the right thing in most
* (but not all) cases.
*/
if (var_resolve_dequoted) {
tree = tok822_scan_addr(addr);
} else {
quote_822_local(addr_buf, addr);
tree = tok822_scan_addr(vstring_str(addr_buf));
addr_len = strlen(addr);
quote_822_local(addr_buf, addr);
tree = tok822_scan_addr(vstring_str(addr_buf));
/*
* Let the optimizer replace multiple expansions of this macro by a GOTO
* to a single instance.
*/
#define FREE_MEMORY_AND_RETURN { \
if (saved_domain) \
tok822_free_tree(saved_domain); \
if(tree) \
tok822_free_tree(tree); \
if (addr_buf) \
vstring_free(addr_buf); \
}
/*
* Preliminary resolver: strip off all instances of the local domain.
* Terminate when no destination domain is left over, or when the
* destination domain is remote.
*
* XXX To whom it may concern. If you change the resolver loop below, or
* quote_822_local.c, or tok822_parse.c, be sure to re-run the tests
* under "make resolve_clnt_test" in the global directory.
*/
#define RESOLVE_LOCAL(domain) \
resolve_local(STR(tok822_internalize(addr_buf, domain, TOK822_STR_DEFL)))
while (tree->head) {
dict_errno = 0;
for (loop_count = 0, loop_max = addr_len + 100; /* void */ ; loop_count++) {
/*
* Grr. resolve_local() table lookups may fail. It may be OK for
* local file lookup code to abort upon failure, but with
* network-based tables it is preferable to return an error
* indication to the requestor.
*/
if (dict_errno) {
*flags |= RESOLVE_FLAG_FAIL;
FREE_MEMORY_AND_RETURN;
}
/*
* XXX Should never happen, but if this happens with some
* pathological address, then that is not sufficient reason to
* disrupt the operation of an MTA.
*/
if (loop_count > loop_max) {
msg_warn("resolve_addr: <%s>: giving up after %d iterations",
addr, loop_count);
break;
}
/*
* Strip trailing dot at end of domain, but not dot-dot. This merely
* makes diagnostics more accurate by leaving bogus addresses alone.
*/
if (tree->tail->type == '.'
if (tree->tail
&& tree->tail->type == '.'
&& tok822_rfind_type(tree->tail, '@') != 0
&& tree->tail->prev->type != '.')
tok822_free_tree(tok822_sub_keep_before(tree, tree->tail));
@ -208,26 +254,15 @@ void resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
/*
* Strip trailing @.
*/
if (tree->tail->type == '@') {
if (tree->tail
&& tree->tail->type == '@')
tok822_free_tree(tok822_sub_keep_before(tree, tree->tail));
continue;
}
/*
* A lone empty string becomes the postmaster.
*/
if (tree->head == tree->tail && tree->head->type == TOK822_QSTRING
&& VSTRING_LEN(tree->head->vstr) == 0) {
tok822_free(tree->head);
tree->head = tok822_scan(MAIL_ADDR_POSTMASTER, &tree->tail);
rewrite_tree(REWRITE_CANON, tree);
}
/*
* Strip (and save) @domain if local.
*/
if ((domain = tok822_rfind_type(tree->tail, '@')) != 0) {
if (RESOLVE_LOCAL(domain->next) == 0)
if (domain->next && RESOLVE_LOCAL(domain->next) == 0)
break;
tok822_sub_keep_before(tree, domain);
if (saved_domain)
@ -239,32 +274,65 @@ void resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
* After stripping the local domain, if any, replace foo%bar by
* foo@bar, site!user by user@site, rewrite to canonical form, and
* retry.
*
* Otherwise we're done.
*/
if (tok822_rfind_type(tree->tail, '@')
|| (var_swap_bangpath && tok822_rfind_type(tree->tail, '!'))
|| (var_percent_hack && tok822_rfind_type(tree->tail, '%'))) {
rewrite_tree(REWRITE_CANON, tree);
} else {
domain = 0;
break;
continue;
}
/*
* If the local-part is a quoted string, crack it open when we're
* permitted to do so and look for routing operators. This is
* technically incorrect, but is needed to stop relaying problems.
*
* XXX Do another feeble attempt to keep local-part info quoted.
*/
if (var_resolve_dequoted
&& tree->head && tree->head == tree->tail
&& tree->head->type == TOK822_QSTRING
&& ((oper = strrchr(local = STR(tree->head->vstr), '@')) != 0
|| (var_percent_hack && (oper = strrchr(local, '%')) != 0)
|| (var_swap_bangpath && (oper = strrchr(local, '!')) != 0))) {
if (*oper == '%')
*oper = '@';
tok822_internalize(addr_buf, tree->head, TOK822_STR_DEFL);
if (*oper == '@') {
junk = mystrdup(STR(addr_buf));
quote_822_local(addr_buf, junk);
myfree(junk);
}
tok822_free(tree->head);
tree->head = tok822_scan(STR(addr_buf), &tree->tail);
rewrite_tree(REWRITE_CANON, tree);
continue;
}
/*
* An empty local-part or an empty quoted string local-part becomes
* the local MAILER-DAEMON, for consistency with our own From:
* message headers.
*/
if (tree->head && tree->head == tree->tail
&& tree->head->type == TOK822_QSTRING
&& VSTRING_LEN(tree->head->vstr) == 0) {
tok822_free(tree->head);
tree->head = 0;
}
if (tree->head == 0)
tree->head = tok822_scan(MAIL_ADDR_MAIL_DAEMON, &tree->tail);
/*
* We're done. There are no domains left to strip off the address,
* and all null local-part information is sanitized.
*/
domain = 0;
break;
}
/*
* If the destination is non-local, recognize routing operators in the
* address localpart. This is needed to prevent backup MX hosts from
* relaying third-party destinations through primary MX hosts, otherwise
* the backup host could end up on black lists. Ignore local
* swap_bangpath and percent_hack settings because we can't know how the
* primary MX host is set up.
*/
if (domain && domain->prev)
if (tok822_rfind_type(domain->prev, '@') != 0
|| tok822_rfind_type(domain->prev, '!') != 0
|| tok822_rfind_type(domain->prev, '%') != 0)
*flags |= RESOLVE_FLAG_ROUTED;
vstring_free(addr_buf);
addr_buf = 0;
/*
* Make sure the resolved envelope recipient has the user@domain form. If
@ -275,105 +343,134 @@ void resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
if (saved_domain) {
tok822_sub_append(tree, saved_domain);
saved_domain = 0;
} else { /* Aargh! Always! */
} else {
tok822_sub_append(tree, tok822_alloc('@', (char *) 0));
tok822_sub_append(tree, tok822_scan(var_myhostname, (TOK822 **) 0));
}
}
tok822_internalize(nextrcpt, tree, TOK822_STR_DEFL);
/*
* With relay or other non-local destinations, the relayhost setting
* overrides the destination domain name.
* Transform the recipient address back to internal form.
*
* With virtual, relay, or other non-local destinations, give the highest
* precedence to delivery transport associated next-hop information.
* XXX This may produce incorrect results if we cracked open a quoted
* local-part with routing operators; see discussion above at the top of
* the big loop.
*/
tok822_internalize(nextrcpt, tree, TOK822_STR_DEFL);
rcpt_domain = strrchr(STR(nextrcpt), '@') + 1;
if (*rcpt_domain == '[' ? !valid_hostliteral(rcpt_domain, DONT_GRIPE) :
!valid_hostname(rcpt_domain, DONT_GRIPE))
*flags |= RESOLVE_FLAG_ERROR;
tok822_free_tree(tree);
tree = 0;
/*
* Recognize routing operators in the local-part, even when we do not
* recognize ! or % as valid routing operators locally. This is needed to
* prevent backup MX hosts from relaying third-party destinations through
* primary MX hosts, otherwise the backup host could end up on black
* lists. Ignore local swap_bangpath and percent_hack settings because we
* can't know how the next MX host is set up.
*/
if (strcmp(STR(nextrcpt) + strcspn(STR(nextrcpt), "@!%") + 1, rcpt_domain))
*flags |= RESOLVE_FLAG_ROUTED;
/*
* With local, virtual, relay, or other non-local destinations, give the
* highest precedence to transport associated nexthop information.
*
* XXX With the virtual mailbox transport, set the nexthop information to
* $myhostname, so that in default configurations the virtual delivery
* agent will not use separate queues for every $virtual_mailbox_domains
* domain name. That prevents anomalies where many low-traffic domains
* starve a high-traffic domain.
* Otherwise, with relay or other non-local destinations, the relayhost
* setting overrides the destination domain name.
*
* XXX Nag if the domain is listed in multiple domain lists. The effect is
* implementation defined, and may break when internals change.
* XXX Nag if the recipient domain is listed in multiple domain lists. The
* result is implementation defined, and may break when internals change.
*
* For now, we distinguish only a fixed number of address classes.
* Eventually this may become extensible, so that new classes can be
* configured with their own domain list, delivery transport, and
* recipient table.
*/
#define STREQ(x,y) (strcmp((x), (y)) == 0)
dict_errno = 0;
if (domain != 0) {
tok822_internalize(nexthop, domain->next, TOK822_STR_DEFL);
vstring_strcpy(saved_class_domain, STR(nexthop));
if (STR(nexthop)[strspn(STR(nexthop), "[]0123456789.")] != 0
&& valid_hostname(STR(nexthop), DONT_GRIPE) == 0)
*flags |= RESOLVE_FLAG_ERROR;
/*
* Virtual alias domain.
*/
if (virt_alias_doms
&& string_list_match(virt_alias_doms, STR(nexthop))) {
&& string_list_match(virt_alias_doms, rcpt_domain)) {
if (var_helpful_warnings
&& virt_mailbox_doms
&& string_list_match(virt_mailbox_doms, STR(nexthop)))
&& string_list_match(virt_mailbox_doms, rcpt_domain))
msg_warn("do not list domain %s in BOTH %s and %s",
STR(nexthop), VAR_VIRT_ALIAS_DOMS, VAR_VIRT_MAILBOX_DOMS);
vstring_strcpy(channel, var_error_transport);
rcpt_domain, VAR_VIRT_ALIAS_DOMS,
VAR_VIRT_MAILBOX_DOMS);
vstring_strcpy(channel, MAIL_SERVICE_ERROR);
vstring_strcpy(nexthop, "User unknown in virtual alias table");
vstring_strcpy(saved_class_domain, var_myhostname);
blame = VAR_ERROR_TRANSPORT;
*flags |= RESOLVE_CLASS_ALIAS;
} else if (dict_errno != 0) {
msg_warn("%s lookup failure", VAR_VIRT_ALIAS_DOMS);
*flags |= RESOLVE_FLAG_FAIL;
} else if (virt_mailbox_doms
&& string_list_match(virt_mailbox_doms, STR(nexthop))) {
FREE_MEMORY_AND_RETURN;
}
/*
* Virtual mailbox domain.
*/
else if (virt_mailbox_doms
&& string_list_match(virt_mailbox_doms, rcpt_domain)) {
vstring_strcpy(channel, var_virt_transport);
vstring_strcpy(nexthop, var_myhostname);
vstring_strcpy(saved_class_domain, var_myhostname);
vstring_strcpy(nexthop, rcpt_domain);
blame = VAR_VIRT_TRANSPORT;
*flags |= RESOLVE_CLASS_VIRTUAL;
} else if (dict_errno != 0) {
msg_warn("%s lookup failure", VAR_VIRT_MAILBOX_DOMS);
*flags |= RESOLVE_FLAG_FAIL;
FREE_MEMORY_AND_RETURN;
} else {
/*
* Off-host relay destination.
*/
if (relay_domains
&& domain_list_match(relay_domains, STR(nexthop))) {
&& domain_list_match(relay_domains, rcpt_domain)) {
vstring_strcpy(channel, var_relay_transport);
blame = VAR_RELAY_TRANSPORT;
*flags |= RESOLVE_CLASS_RELAY;
} else if (dict_errno != 0) {
msg_warn("%s lookup failure", VAR_RELAY_DOMAINS);
*flags |= RESOLVE_FLAG_FAIL;
} else {
FREE_MEMORY_AND_RETURN;
}
/*
* Other off-host destination.
*/
else {
vstring_strcpy(channel, var_def_transport);
blame = VAR_DEF_TRANSPORT;
*flags |= RESOLVE_CLASS_DEFAULT;
}
if (*var_relayhost) {
/*
* With off-host delivery, relayhost overrides recipient domain.
*/
if (*var_relayhost)
vstring_strcpy(nexthop, var_relayhost);
if (!STREQ(STR(channel), var_error_transport))
vstring_strcpy(saved_class_domain, STR(nexthop));
}
}
if ((destination = split_at(STR(channel), ':')) != 0 && *destination) {
vstring_strcpy(nexthop, destination);
if (!STREQ(STR(channel), var_error_transport))
vstring_strcpy(saved_class_domain, STR(nexthop));
else
vstring_strcpy(nexthop, rcpt_domain);
}
}
/*
* Local delivery. Set up the default local transport and the default
* next-hop hostname (myself).
*
* XXX Set the nexthop information to myhostname, so that the local delivery
* agent does not get a queue for every domain name in $mydestination or
* for every network address in $inet_interfaces.
* Local delivery.
*
* XXX Nag if the domain is listed in multiple domain lists. The effect is
* implementation defined, and may break when internals change.
*/
else {
if (var_helpful_warnings
&& (rcpt_domain = strrchr(STR(nextrcpt), '@')) != 0) {
rcpt_domain++;
if (var_helpful_warnings) {
if (virt_alias_doms
&& string_list_match(virt_alias_doms, rcpt_domain))
msg_warn("do not list domain %s in BOTH %s and %s",
@ -384,56 +481,67 @@ void resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
rcpt_domain, VAR_MYDEST, VAR_VIRT_MAILBOX_DOMS);
}
vstring_strcpy(channel, var_local_transport);
vstring_strcpy(nexthop, rcpt_domain);
blame = VAR_LOCAL_TRANSPORT;
if ((destination = split_at(STR(channel), ':')) == 0
|| *destination == 0)
destination = var_myhostname;
vstring_strcpy(nexthop, destination);
if (!STREQ(STR(channel), var_error_transport))
vstring_strcpy(saved_class_domain, STR(nexthop));
else
vstring_strcpy(saved_class_domain, var_myhostname);
*flags |= RESOLVE_CLASS_LOCAL;
}
/*
* Sanity checks.
* An explicit main.cf transport:nexthop setting overrides the nexthop.
*
* XXX We depend on this mechanism to enforce per-recipient concurrencies
* for local recipients. With "local_transport = local:$myhostname" we
* force mail for any domain in $mydestination/$inet_interfaces to share
* the same queue.
*/
if ((*flags & RESOLVE_FLAG_FAIL) == 0) {
if (*STR(channel) == 0) {
if (blame == 0)
msg_panic("%s: null blame", myname);
msg_warn("file %s/%s: parameter %s: null transport is not allowed",
var_config_dir, MAIN_CONF_FILE, blame);
*flags |= RESOLVE_FLAG_FAIL;
}
if (*STR(nexthop) == 0)
msg_panic("%s: null nexthop", myname);
}
if ((destination = split_at(STR(channel), ':')) != 0 && *destination)
vstring_strcpy(nexthop, destination);
/*
* The transport map overrides any transport and next-hop host info that
* is set up above.
*
* With error transports, the nexthop info is arbitrary text that must not
* be passed on to regular delivery agents. When the transport map
* overrides an error transport without overriding the nexthop
* information, or vice versa, update the nexthop information
* appropriately.
* Sanity checks.
*/
if ((*flags & RESOLVE_FLAG_FAIL) == 0 && *var_transport_maps) {
vstring_strcpy(saved_class_channel, STR(channel));
vstring_strcpy(saved_class_nexthop, STR(nexthop));
if (*STR(channel) == 0) {
if (blame == 0)
msg_panic("%s: null blame", myname);
msg_warn("file %s/%s: parameter %s: null transport is not allowed",
var_config_dir, MAIN_CONF_FILE, blame);
*flags |= RESOLVE_FLAG_FAIL;
FREE_MEMORY_AND_RETURN;
}
if (*STR(nexthop) == 0)
msg_panic("%s: null nexthop", myname);
if (transport_lookup(STR(nextrcpt), channel, nexthop) != 0) {
if (!STREQ(STR(saved_class_channel), STR(channel))
&& STREQ(STR(saved_class_nexthop), STR(nexthop))) {
vstring_strcpy(nexthop, STREQ(STR(channel), var_error_transport) ?
"Address is not deliverable" : STR(saved_class_domain));
}
} else if (dict_errno != 0) {
/*
* The transport map can selectively override any transport and/or
* nexthop host info that is set up above. Unfortunately, the syntax for
* nexthop information is transport specific. We therefore need sane and
* intuitive semantics for transport map entries that specify a channel
* but no nexthop.
*
* With non-error transports, the initial nexthop information is the
* recipient domain. However, specific main.cf transport definitions may
* specify a transport-specific destination, such as a host + TCP socket,
* or the pathname of a UNIX-domain socket. With less precedence than
* main.cf transport definitions, a main.cf relayhost definition may also
* override nexthop information for off-host deliveries.
*
* With the error transport, the nexthop information is free text that
* specifies the reason for non-delivery.
*
* Because nexthop syntax is transport specific we reset the nexthop
* information to the recipient domain when the transport table specifies
* a transport without also specifying the nexthop information.
*
* Subtle note: reset nexthop even when the transport table does not change
* the transport. Otherwise it is hard to get rid of main.cf specified
* nexthop information.
*/
if (*var_transport_maps) {
if (transport_lookup(STR(nextrcpt), rcpt_domain, channel, nexthop) == 0
&& dict_errno != 0) {
msg_warn("%s lookup failure", VAR_TRANSPORT_MAPS);
*flags |= RESOLVE_FLAG_FAIL;
FREE_MEMORY_AND_RETURN;
}
}
@ -448,26 +556,24 @@ void resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
*/
#define IGNORE_ADDR_EXTENSION ((char **) 0)
if ((*flags & RESOLVE_FLAG_FAIL) == 0 && relocated_maps != 0) {
if (relocated_maps != 0) {
const char *newloc;
if ((newloc = mail_addr_find(relocated_maps, STR(nextrcpt),
IGNORE_ADDR_EXTENSION)) != 0) {
vstring_strcpy(channel, var_error_transport);
vstring_strcpy(channel, MAIL_SERVICE_ERROR);
vstring_sprintf(nexthop, "User has moved to %s", newloc);
} else if (dict_errno != 0) {
msg_warn("%s lookup failure", VAR_RELOCATED_MAPS);
*flags |= RESOLVE_FLAG_FAIL;
FREE_MEMORY_AND_RETURN;
}
}
/*
* Clean up.
*/
if (saved_domain)
tok822_free_tree(saved_domain);
tok822_free_tree(tree);
vstring_free(addr_buf);
FREE_MEMORY_AND_RETURN;
}
/* Static, so they can be used by the network protocol interface only. */
@ -516,9 +622,6 @@ void resolve_init(void)
channel = vstring_alloc(100);
nexthop = vstring_alloc(100);
nextrcpt = vstring_alloc(100);
saved_class_channel = vstring_alloc(100);
saved_class_nexthop = vstring_alloc(100);
saved_class_domain = vstring_alloc(100);
if (*var_virt_alias_doms)
virt_alias_doms =

View File

@ -90,6 +90,12 @@ void rewrite_tree(char *unused_ruleset, TOK822 *tree)
TOK822 *bang;
TOK822 *local;
/*
* XXX If you change this module, quote_822_local.c, or tok822_parse.c,
* be sure to re-run the tests under "make rewrite_clnt_test" and "make
* resolve_clnt_test" in the global directory.
*/
/*
* Sanity check.
*/
@ -158,10 +164,13 @@ void rewrite_tree(char *unused_ruleset, TOK822 *tree)
}
/*
* Append missing .domain
* Append missing .domain, but leave broken forms ending in @ alone. This
* merely makes diagnostics more accurate by leaving bogus addresses
* alone.
*/
if (var_append_dot_mydomain != 0
&& (domain = tok822_rfind_type(tree->tail, '@')) != 0
&& domain != tree->tail
&& tok822_find_type(domain, TOK822_DOMLIT) == 0
&& tok822_find_type(domain, '.') == 0) {
tok822_sub_append(tree, tok822_alloc('.', (char *) 0));
@ -169,13 +178,17 @@ void rewrite_tree(char *unused_ruleset, TOK822 *tree)
}
/*
* Strip trailing dot at end of domain, but not dot-dot. This merely
* makes diagnostics more accurate by leaving bogus addresses alone.
* Strip trailing dot at end of domain, but not dot-dot or @-dot. This
* merely makes diagnostics more accurate by leaving bogus addresses
* alone.
*/
#if 0
if (tree->tail->type == '.'
&& tok822_rfind_type(tree->tail, '@') != 0
&& tree->tail->prev->type != '.')
&& tree->tail->prev
&& tree->tail->prev->type != '.'
&& tree->tail->prev->type != '@')
tok822_free_tree(tok822_sub_keep_before(tree, tree->tail));
#endif
}
/* rewrite_addr - rewrite address according to rule set */

View File

@ -8,8 +8,9 @@
/*
/* void transport_init()
/*
/* int transport_lookup(address, channel, nexthop)
/* int transport_lookup(address, rcpt_domain, channel, nexthop)
/* const char *address;
/* const char *rcpt_domain;
/* VSTRING *channel;
/* VSTRING *nexthop;
/* DESCRIPTION
@ -65,6 +66,7 @@
#include <mail_params.h>
#include <maps.h>
#include <match_parent_style.h>
#include <mail_proto.h>
/* Application-specific. */
@ -77,13 +79,6 @@ static VSTRING *wildcard_nexthop;
#define STR(x) vstring_str(x)
/*
* Macro for consistent updates of the transport and nexthop results.
*/
#define UPDATE_IF_SPECIFIED(dst, src) do { \
if ((src) && *(src)) vstring_strcpy((dst), (src)); \
} while (0)
/* transport_init - pre-jail initialization */
void transport_init(void)
@ -95,15 +90,52 @@ void transport_init(void)
transport_match_parent_style = match_parent_style(VAR_TRANSPORT_MAPS);
}
/* update_entry - update from transport table entry */
static void update_entry(const char *new_channel, const char *new_nexthop,
const char *rcpt_domain, VSTRING *channel,
VSTRING *nexthop)
{
/*
* :[nexthop] means don't change the channel, and don't change the
* nexthop unless a non-default nexthop is specified. Thus, a right-hand
* side of ":" is the transport table equivalent of a NOOP.
*/
if (*new_channel == 0) { /* :[nexthop] */
if (*new_nexthop != 0)
vstring_strcpy(nexthop, new_nexthop);
}
/*
* transport[:[nexthop]] means change the channel, and reset the nexthop
* to the default unless a non-default nexthop is specified.
*/
else {
vstring_strcpy(channel, new_channel);
if (*new_nexthop != 0)
vstring_strcpy(nexthop, new_nexthop);
else if (strcmp(STR(channel), MAIL_SERVICE_ERROR) != 0)
vstring_strcpy(nexthop, rcpt_domain);
else
vstring_strcpy(nexthop, "Address is undeliverable");
}
}
/* find_transport_entry - look up and parse transport table entry */
static int find_transport_entry(const char *key, int flags,
VSTRING *channel, VSTRING *nexthop)
static int find_transport_entry(const char *key, const char *rcpt_domain,
int flags, VSTRING *channel, VSTRING *nexthop)
{
char *saved_value;
const char *host;
const char *value;
/*
* Reset previous error history.
*/
dict_errno = 0;
#define FOUND 1
#define NOTFOUND 0
@ -115,11 +147,8 @@ static int find_transport_entry(const char *key, int flags,
*
* XXX Should report lookup failure status to caller instead of aborting.
*/
if ((value = maps_find(transport_path, key, flags)) == 0) {
if (dict_errno != 0)
msg_fatal("transport table lookup problem.");
if ((value = maps_find(transport_path, key, flags)) == 0)
return (NOTFOUND);
}
/*
* It would be great if we could specify a recipient address in the
@ -131,8 +160,8 @@ static int find_transport_entry(const char *key, int flags,
else {
saved_value = mystrdup(value);
host = split_at(saved_value, ':');
UPDATE_IF_SPECIFIED(nexthop, host);
UPDATE_IF_SPECIFIED(channel, saved_value);
update_entry(saved_value, host ? host : "", rcpt_domain,
channel, nexthop);
myfree(saved_value);
return (FOUND);
}
@ -159,13 +188,15 @@ void transport_wildcard_init(void)
#define FULL 0
#define PARTIAL DICT_FLAG_FIXED
if (find_transport_entry(WILDCARD, FULL, channel, nexthop)) {
if (find_transport_entry(WILDCARD, "", FULL, channel, nexthop)) {
wildcard_channel = channel;
wildcard_nexthop = nexthop;
if (msg_verbose)
msg_info("wildcard_{chan:hop}={%s:%s}",
vstring_str(wildcard_channel), vstring_str(wildcard_nexthop));
} else {
if (dict_errno != 0)
msg_fatal("transport table initialization problem.");
vstring_free(channel);
vstring_free(nexthop);
}
@ -173,9 +204,10 @@ void transport_wildcard_init(void)
/* transport_lookup - map a transport domain */
int transport_lookup(const char *addr, VSTRING *channel, VSTRING *nexthop)
int transport_lookup(const char *addr, const char *rcpt_domain,
VSTRING *channel, VSTRING *nexthop)
{
char *full_addr = lowercase(mystrdup(*addr ? addr : var_xport_null_key));
char *full_addr;
char *stripped_addr;
char *ratsign = 0;
const char *name;
@ -185,6 +217,15 @@ int transport_lookup(const char *addr, VSTRING *channel, VSTRING *nexthop)
#define STREQ(x,y) (strcmp((x), (y)) == 0)
#define DISCARD_EXTENSION ((char **) 0)
/*
* The null recipient is rewritten to the local mailer daemon address.
*/
if (*addr == 0) {
msg_warn("transport_lookup: null address - skipping table lookup");
return (NOTFOUND);
}
full_addr = lowercase(mystrdup(addr));
/*
* The optimizer will replace multiple instances of this macro expansion
* by gotos to a single instance that does the same thing.
@ -194,16 +235,6 @@ int transport_lookup(const char *addr, VSTRING *channel, VSTRING *nexthop)
return (x); \
}
/*
* If this is a special address such as <> do only one lookup of the full
* string. Specify the FULL flag to include regexp maps in the query.
*/
if (STREQ(full_addr, var_xport_null_key)) {
if (find_transport_entry(full_addr, FULL, channel, nexthop))
RETURN_FREE(FOUND);
RETURN_FREE(NOTFOUND);
}
/*
* Look up the full address with the FULL flag to include regexp maps in
* the query.
@ -211,8 +242,10 @@ int transport_lookup(const char *addr, VSTRING *channel, VSTRING *nexthop)
if ((ratsign = strrchr(full_addr, '@')) == 0 || ratsign[1] == 0)
msg_panic("transport_lookup: bad address: \"%s\"", full_addr);
if (find_transport_entry(full_addr, FULL, channel, nexthop))
if (find_transport_entry(full_addr, rcpt_domain, FULL, channel, nexthop))
RETURN_FREE(FOUND);
if (dict_errno != 0)
RETURN_FREE(NOTFOUND);
/*
* If the full address did not match, and there is an address extension,
@ -221,13 +254,14 @@ int transport_lookup(const char *addr, VSTRING *channel, VSTRING *nexthop)
*/
if ((stripped_addr = strip_addr(full_addr, DISCARD_EXTENSION,
*var_rcpt_delim)) != 0) {
if (find_transport_entry(stripped_addr, PARTIAL,
channel, nexthop)) {
myfree(stripped_addr);
found = find_transport_entry(stripped_addr, rcpt_domain, PARTIAL,
channel, nexthop);
myfree(stripped_addr);
if (found)
RETURN_FREE(FOUND);
} else {
myfree(stripped_addr);
}
if (dict_errno != 0)
RETURN_FREE(NOTFOUND);
}
/*
@ -246,9 +280,11 @@ int transport_lookup(const char *addr, VSTRING *channel, VSTRING *nexthop)
* Specify that the lookup key is partial, to avoid matching partial keys
* with regular expressions.
*/
for (found = 0, name = ratsign + 1; /* void */ ; name = next) {
if (find_transport_entry(name, PARTIAL, channel, nexthop))
for (name = ratsign + 1; /* void */ ; name = next) {
if (find_transport_entry(name, rcpt_domain, PARTIAL, channel, nexthop))
RETURN_FREE(FOUND);
if (dict_errno != 0)
RETURN_FREE(NOTFOUND);
if ((next = strchr(name + 1, '.')) == 0)
break;
if (transport_match_parent_style == MATCH_FLAG_PARENT)
@ -259,8 +295,8 @@ int transport_lookup(const char *addr, VSTRING *channel, VSTRING *nexthop)
* Fall back to the wild-card entry.
*/
if (wildcard_channel) {
UPDATE_IF_SPECIFIED(channel, STR(wildcard_channel));
UPDATE_IF_SPECIFIED(nexthop, STR(wildcard_nexthop));
update_entry(STR(wildcard_channel), STR(wildcard_nexthop),
rcpt_domain, channel, nexthop);
RETURN_FREE(FOUND);
}

View File

@ -18,7 +18,7 @@
*/
extern void transport_init(void);
extern void transport_wildcard_init(void);
extern int transport_lookup(const char *, VSTRING *, VSTRING *);
extern int transport_lookup(const char *, const char *, VSTRING *, VSTRING *);
/* LICENSE
/* .ad

View File

@ -101,15 +101,6 @@
/* .sp
/* Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
/* for details. The :\fInexthop\fR part is optional.
/* .IP \fBerror_transport\fR
/* Where to deliver mail for non-existent recipients in domains
/* that match \fBvirtual_alias_domains\fR (all recipients
/* in simulated virtual domains must be aliased to some other
/* local or remote domain), or for recipients that have moved.
/* The default transport is \fBerror\fR.
/* .sp
/* Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
/* for details. The :\fInexthop\fR part is optional.
/* .IP \fBvirtual_transport\fR
/* Where to deliver mail for non-local domains that match
/* \fB$virtual_mailbox_domains\fR.
@ -144,8 +135,6 @@
/* .IP \fBtransport_maps\fR
/* List of tables with \fIdomain\fR to (\fItransport, nexthop\fR)
/* mappings.
/* .IP \fBtransport_null_address_lookup_key\fR
/* Lookup key to be used for the null address.
/* SEE ALSO
/* master(8) process manager
/* syslogd(8) system logging
@ -208,11 +197,9 @@ bool var_append_dot_mydomain;
bool var_append_at_myorigin;
bool var_percent_hack;
char *var_local_transport;
char *var_error_transport;
char *var_virt_transport;
char *var_relay_transport;
int var_resolve_dequoted;
char *var_xport_null_key;
char *var_virt_alias_maps; /* XXX virtual_alias_domains */
char *var_virt_mailbox_maps; /* XXX virtual_mailbox_domains */
char *var_virt_alias_doms;
@ -284,10 +271,8 @@ int main(int argc, char **argv)
static CONFIG_STR_TABLE str_table[] = {
VAR_TRANSPORT_MAPS, DEF_TRANSPORT_MAPS, &var_transport_maps, 0, 0,
VAR_LOCAL_TRANSPORT, DEF_LOCAL_TRANSPORT, &var_local_transport, 1, 0,
VAR_ERROR_TRANSPORT, DEF_ERROR_TRANSPORT, &var_error_transport, 1, 0,
VAR_VIRT_TRANSPORT, DEF_VIRT_TRANSPORT, &var_virt_transport, 1, 0,
VAR_RELAY_TRANSPORT, DEF_RELAY_TRANSPORT, &var_relay_transport, 1, 0,
VAR_XPORT_NULL_KEY, DEF_XPORT_NULL_KEY, &var_xport_null_key, 1, 0,
VAR_VIRT_ALIAS_MAPS, DEF_VIRT_ALIAS_MAPS, &var_virt_alias_maps, 0, 0,
VAR_VIRT_ALIAS_DOMS, DEF_VIRT_ALIAS_DOMS, &var_virt_alias_doms, 0, 0,
VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_virt_mailbox_maps, 0, 0,

View File

@ -13,6 +13,10 @@
/* int valid_hostaddr(addr, gripe)
/* const char *addr;
/* int gripe;
/*
/* int valid_hostliteral(addr, gripe)
/* const char *addr;
/* int gripe;
/* DESCRIPTION
/* valid_hostname() scrutinizes a hostname: the name should be no
/* longer than VALID_HOSTNAME_LEN characters, should contain only
@ -20,9 +24,11 @@
/* no leading or trailing dots or hyphens, no labels longer than
/* VALID_LABEL_LEN characters, and no numeric top-level domain.
/*
/* valid_hostaddr() requirs that the input is a valid string
/* valid_hostaddr() requires that the input is a valid string
/* representation of an internet network address.
/*
/* valid_hostliteral() requires an address enclosed in [].
/*
/* These routines operate silently unless the gripe parameter
/* specifies a non-zero value. The macros DO_GRIPE and DONT_GRIPE
/* provide suitable constants.
@ -192,6 +198,39 @@ int valid_hostaddr(const char *addr, int gripe)
return (1);
}
/* valid_hostliteral - validate address literal */
int valid_hostliteral(const char *addr, int gripe)
{
const char *myname = "valid_hostliteral";
char buf[100];
const char *last;
if (*addr != '[') {
if (gripe)
msg_warn("%s: '[' expected at start: %.100s", myname, addr);
return (0);
}
if ((last = strchr(addr, ']')) == 0) {
if (gripe)
msg_warn("%s: ']' expected at end: %.100s", myname, addr);
return (0);
}
if (last[1]) {
if (gripe)
msg_warn("%s: unexpected text after ']': %.100s", myname, addr);
return (0);
}
if (last - addr >= sizeof(buf)) {
if (gripe)
msg_warn("%s: too much text: %.100s", myname, addr);
return (0);
}
strncpy(buf, addr + 1, last - addr - 1);
buf[last - addr - 1] = 0;
return (valid_hostaddr(buf, gripe));
}
#ifdef TEST
/*
@ -216,6 +255,7 @@ int main(int unused_argc, char **argv)
msg_info("testing: \"%s\"", vstring_str(buffer));
valid_hostname(vstring_str(buffer), DO_GRIPE);
valid_hostaddr(vstring_str(buffer), DO_GRIPE);
valid_hostliteral(vstring_str(buffer), DO_GRIPE);
}
exit(0);
}

View File

@ -21,6 +21,7 @@
extern int valid_hostname(const char *, int);
extern int valid_hostaddr(const char *, int);
extern int valid_hostliteral(const char *, int);
/* LICENSE
/* .ad

View File

@ -36,3 +36,8 @@ a.bb-.b
a.b.-bb
a.b.bb-
a-a.b-b
[1.2.3.4]
[321.255.255.255]
[1.2.3.4
[1.2.3.4]foo
[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]

View File

@ -1,101 +1,158 @@
./valid_hostname: testing: "123456789012345678901234567890123456789012345678901234567890123"
./valid_hostname: warning: valid_hostname: numeric hostname: 123456789012345678901234567890123456789012345678901234567890123
./valid_hostname: warning: valid_hostaddr: invalid octet value: 123456789012345678901234567890123456789012345678901234567890123
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 123456789012345678901234567890123456789012345678901234567890123
./valid_hostname: testing: "1234567890123456789012345678901234567890123456789012345678901234"
./valid_hostname: warning: valid_hostname: hostname label too long: 1234567890123456789012345678901234567890123456789012345678901234
./valid_hostname: warning: valid_hostaddr: invalid octet value: 1234567890123456789012345678901234567890123456789012345678901234
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1234567890123456789012345678901234567890123456789012345678901234
./valid_hostname: testing: "a.123456789012345678901234567890123456789012345678901234567890123.b"
./valid_hostname: warning: valid_hostaddr: invalid character 97(decimal): a.123456789012345678901234567890123456789012345678901234567890123.b
./valid_hostname: warning: valid_hostliteral: '[' expected at start: a.123456789012345678901234567890123456789012345678901234567890123.b
./valid_hostname: testing: "a.1234567890123456789012345678901234567890123456789012345678901234.b"
./valid_hostname: warning: valid_hostname: hostname label too long: a.1234567890123456789012345678901234567890123456789012345678901234.b
./valid_hostname: warning: valid_hostaddr: invalid character 97(decimal): a.1234567890123456789012345678901234567890123456789012345678901234.b
./valid_hostname: warning: valid_hostliteral: '[' expected at start: a.1234567890123456789012345678901234567890123456789012345678901234.b
./valid_hostname: testing: "1.2.3.4"
./valid_hostname: warning: valid_hostname: numeric hostname: 1.2.3.4
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1.2.3.4
./valid_hostname: testing: "321.255.255.255"
./valid_hostname: warning: valid_hostname: numeric hostname: 321.255.255.255
./valid_hostname: warning: valid_hostaddr: invalid octet value: 321.255.255.255
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 321.255.255.255
./valid_hostname: testing: "0.0.0.0"
./valid_hostname: warning: valid_hostname: numeric hostname: 0.0.0.0
./valid_hostname: warning: valid_hostaddr: bad initial octet value: 0.0.0.0
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 0.0.0.0
./valid_hostname: testing: "255.255.255.255"
./valid_hostname: warning: valid_hostname: numeric hostname: 255.255.255.255
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 255.255.255.255
./valid_hostname: testing: "0.255.255.255"
./valid_hostname: warning: valid_hostname: numeric hostname: 0.255.255.255
./valid_hostname: warning: valid_hostaddr: bad initial octet value: 0.255.255.255
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 0.255.255.255
./valid_hostname: testing: "1.2.3.321"
./valid_hostname: warning: valid_hostname: numeric hostname: 1.2.3.321
./valid_hostname: warning: valid_hostaddr: invalid octet value: 1.2.3.321
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1.2.3.321
./valid_hostname: testing: "1.2.3"
./valid_hostname: warning: valid_hostname: numeric hostname: 1.2.3
./valid_hostname: warning: valid_hostaddr: invalid octet count: 1.2.3
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1.2.3
./valid_hostname: testing: "1.2.3.4.5"
./valid_hostname: warning: valid_hostname: numeric hostname: 1.2.3.4.5
./valid_hostname: warning: valid_hostaddr: invalid octet count: 1.2.3.4.5
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1.2.3.4.5
./valid_hostname: testing: "1..2.3.4"
./valid_hostname: warning: valid_hostname: misplaced delimiter: 1..2.3.4
./valid_hostname: warning: valid_hostaddr: misplaced dot: 1..2.3.4
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1..2.3.4
./valid_hostname: testing: ".1.2.3.4"
./valid_hostname: warning: valid_hostname: misplaced delimiter: .1.2.3.4
./valid_hostname: warning: valid_hostaddr: misplaced dot: .1.2.3.4
./valid_hostname: warning: valid_hostliteral: '[' expected at start: .1.2.3.4
./valid_hostname: testing: "1.2.3.4.5."
./valid_hostname: warning: valid_hostname: misplaced delimiter: 1.2.3.4.5.
./valid_hostname: warning: valid_hostaddr: misplaced dot: 1.2.3.4.5.
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1.2.3.4.5.
./valid_hostname: testing: "1"
./valid_hostname: warning: valid_hostname: numeric hostname: 1
./valid_hostname: warning: valid_hostaddr: invalid octet count: 1
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1
./valid_hostname: testing: "."
./valid_hostname: warning: valid_hostname: misplaced delimiter: .
./valid_hostname: warning: valid_hostaddr: misplaced dot: .
./valid_hostname: warning: valid_hostliteral: '[' expected at start: .
./valid_hostname: testing: ""
./valid_hostname: warning: valid_hostname: empty hostname
./valid_hostname: warning: valid_hostaddr: empty address
./valid_hostname: warning: valid_hostliteral: '[' expected at start:
./valid_hostname: testing: "321"
./valid_hostname: warning: valid_hostname: numeric hostname: 321
./valid_hostname: warning: valid_hostaddr: invalid octet value: 321
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 321
./valid_hostname: testing: "f"
./valid_hostname: warning: valid_hostaddr: invalid character 102(decimal): f
./valid_hostname: warning: valid_hostliteral: '[' expected at start: f
./valid_hostname: testing: "f.2.3.4"
./valid_hostname: warning: valid_hostaddr: invalid character 102(decimal): f.2.3.4
./valid_hostname: warning: valid_hostliteral: '[' expected at start: f.2.3.4
./valid_hostname: testing: "1f.2.3.4"
./valid_hostname: warning: valid_hostaddr: invalid character 102(decimal): 1f.2.3.4
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1f.2.3.4
./valid_hostname: testing: "f1.2.3.4"
./valid_hostname: warning: valid_hostaddr: invalid character 102(decimal): f1.2.3.4
./valid_hostname: warning: valid_hostliteral: '[' expected at start: f1.2.3.4
./valid_hostname: testing: "1.2f.3.4"
./valid_hostname: warning: valid_hostaddr: invalid character 102(decimal): 1.2f.3.4
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1.2f.3.4
./valid_hostname: testing: "1.f2.3.4"
./valid_hostname: warning: valid_hostaddr: invalid character 102(decimal): 1.f2.3.4
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1.f2.3.4
./valid_hostname: testing: "1.2.3.4f"
./valid_hostname: warning: valid_hostaddr: invalid character 102(decimal): 1.2.3.4f
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1.2.3.4f
./valid_hostname: testing: "1.2.3.f4"
./valid_hostname: warning: valid_hostaddr: invalid character 102(decimal): 1.2.3.f4
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1.2.3.f4
./valid_hostname: testing: "1.2.3.f"
./valid_hostname: warning: valid_hostaddr: invalid character 102(decimal): 1.2.3.f
./valid_hostname: warning: valid_hostliteral: '[' expected at start: 1.2.3.f
./valid_hostname: testing: "-.a.b"
./valid_hostname: warning: valid_hostname: misplaced hyphen: -.a.b
./valid_hostname: warning: valid_hostaddr: invalid character 45(decimal): -.a.b
./valid_hostname: warning: valid_hostliteral: '[' expected at start: -.a.b
./valid_hostname: testing: "a.-.b"
./valid_hostname: warning: valid_hostname: misplaced hyphen: a.-.b
./valid_hostname: warning: valid_hostaddr: invalid character 97(decimal): a.-.b
./valid_hostname: warning: valid_hostliteral: '[' expected at start: a.-.b
./valid_hostname: testing: "a.b.-"
./valid_hostname: warning: valid_hostname: misplaced hyphen: a.b.-
./valid_hostname: warning: valid_hostaddr: invalid character 97(decimal): a.b.-
./valid_hostname: warning: valid_hostliteral: '[' expected at start: a.b.-
./valid_hostname: testing: "-aa.b.b"
./valid_hostname: warning: valid_hostname: misplaced hyphen: -aa.b.b
./valid_hostname: warning: valid_hostaddr: invalid character 45(decimal): -aa.b.b
./valid_hostname: warning: valid_hostliteral: '[' expected at start: -aa.b.b
./valid_hostname: testing: "aa-.b.b"
./valid_hostname: warning: valid_hostname: misplaced hyphen: aa-.b.b
./valid_hostname: warning: valid_hostaddr: invalid character 97(decimal): aa-.b.b
./valid_hostname: warning: valid_hostliteral: '[' expected at start: aa-.b.b
./valid_hostname: testing: "a.-bb.b"
./valid_hostname: warning: valid_hostname: misplaced hyphen: a.-bb.b
./valid_hostname: warning: valid_hostaddr: invalid character 97(decimal): a.-bb.b
./valid_hostname: warning: valid_hostliteral: '[' expected at start: a.-bb.b
./valid_hostname: testing: "a.bb-.b"
./valid_hostname: warning: valid_hostname: misplaced hyphen: a.bb-.b
./valid_hostname: warning: valid_hostaddr: invalid character 97(decimal): a.bb-.b
./valid_hostname: warning: valid_hostliteral: '[' expected at start: a.bb-.b
./valid_hostname: testing: "a.b.-bb"
./valid_hostname: warning: valid_hostname: misplaced hyphen: a.b.-bb
./valid_hostname: warning: valid_hostaddr: invalid character 97(decimal): a.b.-bb
./valid_hostname: warning: valid_hostliteral: '[' expected at start: a.b.-bb
./valid_hostname: testing: "a.b.bb-"
./valid_hostname: warning: valid_hostname: misplaced hyphen: a.b.bb-
./valid_hostname: warning: valid_hostaddr: invalid character 97(decimal): a.b.bb-
./valid_hostname: warning: valid_hostliteral: '[' expected at start: a.b.bb-
./valid_hostname: testing: "a-a.b-b"
./valid_hostname: warning: valid_hostaddr: invalid character 97(decimal): a-a.b-b
./valid_hostname: warning: valid_hostliteral: '[' expected at start: a-a.b-b
./valid_hostname: testing: "[1.2.3.4]"
./valid_hostname: warning: valid_hostname: invalid character 91(decimal): [1.2.3.4]
./valid_hostname: warning: valid_hostaddr: invalid character 91(decimal): [1.2.3.4]
./valid_hostname: testing: "[321.255.255.255]"
./valid_hostname: warning: valid_hostname: invalid character 91(decimal): [321.255.255.255]
./valid_hostname: warning: valid_hostaddr: invalid character 91(decimal): [321.255.255.255]
./valid_hostname: warning: valid_hostaddr: invalid octet value: 321.255.255.255
./valid_hostname: testing: "[1.2.3.4"
./valid_hostname: warning: valid_hostname: invalid character 91(decimal): [1.2.3.4
./valid_hostname: warning: valid_hostaddr: invalid character 91(decimal): [1.2.3.4
./valid_hostname: warning: valid_hostliteral: ']' expected at end: [1.2.3.4
./valid_hostname: testing: "[1.2.3.4]foo"
./valid_hostname: warning: valid_hostname: invalid character 91(decimal): [1.2.3.4]foo
./valid_hostname: warning: valid_hostaddr: invalid character 91(decimal): [1.2.3.4]foo
./valid_hostname: warning: valid_hostliteral: unexpected text after ']': [1.2.3.4]foo
./valid_hostname: testing: "[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]"
./valid_hostname: warning: valid_hostname: invalid character 91(decimal): [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
./valid_hostname: warning: valid_hostaddr: invalid character 91(decimal): [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
./valid_hostname: warning: valid_hostliteral: too much text: [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx