-TSMTP_STATE
-TSOCKADDR_SIZE
-TSPAWN_ATTR
+-TSTRING_LIST
-TSTRING_TABLE
-TSYS_EXITS_TABLE
-TTOK822
missing reject_rbl_mumble domain names. Patrik Rak. File:
smtpd/smtpd_check.c.
+20021203
+
+ Bugfix: the FILTER access table action included the FILTER
+ command in the filter request, where only the transport+destination
+ were expected. Noel Jones. File smtpd/smtpd_check.c.
+
+ Cleanup: virtual_maps is now called virtual_alias_maps, in
+ order to better distinguish it from virtual_mailbox_maps.
+ The default value is $virtual_maps for backwards compatibility.
+
+ New parameters virtual_alias_domains and virtual_mailbox_domains
+ for the "domain.tld whatever" lookups. These use the same
+ syntax as the mydestination parameter. Default settings
+ are backwards compatible with Postfix 1.1.
+
+ Cleanup: just like $mydestination+$inet_interfaces control
+ what routes to $local_transport, $virtual_mailbox_domains
+ now controls what routes to $virtual_transport (default
+ transport: virtual), and $relay_domains now controls what
+ routes to $relay_transport (default transport: relay, a
+ clone of the smtp transport). Everything else routes to
+ $default_transport as before. This eliminates the need
+ for transport maps for virtual(8) domains, and avoids
+ performance problems with inbound relay mail. This was
+ improvement was suggested by Victor Duchovni. File:
+ trivial-rewrite/resolve.c.
+
+20021206
+
+ Cleanup: do allow regexps in aliases, virtual mailbox maps
+ but do not allow regular expression substitutions. Files:
+ util/dict.h, util/dict_regexp.c, util/dict_pcre.c.
+
+20021207
+
+ Performance: apparently, RFC 2821 blesses the use of CNAME
+ domain names in SMTP commands. This speeds things up a bit.
+ File: smtp/smtp_proto.c.
+
+ Workaround: exclude error mailer destinations from transport
+ table lookups. File: trivial-rewrite/resolve.c.
+
+ Cleanup: relocated_maps lookups moved to the trivial-rewrite
+ server. The queue manager no longer does any map lookups,
+ so it won't restart when maps change. This required that
+ resolver clients be prepared for the case that the resolver
+ reports it is unable to access a lookup table. This also
+ required that trivial-rewrite be running as multiple
+ processes to reduce the impact of table lookup latencies.
+ Files: *qmgr/qmgr_message.c, trivial-rewrite/resolve.c,
+ local/resolve.c, smtpd/smtpd_check.c, master/multi-server.c.
+
+ Workaround: don't discard all DNS lookup results when one
+ has a malformed name or address. File: dns/dns_lookups.c.
+
Open problems:
Low: revise other local delivery agent duplicate filters.
Low: postconf -e edits parameters that postconf won't list.
- Low: with quoted-printable, perhaps use =46rom instead of >From.
+ Low: with quoted-printable, perhaps use =46rom instead of
+ >From.
Low: make it easier to have local_recipient_maps turned on
by default. This requires documentation of its existence
--- /dev/null
+The following information was kindly provided by Russell Mosemann,
+with tips by Victor Duchovni for supporting user+foo@domain addresses.
+
+In order to use the maildrop transport for some domain, add an entry
+to transport_maps for each domain similar to the following.
+
+/etc/postfix/transport:
+ some.domain maildrop:
+ someother.domain maildrop:
+
+Define the following variable in main.cf so that pipe will provide one
+recipient at a time to maildrop.
+
+/etc/postfix/main.cf:
+ maildrop_destination_recipient_limit = 1
+
+The vmail userid as used below is the user that maildrop should
+run as. This would be the owner of the virtual mailboxes if they
+all have the same owner. If maildrop is suid (see maildrop
+documentation), then maildrop will change to the appropriate owner
+to deliver the mail. Do not use the postfix user as the maildrop
+user.
+
+/etc/postfix/master.cf:
+ maildrop unix - n n - - pipe
+ flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient}
+
+If you want to support user+extension@domain style addresses, use
+the following instead:
+
+/etc/postfix/master.cf:
+ maildrop unix - n n - - pipe
+ flags=DRhu user=vmail argv=/usr/local/bin/maildrop
+ -d ${user}@${nexthop} ${extension} ${recipient} ${user} ${nexthop}
+
+The mail is delivered to ${user}@${nexthop} (match key for maildrop
+userdb lookup). The ${extension} and the other address components
+are available to maildrop rules as $1, $2, $3, ... and can be
+omitted from master.cf or ignored by maildrop when not needed.
litter the filesystem with mailboxes (or worse). While it could
be set to "/", this isn't recommended.
+virtual_mailbox_domains
+
+ Specifies the list of domains that should be delivered to the
+ $virtual_transport delivery agent (default: virtual).
+
virtual_mailbox_maps
Recipients are looked up in this map to determine the path to
types.
/etc/postfix/main.cf:
- local_transport = virtual
+ virtual_transport = virtual
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_minimum_uid = 100
virtual_uid_maps = hash:/etc/postfix/vuid
virtual_gid_maps = hash:/etc/postfix/vgid
- # All domains that are listed in $mydestination are delivered
- # with $local_transport, which is the virtual delivery agent.
+ # Don't send mail to the local delivery agent.
+ mydestination =
- mydestination =
+ # All domains that are listed in $virtual_mailbox_domains
+ # are delivered via $virtual_transport, which is the virtual
+ # delivery agent by default.
+ virtual_mailbox_domains =
$myhostname localhost.$mydomain virtual1.domain virtual2.domain
Define a virtual delivery agent if the entry doesn't already exist:
types.
/etc/postfix/main.cf:
+ virtual_transport = virtual
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
+ virtual_mailbox_domains = $virtual_mailbox_maps
virtual_minimum_uid = 100
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
- transport_maps = hash:/etc/postfix/transport
# All domains that are delivered by the local delivery agent.
/etc/postfix/master.cf:
virtual unix - n n - - virtual
-Route virtual domains to the virtual delivery agent:
-
- /etc/postfix/transport:
- virtual1.domain virtual
- virtual2.domain virtual
-
Example recipients, one UNIX-style mailbox, one qmail-style maildir:
/etc/postfix/vmailbox:
+ test1@virtual1.domain test1
+ test2@virtual2.domain test2/
+
+ /etc/postfix/vmaildomains:
virtual1.domain required to prevent relay access denied errors
virtual2.domain required to prevent relay access denied errors
+
+Execute something like the following commands for each mailbox recipient:
+
+ # touch /var/mail/vhosts/test1
+ # chown 5000:5000 /var/mail/vhosts/test1
+
+Execute something like the following commands for each maildir recipient:
+
+ # mkdir /var/mail/vhosts/test2
+ # chown 5000:5000 /var/mail/vhosts/test2
+
+Remember that each domain is required to have a postmaster contact
+address.
+
+Example 3: hosting many virtual users
+=====================================
+
+Example 2 is fine if you host only a few virtual users. With many
+users you will want to separate the information that changes often
+(the user addresses) from the information that changes rarely (the
+names of hosted domains).
+
+This example is the same as above, but it uses a separate table for
+specifying the virtual domain names.
+
+ /etc/postfix/main.cf:
+ virtual_transport = virtual
+ virtual_mailbox_base = /var/mail/vhosts
+ virtual_mailbox_maps = hash:/etc/postfix/vmailbox
+ virtual_mailbox_domains = hash:/etc/postfix/vmaildomains
+ virtual_minimum_uid = 100
+ virtual_uid_maps = static:5000
+ virtual_gid_maps = static:5000
+
+ # All domains that are delivered by the local delivery agent.
+
+ mydestination = $myhostname $localhost.$mydomain
+
+ # Reject unknown local recipients at the SMTP port.
+
+ local_recipient_maps = unix:passwd.byname $alias_maps
+
+Define a virtual delivery agent if the entry doesn't already exist:
+
+ /etc/postfix/master.cf:
+ virtual unix - n n - - virtual
+
+Example recipients, one UNIX-style mailbox, one qmail-style maildir:
+
+ /etc/postfix/vmailbox:
test1@virtual1.domain test1
test2@virtual2.domain test2/
+ /etc/postfix/vmaildomains:
+ virtual1.domain required to prevent relay access denied errors
+ virtual2.domain required to prevent relay access denied errors
+
Execute something like the following commands for each mailbox recipient:
# touch /var/mail/vhosts/test1
Remember that each domain is required to have a postmaster contact
address.
-Example 3: forwarding mail for an old account to a new address
+Example 4: forwarding mail for an old account to a new address
==============================================================
In order to forward mail for a user who no longer exists, one would
/etc/postfix/virtual:
old_user@old.domain new_user@new.domain
-Example 4: setting up a virtual vacation autoresponder
+Example 5: setting up a virtual vacation autoresponder
======================================================
In order to set up an autoreply for virtual recipients while still
# Specify a list of host or domain names, /file/name or type:table
# patterns, separated by commas and/or whitespace. A /file/name
# pattern is replaced by its contents; a type:table is matched when
-# a name matches a lookup key. Continue long lines by starting the
-# next line with whitespace.
+# a name matches a lookup key (the right-hand side is ignored).
+# Continue long lines by starting the next line with whitespace.
#
#mydestination = $myhostname, localhost.$mydomain
#mydestination = $myhostname, localhost.$mydomain $mydomain
# that Postfix is final destination for:
# - destinations that match $inet_interfaces,
# - destinations that match $mydestination
-# - destinations that match $virtual_maps,
-# - destinations that match $virtual_mailbox_maps.
+# - destinations that match $virtual_alias_domains,
+# - destinations that match $virtual_mailbox_domains.
# These destinations do not need to be listed in $relay_domains.
#
# Specify a list of hosts or domains, /file/name patterns or type:name
defer unix - - n - 0 bounce
flush unix n - n 1000? 0 flush
smtp unix - - n - - smtp
+relay unix - - n - - smtp
+# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq unix n - n - - showq
error unix - - n - - error
local unix - n n - - local
#
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.
+#
+# maildrop. See the Postfix MAILDROP_README file for details.
+#
+maildrop unix - n n - - pipe
+ flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient}
+#
# The Cyrus deliver program has changed incompatibly, multiple times.
#
old-cyrus unix - n n - - pipe
test -n "$upgrade_conf" && {
+ # Add missing relay service to master.cf.
+
+ grep '^relay' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for relay service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+relay unix - - n - - smtp
+EOF
+ }
+
# Add missing flush service to master.cf.
- grep 'flush.*flush' $config_directory/master.cf >/dev/null || {
+ grep '^flush.*flush' $config_directory/master.cf >/dev/null || {
echo Editing $config_directory/master.cf, adding missing entry for flush service
cat >>$config_directory/master.cf <<EOF || exit 1
flush unix - - n 1000? 0 flush
# that Postfix is final destination for:
# - destinations that match $inet_interfaces,
# - destinations that match $mydestination
-# - destinations that match $virtual_maps,
-# - destinations that match $virtual_mailbox_maps.
+# - destinations that match $virtual_alias_domains,
+# - destinations that match $virtual_mailbox_domains.
# These destinations do not need to be listed in $relay_domains.
#
# The following restrictions are available (* is part of default setting):
# listed in an A record under domain.tld.
# permit_auth_destination: permit mail
# - to destinations matching $inet_interfaces, $mydestination,
-# or $virtual_maps.
+# $virtual_alias_domains, or $virtual_mailbox_domains.
# - to destinations matching $relay_domains or subdomain thereof,
# except for addresses with sender-specified routing.
# reject_unauth_destination: reject mail unless it is sent
# - to destinations matching $inet_interfaces, $mydestination,
-# $virtual_maps, or $virtual_mailbox_maps.
+# $virtual_alias_domains, or $virtual_mailbox_domains.
# - to destinations matching $relay_domains or subdomain thereof,
# except for addresses with sender-specified routing.
# reject_unauth_pipelining: reject mail from improperly pipelining spamware
# that Postfix is final destination for:
# - destinations that match $inet_interfaces,
# - destinations that match $mydestination
-# - destinations that match $virtual_maps,
-# - destinations that match $virtual_mailbox_maps.
+# - destinations that match $virtual_alias_domains,
+# - destinations that match $virtual_mailbox_domains.
# These destinations do not need to be listed in $relay_domains.
#
# Specify a list of hosts or domains, /file/name patterns or type:name
# HERE JUST SERVES AS AN EXAMPLE.
#
# This file contains example settings of Postfix configuration
-# parameters that control virtual database lookups.
+# parameters that control virtual alias database lookups.
-# The virtual_maps parameter specifies optional lookup tables to
+# This file describes settings for simulated virtual domains. These
+# are domains for which all mail is aliased to one or more local or
+# remote addresses. For details, see the virtual(5) manual page.
+#
+# If you need virtual domains where each virtual address can have
+# its own mailbox, then you should use the virtual(8) delivery agent
+# instead. For details, see the VIRTUAL_README file.
+
+# The virtual_alias_maps parameter specifies optional lookup tables to
# redirect specific addresses or even complete domains to another
-# address. This is typically used to implement virtual domain support.
+# address. This is typically used to simulate virtual domain support.
#
# By default, no address redirection is done.
#
# It may take a minute or so before the change becomes visible.
# Use "postfix reload" to eliminate the delay.
#
-#virtual_maps = dbm:/etc/postfix/virtual
-#virtual_maps = hash:/etc/postfix/virtual
-#virtual_maps = hash:/etc/postfix/virtual, nis:virtual
-#virtual_maps = hash:/etc/postfix/virtual, netinfo:/virtual
-virtual_maps =
+#virtual_alias_maps = dbm:/etc/postfix/virtual
+#virtual_alias_maps = hash:/etc/postfix/virtual
+#virtual_alias_maps = hash:/etc/postfix/virtual, nis:virtual
+#virtual_alias_maps = hash:/etc/postfix/virtual, netinfo:/virtual
+virtual_alias_maps =
+
+# The virtual_alias_domains parameter specifies the names of simulated
+# virtual domains, that is, domains for which all mail is aliased to
+# one or more local or remote addresses.
+#
+# By default, this is set to $virtual_alias_maps so that you can keep
+# all information about simulated virtual domains in one place. If
+# you have many users, it is better to separate information that
+# changes more frequently (virtual address -> local or remote address
+# mapping) from information that changes less frequently (the list
+# of virtual domain names).
+#
+# Specify a list of host or domain names, /file/name or type:table
+# patterns, separated by commas and/or whitespace. A /file/name
+# pattern is replaced by its contents; a type:table is matched when
+# a name matches a lookup key (the right-hand side is ignored).
+# Continue long lines by starting the next line with whitespace.
+#
+#virtual_alias_domains = virtual1.tld virtual2.tld
+virtual_alias_domains = $virtual_alias_maps
# VIRTUAL(5) VIRTUAL(5)
#
# NAME
-# virtual - format of Postfix virtual table
+# virtual - format of Postfix virtual alias table
#
# SYNOPSIS
# postmap /etc/postfix/virtual
# postmap -q - /etc/postfix/virtual <inputfile
#
# DESCRIPTION
-# The optional virtual table specifies address redirections
-# for local and non-local recipients or domains. The redi-
-# rections are used by the cleanup(8) daemon. The redirec-
-# tions are recursive.
-#
-# The virtual redirection is applied only to recipient enve-
-# lope addresses, and does not affect message headers.
-# Think Sendmail rule set S0, if you like. Use canonical(5)
-# mapping to rewrite header and envelope addresses in gen-
-# eral.
-#
-# Normally, the virtual table is specified as a text file
-# that serves as input to the postmap(1) command. The
+# The optional virtual alias table specifies address alias-
+# ing for local and non-local recipients. Virtual aliasing
+# is used by the cleanup(8) daemon. Virtual aliasing is
+# recursive.
+#
+# Virtual aliasing is applied only to recipient envelope
+# addresses, and does not affect message headers. Think
+# Sendmail rule set S0, if you like. Use canonical(5) map-
+# ping to rewrite header and envelope addresses in general.
+#
+# Normally, the virtual alias table is specified as a text
+# file that serves as input to the postmap(1) command. The
# result, an indexed file in dbm or db format, is used for
# fast searching by the mail system. Execute the command
# postmap /etc/postfix/virtual in order to rebuild the
# sions. In that case, the lookups are done in a slightly
# different way as described below.
#
-# POSTFIX-STYLE VIRTUAL DOMAINS
-# With a Postfix-style virtual domain, the virtual domain
-# has its own user name space. Local (i.e. non-virtual)
-# usernames are not visible in a Postfix-style virtual
-# domain. In particular, local aliases(5) and mailing lists
-# are not visible as localname@virtual.domain.
+# SIMULATED VIRTUAL DOMAINS
+# Besides virtual aliases, the virtual alias table can also
+# be used to simulate virtual domains. With a simulated vir-
+# tual domain, all recipient addresses are aliased to non-
+# virtual addresses. These non-virtual addresses may be
+# either local or remote.
#
-# Use a Sendmail-style virtual domain (see below) if local
-# usernames, aliases(5) or mailing lists should be visible
-# as localname@virtual.domain.
+# Simulated virtual domains are not to be confused with the
+# true virtual domains that are implemented with the Postfix
+# virtual(8) mail delivery agent. With true virtual domains,
+# each recipient address can have its own mailbox.
#
-# Support for a Postfix-style virtual domain looks like:
+# With a simulated virtual domain, the virtual domain has
+# its own user name space. Local (i.e. non-virtual) user-
+# names are not visible in a simulated virtual domain. In
+# particular, local aliases(5) and mailing lists are not
+# visible as localname@virtual.domain.
#
-# /etc/postfix/virtual:
-# virtual.domain anything (right-hand content does not matter)
-# postmaster@virtual.domain postmaster
-# user1@virtual.domain address1
-# user2@virtual.domain address2, address3
-#
-# The virtual.domain anything entry is required for a Post-
-# fix-style virtual domain.
-#
-# Do not list a Postfix-style virtual domain in the main.cf
-# mydestination configuration parameter. Such an entry is
-# required only for a Sendmail-style virtual domain.
-#
-# With a Postfix-style virtual domain, the Postfix SMTP
-# server accepts mail for known-user@virtual.domain and
-# rejects mail for unknown-user@virtual.domain as undeliver-
-# able.
-#
-# SENDMAIL-STYLE VIRTUAL DOMAINS
-# With a Sendmail-style virtual domain, every local (i.e.
-# non-virtual) username is visible in the virtual domain. In
-# particular, every local alias and mailing list is visible
-# as localname@virtual.domain.
-#
-# Use a Postfix-style virtual domain (see above) if local
-# usernames, aliases(5) or mailing lists should not be visi-
-# ble as localname@virtual.domain.
-#
-# Support for a Sendmail-style virtual domain looks like:
+# Support for a simulated virtual domain looks like:
#
# /etc/postfix/main.cf:
-# mydestination = $myhostname localhost.$mydomain $mydomain
-# virtual.domain
+# virtual_alias_maps = hash:/etc/postfix/virtual
+#
+# Note: some systems use dbm databases instead of hash.
+# See the output from postconf -m for available database
+# types.
#
# /etc/postfix/virtual:
+# virtual.domain anything (right-hand content does not matter)
+# postmaster@virtual.domain postmaster
# user1@virtual.domain address1
# user2@virtual.domain address2, address3
#
-# The main.cf mydestination entry is required for a Send-
-# mail-style virtual domain.
+# The virtual.domain anything entry is required for a simu-
+# lated virtual domain. Without this entry, mail will be
+# rejected with a "relay access denied" error condition.
#
-# Do not specify a virtual.domain anything virtual map entry
-# for a Sendmail-style virtual domain. Such an entry is
-# required only with a Postfix-style virtual domain.
+# Do not list a simulated virtual domain name in the main.cf
+# mydestination configuration parameter.
#
-# With a Sendmail-style virtual domain, the Postfix local
-# delivery agent delivers mail for an unknown user@vir-
-# tual.domain to a local (i.e. non-virtual) user that has
-# the same name; if no such recipient exists, the Postfix
-# local delivery agent bounces the mail to the sender.
+# With a simulated virtual domain, the Postfix SMTP server
+# accepts mail for known-user@virtual.domain, and rejects
+# mail for unknown-user@virtual.domain as undeliverable.
+#
+# Instead of specifying the simulated virtual domain name
+# via the virtual_alias_maps table, you may also specify it
+# via the main.cf virtual_alias_domains configuration param-
+# eter. This latter parameter uses the same syntax as the
+# main.cf mydestination configuration parameter.
#
# TABLE FORMAT
# The format of the virtual table is as follows, mappings
# details and for default values. Use the postfix reload
# command after a configuration change.
#
-# virtual_maps
-# List of virtual mapping tables.
+# virtual_alias_maps
+# List of virtual aliasing tables.
+#
+# virtual_alias_domains
+# List of simulated virtual domains. This uses the
+# same syntax as the mydestination parameter.
#
# Other parameters of interest:
#
# inet_interfaces
-# The network interface addresses that this system
+# The network interface addresses that this system
# receives mail on. You need to stop and start Post-
# fix when this parameter changes.
#
# mydestination
-# List of domains that this mail system considers
+# List of domains that this mail system considers
# local.
#
# myorigin
# 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)
List of user names that are not subject to address
masquerading.
- <b>virtual</b><i>_</i><b>maps</b>
+ <b>virtual</b><i>_</i><b>alias</b><i>_</i><b>maps</b>
Address mapping lookup table for envelope recipient
addresses.
<pre>
/etc/postfix/main.cf:
- virtual_maps = hash:/etc/postfix/virtual
+ virtual_alias_maps = hash:/etc/postfix/virtual
/etc/postfix/virtual:
root root@localhost
<pre>
/etc/postfix/main.cf:
recipient_delimiter = +
- virtual_maps =
+ virtual_alias_maps =
...non-regexp virtual maps...
regexp:/etc/postfix/virtual_regexp
<blockquote>
<pre>
/etc/postfix/main.cf:
- virtual_maps = regexp:/etc/postfix/virtual_regexp
+ virtual_alias_maps = regexp:/etc/postfix/virtual_regexp
recipient_delimiter = +
/etc/postfix/virtual_regexp:
silently discarded. This stops potential loops caused by
undeliverable bounce notifications.
- Mail addressed to a user listed in the optional <b>relocated</b>
- database is bounced with a "user has moved to <i>new_loca-</i>
- <i>tion</i>" message. See <a href="relocated.5.html"><b>relocated</b>(5)</a> for a precise description.
-
<b>MAIL</b> <b>QUEUES</b>
The <b>nqmgr</b> daemon maintains the following queues:
Inbound mail from the network, or mail picked up by
the local <b>pickup</b> agent from the <b>maildrop</b> directory.
- <b>active</b> Messages that the queue manager has opened for
- delivery. Only a limited number of messages is
- allowed to enter the <b>active</b> queue (leaky bucket
+ <b>active</b> Messages that the queue manager has opened for
+ delivery. Only a limited number of messages is
+ allowed to enter the <b>active</b> queue (leaky bucket
strategy, for a fixed delivery rate).
<b>deferred</b>
- Mail that could not be delivered upon the first
- attempt. The queue manager implements exponential
+ Mail that could not be delivered upon the first
+ attempt. The queue manager implements exponential
backoff by doubling the time between delivery
attempts.
<b>corrupt</b>
- Unreadable or damaged queue files are moved here
+ Unreadable or damaged queue files are moved here
for inspection.
- <b>hold</b> Messages that are kept "on hold" are kept here
+ <b>hold</b> Messages that are kept "on hold" are kept here
until someone sets them free.
<b>DELIVERY</b> <b>STATUS</b> <b>REPORTS</b>
The <b>nqmgr</b> daemon keeps an eye on per-message delivery sta-
- tus reports in the following directories. Each status
+ tus reports in the following directories. Each status
report file has the same name as the corresponding message
file:
- <b>bounce</b> Per-recipient status information about why mail is
- bounced. These files are maintained by the
+ <b>bounce</b> Per-recipient status information about why mail is
+ bounced. These files are maintained by the
<a href="bounce.8.html"><b>bounce</b>(8)</a> daemon.
- <b>defer</b> Per-recipient status information about why mail is
- delayed. These files are maintained by the
+ <b>defer</b> Per-recipient status information about why mail is
+ delayed. These files are maintained by the
<a href="defer.8.html"><b>defer</b>(8)</a> daemon.
- The <b>nqmgr</b> daemon is responsible for asking the <a href="bounce.8.html"><b>bounce</b>(8)</a>
+ The <b>nqmgr</b> daemon is responsible for asking the <a href="bounce.8.html"><b>bounce</b>(8)</a>
or <a href="defer.8.html"><b>defer</b>(8)</a> daemons to send non-delivery reports.
<b>STRATEGIES</b>
- The queue manager implements a variety of strategies for
+ The queue manager implements a variety of strategies for
either opening queue files (input) or for message delivery
(output).
<b>leaky</b> <b>bucket</b>
- This strategy limits the number of messages in the
- <b>active</b> queue and prevents the queue manager from
+ This strategy limits the number of messages in the
+ <b>active</b> queue and prevents the queue manager from
running out of memory under heavy load.
<b>fairness</b>
- When the <b>active</b> queue has room, the queue manager
- takes one message from the <b>incoming</b> queue and one
+ When the <b>active</b> queue has room, the queue manager
+ takes one message from the <b>incoming</b> queue and one
from the <b>deferred</b> queue. This prevents a large mail
backlog from blocking the delivery of new mail.
<b>round</b> <b>robin</b>
The queue manager sorts delivery requests by desti-
- nation. Round-robin selection prevents one desti-
+ nation. Round-robin selection prevents one desti-
nation from dominating deliveries to other destina-
tions.
<b>exponential</b> <b>backoff</b>
Mail that cannot be delivered upon the first
- attempt is deferred. The time interval between
+ attempt is deferred. The time interval between
delivery attempts is doubled after each attempt.
<b>destination</b> <b>status</b> <b>cache</b>
- The queue manager avoids unnecessary delivery
- attempts by maintaining a short-term, in-memory
+ The queue manager avoids unnecessary delivery
+ attempts by maintaining a short-term, in-memory
list of unreachable destinations.
<b>preemptive</b> <b>message</b> <b>scheduling</b>
- The queue manager attempts to minimize the average
+ The queue manager attempts to minimize the average
per-recipient delay while still preserving the cor-
rect per-message delays, using a sophisticated pre-
emptive message scheduling.
<b>TRIGGERS</b>
On an idle system, the queue manager waits for the arrival
- of trigger events, or it waits for a timer to go off. A
- trigger is a one-byte message. Depending on the message
- received, the queue manager performs one of the following
- actions (the message is followed by the symbolic constant
+ of trigger events, or it waits for a timer to go off. A
+ trigger is a one-byte message. Depending on the message
+ received, the queue manager performs one of the following
+ actions (the message is followed by the symbolic constant
used internally by the software):
<b>D</b> <b>(QMGR</b><i>_</i><b>REQ</b><i>_</i><b>SCAN</b><i>_</i><b>DEFERRED)</b>
- Start a deferred queue scan. If a deferred queue
- scan is already in progress, that scan will be
+ Start a deferred queue scan. If a deferred queue
+ scan is already in progress, that scan will be
restarted as soon as it finishes.
<b>I</b> <b>(QMGR</b><i>_</i><b>REQ</b><i>_</i><b>SCAN</b><i>_</i><b>INCOMING)</b>
- Start an incoming queue scan. If an incoming queue
- scan is already in progress, that scan will be
+ Start an incoming queue scan. If an incoming queue
+ scan is already in progress, that scan will be
restarted as soon as it finishes.
<b>A</b> <b>(QMGR</b><i>_</i><b>REQ</b><i>_</i><b>SCAN</b><i>_</i><b>ALL)</b>
affects the next deferred queue scan.
<b>F</b> <b>(QMGR</b><i>_</i><b>REQ</b><i>_</i><b>FLUSH</b><i>_</i><b>DEAD)</b>
- Purge all information about dead transports and
+ Purge all information about dead transports and
destinations.
<b>W</b> <b>(TRIGGER</b><i>_</i><b>REQ</b><i>_</i><b>WAKEUP)</b>
- Wakeup call, This is used by the master server to
- instantiate servers that should not go away for-
- ever. The action is to start an incoming queue
+ Wakeup call, This is used by the master server to
+ instantiate servers that should not go away for-
+ ever. The action is to start an incoming queue
scan.
The <b>nqmgr</b> daemon reads an entire buffer worth of triggers.
- Multiple identical trigger requests are collapsed into
- one, and trigger requests are sorted so that <b>A</b> and <b>F</b> pre-
- cede <b>D</b> and <b>I</b>. Thus, in order to force a deferred queue
+ Multiple identical trigger requests are collapsed into
+ one, and trigger requests are sorted so that <b>A</b> and <b>F</b> pre-
+ cede <b>D</b> and <b>I</b>. Thus, in order to force a deferred queue
run, one would request <b>A</b> <b>F</b> <b>D</b>; in order to notify the queue
manager of the arrival of new mail one would request <b>I</b>.
<b>STANDARDS</b>
- None. The <b>nqmgr</b> daemon does not interact with the outside
+ None. The <b>nqmgr</b> daemon does not interact with the outside
world.
<b>SECURITY</b>
- The <b>nqmgr</b> daemon is not security sensitive. It reads sin-
- gle-character messages from untrusted local users, and
- thus may be susceptible to denial of service attacks. The
- <b>nqmgr</b> daemon does not talk to the outside world, and it
- can be run at fixed low privilege in a chrooted environ-
+ The <b>nqmgr</b> daemon is not security sensitive. It reads sin-
+ gle-character messages from untrusted local users, and
+ thus may be susceptible to denial of service attacks. The
+ <b>nqmgr</b> daemon does not talk to the outside world, and it
+ can be run at fixed low privilege in a chrooted environ-
ment.
<b>DIAGNOSTICS</b>
Corrupted message files are saved to the <b>corrupt</b> queue for
further inspection.
- Depending on the setting of the <b>notify</b><i>_</i><b>classes</b> parameter,
- the postmaster is notified of bounces and of other trou-
+ Depending on the setting of the <b>notify</b><i>_</i><b>classes</b> parameter,
+ the postmaster is notified of bounces and of other trou-
ble.
<b>BUGS</b>
- A single queue manager process has to compete for disk
- access with multiple front-end processes such as <b>smtpd</b>. A
- sudden burst of inbound mail can negatively impact out-
+ A single queue manager process has to compete for disk
+ access with multiple front-end processes such as <b>smtpd</b>. A
+ sudden burst of inbound mail can negatively impact out-
bound delivery rates.
<b>CONFIGURATION</b> <b>PARAMETERS</b>
- The following <b>main.cf</b> parameters are especially relevant
- to this program. 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 program. 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>Miscellaneous</b>
<b>allow</b><i>_</i><b>min</b><i>_</i><b>user</b>
- Do not bounce recipient addresses that begin with
+ Do not bounce recipient addresses that begin with
'-'.
- <b>relocated</b><i>_</i><b>maps</b>
- Tables with contact information for users, hosts or
- domains that no longer exist. See <a href="relocated.5.html"><b>relocated</b>(5)</a>.
-
<b>queue</b><i>_</i><b>directory</b>
Top-level directory of the Postfix queue.
<b>SEE</b> <b>ALSO</b>
<a href="master.8.html">master(8)</a>, process manager
- <a href="relocated.5.html">relocated(5)</a>, format of the "user has moved" table
syslogd(8) system logging
<a href="trivial-rewrite.8.html">trivial-rewrite(8)</a>, address routing
silently discarded. This stops potential loops caused by
undeliverable bounce notifications.
- Mail addressed to a user listed in the optional <b>relocated</b>
- database is bounced with a "user has moved to <i>new_loca-</i>
- <i>tion</i>" message. See <a href="relocated.5.html"><b>relocated</b>(5)</a> for a precise description.
-
<b>MAIL</b> <b>QUEUES</b>
The <b>qmgr</b> daemon maintains the following queues:
Inbound mail from the network, or mail picked up by
the local <b>pickup</b> agent from the <b>maildrop</b> directory.
- <b>active</b> Messages that the queue manager has opened for
- delivery. Only a limited number of messages is
- allowed to enter the <b>active</b> queue (leaky bucket
+ <b>active</b> Messages that the queue manager has opened for
+ delivery. Only a limited number of messages is
+ allowed to enter the <b>active</b> queue (leaky bucket
strategy, for a fixed delivery rate).
<b>deferred</b>
- Mail that could not be delivered upon the first
- attempt. The queue manager implements exponential
+ Mail that could not be delivered upon the first
+ attempt. The queue manager implements exponential
backoff by doubling the time between delivery
attempts.
<b>corrupt</b>
- Unreadable or damaged queue files are moved here
+ Unreadable or damaged queue files are moved here
for inspection.
- <b>hold</b> Messages that are kept "on hold" are kept here
+ <b>hold</b> Messages that are kept "on hold" are kept here
until someone sets them free.
<b>DELIVERY</b> <b>STATUS</b> <b>REPORTS</b>
- The <b>qmgr</b> daemon keeps an eye on per-message delivery sta-
- tus reports in the following directories. Each status
+ The <b>qmgr</b> daemon keeps an eye on per-message delivery sta-
+ tus reports in the following directories. Each status
report file has the same name as the corresponding message
file:
- <b>bounce</b> Per-recipient status information about why mail is
- bounced. These files are maintained by the
+ <b>bounce</b> Per-recipient status information about why mail is
+ bounced. These files are maintained by the
<a href="bounce.8.html"><b>bounce</b>(8)</a> daemon.
- <b>defer</b> Per-recipient status information about why mail is
- delayed. These files are maintained by the
+ <b>defer</b> Per-recipient status information about why mail is
+ delayed. These files are maintained by the
<a href="defer.8.html"><b>defer</b>(8)</a> daemon.
The <b>qmgr</b> daemon is responsible for asking the <a href="bounce.8.html"><b>bounce</b>(8)</a> or
<a href="defer.8.html"><b>defer</b>(8)</a> daemons to send non-delivery reports.
<b>STRATEGIES</b>
- The queue manager implements a variety of strategies for
+ The queue manager implements a variety of strategies for
either opening queue files (input) or for message delivery
(output).
<b>leaky</b> <b>bucket</b>
- This strategy limits the number of messages in the
- <b>active</b> queue and prevents the queue manager from
+ This strategy limits the number of messages in the
+ <b>active</b> queue and prevents the queue manager from
running out of memory under heavy load.
<b>fairness</b>
- When the <b>active</b> queue has room, the queue manager
- takes one message from the <b>incoming</b> queue and one
+ When the <b>active</b> queue has room, the queue manager
+ takes one message from the <b>incoming</b> queue and one
from the <b>deferred</b> queue. This prevents a large mail
backlog from blocking the delivery of new mail.
<b>round</b> <b>robin</b>
The queue manager sorts delivery requests by desti-
- nation. Round-robin selection prevents one desti-
+ nation. Round-robin selection prevents one desti-
nation from dominating deliveries to other destina-
tions.
<b>exponential</b> <b>backoff</b>
Mail that cannot be delivered upon the first
- attempt is deferred. The time interval between
+ attempt is deferred. The time interval between
delivery attempts is doubled after each attempt.
<b>destination</b> <b>status</b> <b>cache</b>
- The queue manager avoids unnecessary delivery
- attempts by maintaining a short-term, in-memory
+ The queue manager avoids unnecessary delivery
+ attempts by maintaining a short-term, in-memory
list of unreachable destinations.
<b>TRIGGERS</b>
On an idle system, the queue manager waits for the arrival
- of trigger events, or it waits for a timer to go off. A
- trigger is a one-byte message. Depending on the message
- received, the queue manager performs one of the following
- actions (the message is followed by the symbolic constant
+ of trigger events, or it waits for a timer to go off. A
+ trigger is a one-byte message. Depending on the message
+ received, the queue manager performs one of the following
+ actions (the message is followed by the symbolic constant
used internally by the software):
<b>D</b> <b>(QMGR</b><i>_</i><b>REQ</b><i>_</i><b>SCAN</b><i>_</i><b>DEFERRED)</b>
- Start a deferred queue scan. If a deferred queue
- scan is already in progress, that scan will be
+ Start a deferred queue scan. If a deferred queue
+ scan is already in progress, that scan will be
restarted as soon as it finishes.
<b>I</b> <b>(QMGR</b><i>_</i><b>REQ</b><i>_</i><b>SCAN</b><i>_</i><b>INCOMING)</b>
- Start an incoming queue scan. If an incoming queue
- scan is already in progress, that scan will be
+ Start an incoming queue scan. If an incoming queue
+ scan is already in progress, that scan will be
restarted as soon as it finishes.
<b>A</b> <b>(QMGR</b><i>_</i><b>REQ</b><i>_</i><b>SCAN</b><i>_</i><b>ALL)</b>
affects the next deferred queue scan.
<b>F</b> <b>(QMGR</b><i>_</i><b>REQ</b><i>_</i><b>FLUSH</b><i>_</i><b>DEAD)</b>
- Purge all information about dead transports and
+ Purge all information about dead transports and
destinations.
<b>W</b> <b>(TRIGGER</b><i>_</i><b>REQ</b><i>_</i><b>WAKEUP)</b>
- Wakeup call, This is used by the master server to
- instantiate servers that should not go away for-
- ever. The action is to start an incoming queue
+ Wakeup call, This is used by the master server to
+ instantiate servers that should not go away for-
+ ever. The action is to start an incoming queue
scan.
- The <b>qmgr</b> daemon reads an entire buffer worth of triggers.
- Multiple identical trigger requests are collapsed into
- one, and trigger requests are sorted so that <b>A</b> and <b>F</b> pre-
- cede <b>D</b> and <b>I</b>. Thus, in order to force a deferred queue
+ The <b>qmgr</b> daemon reads an entire buffer worth of triggers.
+ Multiple identical trigger requests are collapsed into
+ one, and trigger requests are sorted so that <b>A</b> and <b>F</b> pre-
+ cede <b>D</b> and <b>I</b>. Thus, in order to force a deferred queue
run, one would request <b>A</b> <b>F</b> <b>D</b>; in order to notify the queue
manager of the arrival of new mail one would request <b>I</b>.
<b>STANDARDS</b>
- None. The <b>qmgr</b> daemon does not interact with the outside
+ None. The <b>qmgr</b> daemon does not interact with the outside
world.
<b>SECURITY</b>
- The <b>qmgr</b> daemon is not security sensitive. It reads sin-
- gle-character messages from untrusted local users, and
- thus may be susceptible to denial of service attacks. The
+ The <b>qmgr</b> daemon is not security sensitive. It reads sin-
+ gle-character messages from untrusted local users, and
+ thus may be susceptible to denial of service attacks. The
<b>qmgr</b> daemon does not talk to the outside world, and it can
be run at fixed low privilege in a chrooted environment.
Corrupted message files are saved to the <b>corrupt</b> queue for
further inspection.
- Depending on the setting of the <b>notify</b><i>_</i><b>classes</b> parameter,
- the postmaster is notified of bounces and of other trou-
+ Depending on the setting of the <b>notify</b><i>_</i><b>classes</b> parameter,
+ the postmaster is notified of bounces and of other trou-
ble.
<b>BUGS</b>
- A single queue manager process has to compete for disk
- access with multiple front-end processes such as <b>smtpd</b>. A
- sudden burst of inbound mail can negatively impact out-
+ A single queue manager process has to compete for disk
+ access with multiple front-end processes such as <b>smtpd</b>. A
+ sudden burst of inbound mail can negatively impact out-
bound delivery rates.
<b>CONFIGURATION</b> <b>PARAMETERS</b>
- The following <b>main.cf</b> parameters are especially relevant
- to this program. 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 program. 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>Miscellaneous</b>
<b>allow</b><i>_</i><b>min</b><i>_</i><b>user</b>
- Do not bounce recipient addresses that begin with
+ Do not bounce recipient addresses that begin with
'-'.
- <b>relocated</b><i>_</i><b>maps</b>
- Tables with contact information for users, hosts or
- domains that no longer exist. See <a href="relocated.5.html"><b>relocated</b>(5)</a>.
-
<b>queue</b><i>_</i><b>directory</b>
Top-level directory of the Postfix queue.
<b>SEE</b> <b>ALSO</b>
<a href="master.8.html">master(8)</a>, process manager
- <a href="relocated.5.html">relocated(5)</a>, format of the "user has moved" table
syslogd(8) system logging
<a href="trivial-rewrite.8.html">trivial-rewrite(8)</a>, address routing
<dl>
-<a name="#smtpd_error_sleep_time">
+<a name="smtpd_error_sleep_time">
<dt> <b>smtpd_error_sleep_time</b> (default: 1 second) <dd> When
the per-session error count is small, the SMTP server pauses only
<p>
-<a name="#smtpd_soft_error_limit">
+<a name="smtpd_soft_error_limit">
<dt> <b>smtpd_soft_error_limit</b> (default: 10) <dd> When the
per-session error count exceeds this value, the SMTP server sleeps
<p>
-<a name="#smtpd_hard_error_limit">
+<a name="smtpd_hard_error_limit">
<dt> <b>smtpd_hard_error_limit</b> (default: 20) <dd> When
the per-session error count exceeds this value, the SMTP server
If you do this, Postfix will no longer be able to send mail to
individual machines.
-<a name="virtual"> <h2> Virtual address mapping</h2>
+<a name="virtual"> <h2> Virtual address aliasing</h2>
After applying the canonical and masquerade mappings, the <a
href="cleanup.8.html">cleanup</a> daemon uses the <a
href="virtual.5.html">virtual</a> table to redirect mail for all
recipients, local or remote. The mapping affects only envelope
recipients; it has no effect on message headers or envelope senders.
-Virtual lookups are useful to redirect mail for virtual domains to
-real user mailboxes, and to redirect mail for domains that no longer
-exist. Virtual lookups can also be used to transform <i>
-Firstname.Lastname </i> back into UNIX login names, although it
-seems that local <a href="#aliases">aliases</a> are a more appropriate
-vehicle.
+Virtual alias lookups are useful to redirect mail for simulated
+virtual domains to real user mailboxes, and to redirect mail for
+domains that no longer exist. Virtual alias lookups can also be
+used to transform <i> Firstname.Lastname </i> back into UNIX login
+names, although it seems that local <a href="#aliases">aliases</a>
+are a more appropriate vehicle.
<p>
-Virtual mapping is disabled by default. To enable, edit the <b>
-virtual_maps</b> parameter in the <b>main.cf</b> file and
+Virtual aliasing is disabled by default. To enable, edit the <b>
+virtual_alias_maps</b> parameter in the <b>main.cf</b> file and
specify one or more lookup tables, separated by whitespace or
commas. For example:
<dl>
-<dd><b>virtual_maps = hash:/etc/postfix/virtual</b>
+<dd><b>virtual_alias_maps = hash:/etc/postfix/virtual</b>
</dl>
<p>
-Addresses found in virtual maps are subjected to another iteration
-of virtual mapping, but are not subjected to canonical mapping, in
-order to avoid loops.
+Addresses found in virtual alias maps are subjected to another
+iteration of virtual aliasing, but are not subjected to canonical
+mapping, in order to avoid loops.
<a name="relocated"> <h2> Relocated users table</h2>
<b>unknown</b><i>_</i><b>client</b><i>_</i><b>reject</b><i>_</i><b>code</b>
Response code when a client without address to name
- mapping violates the <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>clients</b>
- restriction.
+ mapping violates the <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>client</b> restric-
+ 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
remote.
<b>mydestination</b>
- List of domains that this machine considers local.
+ List of domains that are given to the <b>$local</b><i>_</i><b>trans-</b>
+ <b>port</b>.
- <b>myorigin</b>
- The domain that locally-posted mail appears to come
- from.
+ <b>virtual</b><i>_</i><b>alias</b><i>_</i><b>domains</b>
+ List of simulated virtual domains (domains with all
+ recipients aliased to some other local or remote
+ domain).
+
+ <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>domains</b>
+ List of domains that are given to the <b>$vir-</b>
+ <b>tual</b><i>_</i><b>transport</b>.
+
+ <b>relay</b><i>_</i><b>domains</b>
+ List of domains that are given to the <b>$relay</b><i>_</i><b>trans-</b>
+ <b>port</b>.
<b>resolve</b><i>_</i><b>unquoted</b><i>_</i><b>address</b>
When resolving an address, do not quote the address
- localpart as per <a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a>, so that additional <b>@</b>, <b>%</b>
- or <b>!</b> characters remain visible. This is techni-
+ localpart as per <a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a>, so that additional <b>@</b>, <b>%</b>
+ or <b>!</b> characters remain visible. This is techni-
cally incorrect, but allows us to stop relay
- attacks when forwarding mail to a Sendmail primary
+ attacks when forwarding mail to a Sendmail primary
MX host.
+ <b>relocated</b><i>_</i><b>maps</b>
+ Tables with contact information for users, hosts or
+ domains that no longer exist. See <a href="relocated.5.html"><b>relocated</b>(5)</a>.
+
<b>Rewriting</b>
+ <b>myorigin</b>
+ The domain that locally-posted mail appears to come
+ from.
+
<b>allow</b><i>_</i><b>percent</b><i>_</i><b>hack</b>
Rewrite <i>user</i>%<i>domain</i> to <i>user</i>@<i>domain</i>.
<b>append</b><i>_</i><b>at</b><i>_</i><b>myorigin</b>
- Rewrite <i>user</i> to <i>user</i>@$<b>myorigin</b>.
+ Rewrite <i>user</i> to <i>user</i>@<b>$myorigin</b>.
<b>append</b><i>_</i><b>dot</b><i>_</i><b>mydomain</b>
- Rewrite <i>user</i>@<i>host</i> to <i>user</i>@<i>host</i>.$<b>mydomain</b>.
+ Rewrite <i>user</i>@<i>host</i> to <i>user</i>@<i>host</i>.<b>$mydomain</b>.
<b>swap</b><i>_</i><b>bangpath</b>
Rewrite <i>site</i>!<i>user</i> to <i>user</i>@<i>site</i>.
<b>Routing</b>
<b>local</b><i>_</i><b>transport</b>
- Where to deliver mail for destinations that match
- $<b>mydestination</b> or $<b>inet</b><i>_</i><b>interfaces</b>. The default
+ Where to deliver mail for destinations that match
+ <b>$mydestination</b> or <b>$inet</b><i>_</i><b>interfaces</b>. The default
transport is <b>local</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>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-
+ port is <b>virtual</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>relay</b><i>_</i><b>transport</b>
+ Where to deliver mail for non-local domains that
+ match <b>$relay</b><i>_</i><b>domains</b>. The default transport is
+ <b>relay</b> (which normally is a clone of the <b>smtp</b> trans-
+ port).
+
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>default</b><i>_</i><b>transport</b>
- Where to deliver non-local mail when no information
- is explicitly given in the <a href="transport.5.html"><b>transport</b>(5)</a> table. The
+ Where to deliver all other non-local mail. The
default transport is <b>smtp</b>.
- Syntax is <i>transport</i>:<i>nexthop</i>; see <a href="transport.5.html"><b>transport</b>(5)</a> for
+ 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>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>relayhost</b>
- The default host to send non-local mail to when no
+ The default host to send non-local mail to when no
entry is matched in the <a href="transport.5.html"><b>transport</b>(5)</a> table.
- When no <b>relayhost</b> is specified, mail is routed
+ When no <b>relayhost</b> is specified, mail is routed
directly to the destination's mail exchanger.
<b>transport</b><i>_</i><b>maps</b>
- List of tables with <i>domain</i> to (<i>transport,</i> <i>nexthop</i>)
+ 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>
<a href="transport.5.html">transport(5)</a> transport table format
<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>
<li>to destinations that match <a
href="basic.html#mydestination">$mydestination</a>,
-<li>to destinations that match <a href="virtual.5.html">$virtual_maps</a>,
+<li>to destinations that match <a href="virtual.5.html">$virtual_alias_domains</a>,
<li>to destinations that match <a
-href="virtual.8.html">$virtual_mailbox_maps</a>.
+href="virtual.8.html">$virtual_mailbox_domains</a>.
</ul>
<li>Postfix is the final destination: any destination that matches
<a href="basic.html#mydestination">$mydestination</a>, <a
href="basic.html#inet_interfaces">$inet_interfaces</a>, <a
-href="virtual.5.html">$virtual_maps</a>, or
-href="virtual.8.html">$virtual_mailbox_maps</a>.
+href="virtual.5.html">$virtual_alias_domains</a>, or
+href="virtual.8.html">$virtual_mailbox_domains</a>.
</ul>
<li>Postfix is the final destination: any destination that matches
<a href="basic.html#mydestination">$mydestination</a>, <a
href="basic.html#inet_interfaces">$inet_interfaces</a>, <a
-href="virtual.5.html">$virtual_maps</a>, or <a
-href="virtual.8.html">$virtual_mailbox_maps</a>.
+href="virtual.5.html">$virtual_alias_domains</a>, or <a
+href="virtual.8.html">$virtual_mailbox_domains</a>.
</ul>
VIRTUAL(5) VIRTUAL(5)
<b>NAME</b>
- virtual - format of Postfix virtual table
+ virtual - format of Postfix virtual alias table
<b>SYNOPSIS</b>
<b>postmap</b> <b>/etc/postfix/virtual</b>
<b>postmap</b> <b>-q</b> <b>-</b> <b>/etc/postfix/virtual</b> <<i>inputfile</i>
<b>DESCRIPTION</b>
- The optional <b>virtual</b> table specifies address redirections
- for local and non-local recipients or domains. The redi-
- rections are used by the <a href="cleanup.8.html"><b>cleanup</b>(8)</a> daemon. The redirec-
- tions are recursive.
-
- The <b>virtual</b> redirection is applied only to recipient enve-
- lope addresses, and does not affect message headers.
- Think Sendmail rule set <b>S0</b>, if you like. Use <a href="canonical.5.html"><b>canonical</b>(5)</a>
- mapping to rewrite header and envelope addresses in gen-
- eral.
-
- Normally, the <b>virtual</b> table is specified as a text file
- that serves as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command. The
+ The optional <b>virtual</b> alias table specifies address alias-
+ ing for local and non-local recipients. Virtual aliasing
+ is used by the <a href="cleanup.8.html"><b>cleanup</b>(8)</a> daemon. Virtual aliasing is
+ recursive.
+
+ Virtual aliasing is applied only to recipient envelope
+ addresses, and does not affect message headers. Think
+ Sendmail rule set <b>S0</b>, if you like. Use <a href="canonical.5.html"><b>canonical</b>(5)</a> map-
+ ping to rewrite header and envelope addresses in general.
+
+ Normally, the <b>virtual</b> alias table is specified as a text
+ file that serves as input to the <a href="postmap.1.html"><b>postmap</b>(1)</a> command. The
result, an indexed file in <b>dbm</b> or <b>db</b> format, is used for
fast searching by the mail system. Execute the command
<b>postmap</b> <b>/etc/postfix/virtual</b> in order to rebuild the
sions. In that case, the lookups are done in a slightly
different way as described below.
-<b>POSTFIX-STYLE</b> <b>VIRTUAL</b> <b>DOMAINS</b>
- With a Postfix-style virtual domain, the virtual domain
- has its own user name space. Local (i.e. non-virtual)
- usernames are not visible in a Postfix-style virtual
- domain. In particular, local <a href="aliases.5.html"><b>aliases</b>(5)</a> and mailing lists
- are not visible as <i>localname@virtual.domain</i>.
+<b>SIMULATED</b> <b>VIRTUAL</b> <b>DOMAINS</b>
+ Besides virtual aliases, the virtual alias table can also
+ be used to simulate virtual domains. With a simulated vir-
+ tual domain, all recipient addresses are aliased to non-
+ virtual addresses. These non-virtual addresses may be
+ either local or remote.
- Use a Sendmail-style virtual domain (see below) if local
- usernames, <a href="aliases.5.html"><b>aliases</b>(5)</a> or mailing lists should be visible
- as <i>localname@virtual.domain</i>.
+ Simulated virtual domains are not to be confused with the
+ true virtual domains that are implemented with the Postfix
+ <a href="virtual.8.html"><b>virtual</b>(8)</a> mail delivery agent. With true virtual domains,
+ each recipient address can have its own mailbox.
- Support for a Postfix-style virtual domain looks like:
+ With a simulated virtual domain, the virtual domain has
+ its own user name space. Local (i.e. non-virtual) user-
+ names are not visible in a simulated virtual domain. In
+ particular, local <a href="aliases.5.html"><b>aliases</b>(5)</a> and mailing lists are not
+ visible as <i>localname@virtual.domain</i>.
- /etc/postfix/virtual:
- <i>virtual.domain</i> <i>anything</i> (right-hand content does not matter)
- <i>postmaster@virtual.domain</i> <i>postmaster</i>
- <i>user1@virtual.domain</i> <i>address1</i>
- <i>user2@virtual.domain</i> <i>address2,</i> <i>address3</i>
-
- The <i>virtual.domain</i> <i>anything</i> entry is required for a Post-
- fix-style virtual domain.
-
- Do not list a Postfix-style virtual domain in the <b>main.cf</b>
- <b>mydestination</b> configuration parameter. Such an entry is
- required only for a Sendmail-style virtual domain.
-
- With a Postfix-style virtual domain, the Postfix SMTP
- server accepts mail for <i>known-user@virtual.domain</i> and
- rejects mail for <i>unknown-user</i>@<i>virtual.domain</i> as undeliver-
- able.
-
-<b>SENDMAIL-STYLE</b> <b>VIRTUAL</b> <b>DOMAINS</b>
- With a Sendmail-style virtual domain, every local (i.e.
- non-virtual) username is visible in the virtual domain. In
- particular, every local alias and mailing list is visible
- as <i>localname@virtual.domain</i>.
-
- Use a Postfix-style virtual domain (see above) if local
- usernames, <a href="aliases.5.html"><b>aliases</b>(5)</a> or mailing lists should not be visi-
- ble as <i>localname@virtual.domain</i>.
-
- Support for a Sendmail-style virtual domain looks like:
+ Support for a simulated virtual domain looks like:
/etc/postfix/main.cf:
- mydestination = $myhostname localhost.$mydomain $mydomain
- <i>virtual.domain</i>
+ virtual_alias_maps = hash:/etc/postfix/virtual
+
+ Note: some systems use <b>dbm</b> databases instead of <b>hash</b>.
+ See the output from <b>postconf</b> <b>-m</b> for available database
+ types.
/etc/postfix/virtual:
+ <i>virtual.domain</i> <i>anything</i> (right-hand content does not matter)
+ <i>postmaster@virtual.domain</i> <i>postmaster</i>
<i>user1@virtual.domain</i> <i>address1</i>
<i>user2@virtual.domain</i> <i>address2,</i> <i>address3</i>
- The <b>main.cf</b> <b>mydestination</b> entry is required for a Send-
- mail-style virtual domain.
+ The <i>virtual.domain</i> <i>anything</i> entry is required for a simu-
+ lated virtual domain. Without this entry, mail will be
+ rejected with a "relay access denied" error condition.
- Do not specify a <i>virtual.domain</i> <i>anything</i> virtual map entry
- for a Sendmail-style virtual domain. Such an entry is
- required only with a Postfix-style virtual domain.
+ Do not list a simulated virtual domain name in the <b>main.cf</b>
+ <b>mydestination</b> configuration parameter.
- With a Sendmail-style virtual domain, the Postfix local
- delivery agent delivers mail for an unknown <i>user</i>@<i>vir-</i>
- <i>tual.domain</i> to a local (i.e. non-virtual) user that has
- the same name; if no such recipient exists, the Postfix
- local delivery agent bounces the mail to the sender.
+ With a simulated virtual domain, the Postfix SMTP server
+ accepts mail for <i>known-user@virtual.domain</i>, and rejects
+ mail for <i>unknown-user</i>@<i>virtual.domain</i> as undeliverable.
+
+ Instead of specifying the simulated virtual domain name
+ via the <b>virtual</b><i>_</i><b>alias</b><i>_</i><b>maps</b> table, you may also specify it
+ via the <b>main.cf</b> <b>virtual</b><i>_</i><b>alias</b><i>_</i><b>domains</b> configuration param-
+ eter. This latter parameter uses the same syntax as the
+ <b>main.cf</b> <b>mydestination</b> configuration parameter.
<b>TABLE</b> <b>FORMAT</b>
The format of the virtual table is as follows, mappings
details and for default values. Use the <b>postfix</b> <b>reload</b>
command after a configuration change.
- <b>virtual</b><i>_</i><b>maps</b>
- List of virtual mapping tables.
+ <b>virtual</b><i>_</i><b>alias</b><i>_</i><b>maps</b>
+ List of virtual aliasing tables.
+
+ <b>virtual</b><i>_</i><b>alias</b><i>_</i><b>domains</b>
+ List of simulated virtual domains. This uses the
+ same syntax as the <b>mydestination</b> parameter.
Other parameters of interest:
<b>inet</b><i>_</i><b>interfaces</b>
- The network interface addresses that this system
+ The network interface addresses that this system
receives mail on. You need to stop and start Post-
fix when this parameter changes.
<b>mydestination</b>
- List of domains that this mail system considers
+ List of domains that this mail system considers
local.
<b>myorigin</b>
<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>
Note that <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>base</b> is unconditionally
prepended to this path.
+ <b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>domains</b>
+ The list of domains that should be delivered via
+ the Postfix virtual delivery agent. This uses the
+ same syntax as the <b>mydestination</b> configuration
+ parameter.
+
<b>virtual</b><i>_</i><b>minimum</b><i>_</i><b>uid</b>
- Specifies a minimum uid that will be accepted as a
- return from a <b>virtual</b><i>_</i><b>owner</b><i>_</i><b>maps</b> or <b>vir-</b>
- <b>tual</b><i>_</i><b>uid</b><i>_</i><b>maps</b> lookup. Returned values less than
- this will be rejected, and the message will be
+ Specifies a minimum uid that will be accepted as a
+ return from a <b>virtual</b><i>_</i><b>owner</b><i>_</i><b>maps</b> or <b>vir-</b>
+ <b>tual</b><i>_</i><b>uid</b><i>_</i><b>maps</b> lookup. Returned values less than
+ this will be rejected, and the message will be
deferred.
<b>virtual</b><i>_</i><b>uid</b><i>_</i><b>maps</b> (regexp maps disallowed)
Recipients are looked up in these maps to determine
- the user ID to be used when writing to the target
+ the user ID to be used when writing to the target
mailbox.
- While searching a lookup table, an address exten-
+ While searching a lookup table, an address exten-
sion (<i>user+foo@domain.tld</i>) is ignored.
- In a lookup table, specify a left-hand side of
- <i>@domain.tld</i> to match any user in the specified
- domain that does not have a specific
+ In a lookup table, specify a left-hand side of
+ <i>@domain.tld</i> to match any user in the specified
+ domain that does not have a specific
<i>user@domain.tld</i> entry.
<b>virtual</b><i>_</i><b>gid</b><i>_</i><b>maps</b> (regexp maps disallowed)
Recipients are looked up in these maps to determine
- the group ID to be used when writing to the target
+ the group ID to be used when writing to the target
mailbox.
- While searching a lookup table, an address exten-
+ While searching a lookup table, an address exten-
sion (<i>user+foo@domain.tld</i>) is ignored.
- In a lookup table, specify a left-hand side of
- <i>@domain.tld</i> to match any user in the specified
- domain that does not have a specific
+ In a lookup table, specify a left-hand side of
+ <i>@domain.tld</i> to match any user in the specified
+ domain that does not have a specific
<i>user@domain.tld</i> entry.
<b>Locking</b> <b>controls</b>
<b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>lock</b>
- How to lock UNIX-style mailboxes: one or more of
- <b>flock</b>, <b>fcntl</b> or <b>dotlock</b>. The <b>dotlock</b> method
- requires that the recipient UID or GID has write
+ How to lock UNIX-style mailboxes: one or more of
+ <b>flock</b>, <b>fcntl</b> or <b>dotlock</b>. The <b>dotlock</b> method
+ requires that the recipient UID or GID has write
access to the parent directory of the mailbox file.
- This setting is ignored with <b>maildir</b> style deliv-
+ This setting is ignored with <b>maildir</b> style deliv-
ery, because such deliveries are safe without
explicit locks.
- Use the command <b>postconf</b> <b>-l</b> to find out what lock-
+ Use the command <b>postconf</b> <b>-l</b> to find out what lock-
ing methods are available on your system.
<b>deliver</b><i>_</i><b>lock</b><i>_</i><b>attempts</b>
- Limit the number of attempts to acquire an exclu-
+ Limit the number of attempts to acquire an exclu-
sive lock on a UNIX-style mailbox file.
<b>deliver</b><i>_</i><b>lock</b><i>_</i><b>delay</b>
Time (default: seconds) between successive attempts
- to acquire an exclusive lock on a UNIX-style mail-
- box file. The actual delay is slightly randomized.
+ to acquire an exclusive lock on a UNIX-style mail-
+ box file. The actual delay is slightly randomized.
<b>stale</b><i>_</i><b>lock</b><i>_</i><b>time</b>
- Limit the time after which a stale lockfile is
- removed (applicable to UNIX-style mailboxes only).
+ Limit the time after which a stale lockfile is
+ removed (applicable to UNIX-style mailboxes only).
<b>Resource</b> <b>controls</b>
<b>virtual</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
Limit the number of parallel deliveries to the same
domain via the <b>virtual</b> delivery agent. The default
limit is taken from the <b>default</b><i>_</i><b>destination</b><i>_</i><b>concur-</b>
- <b>rency</b><i>_</i><b>limit</b> parameter. The limit is enforced by
+ <b>rency</b><i>_</i><b>limit</b> parameter. The limit is enforced by
the Postfix queue manager.
<b>virtual</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
Limit the number of recipients per message delivery
- via the <b>virtual</b> delivery agent. The default limit
- is taken from the <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipi-</b>
- <b>ent</b><i>_</i><b>limit</b> parameter. The limit is enforced by the
+ via the <b>virtual</b> delivery agent. The default limit
+ is taken from the <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipi-</b>
+ <b>ent</b><i>_</i><b>limit</b> parameter. The limit is enforced by the
Postfix queue manager.
<b>virtual</b><i>_</i><b>mailbox</b><i>_</i><b>limit</b>
- The maximal size in bytes of a mailbox or maildir
+ The maximal size in bytes of a mailbox or maildir
file. Set to zero to disable the limit.
<b>HISTORY</b>
- This agent was originally based on the Postfix local
+ This agent was originally based on the Postfix local
delivery agent. Modifications mainly consisted of removing
- code that either was not applicable or that was not safe
- in this context: aliases, ~user/.forward files, delivery
+ code that either was not applicable or that was not safe
+ in this context: aliases, ~user/.forward files, delivery
to "|command" or to /file/name.
- The <b>Delivered-To:</b> header appears in the <b>qmail</b> system by
+ The <b>Delivered-To:</b> header appears in the <b>qmail</b> system by
Daniel Bernstein.
- The <b>maildir</b> structure appears in the <b>qmail</b> system by
+ The <b>maildir</b> structure appears in the <b>qmail</b> system by
Daniel Bernstein.
<b>SEE</b> <b>ALSO</b>
<a href="qmgr.8.html">qmgr(8)</a> queue manager
<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>
.SH NAME
virtual
\-
-format of Postfix virtual table
+format of Postfix virtual alias table
.SH SYNOPSIS
.na
.nf
.SH DESCRIPTION
.ad
.fi
-The optional \fBvirtual\fR table specifies address redirections for
-local and non-local recipients or domains. The redirections are used
-by the \fBcleanup\fR(8) daemon. The redirections are recursive.
+The optional \fBvirtual\fR alias table specifies address aliasing
+for local and non-local recipients. Virtual aliasing is used
+by the \fBcleanup\fR(8) daemon. Virtual aliasing is recursive.
-The \fBvirtual\fR redirection is applied only to recipient
+Virtual aliasing is applied only to recipient
envelope addresses, and does not affect message headers.
Think Sendmail rule set \fBS0\fR, if you like. Use \fBcanonical\fR(5)
mapping to rewrite header and envelope addresses in general.
-Normally, the \fBvirtual\fR table is specified as a text file that
-serves as input to the \fBpostmap\fR(1) command.
+Normally, the \fBvirtual\fR alias table is specified as a text file
+that serves as input to the \fBpostmap\fR(1) command.
The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
is used for fast searching by the mail system. Execute the command
\fBpostmap /etc/postfix/virtual\fR in order to rebuild the indexed
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 below.
-.SH POSTFIX-STYLE VIRTUAL DOMAINS
+.SH SIMULATED VIRTUAL DOMAINS
.na
.nf
.ad
.fi
-With a Postfix-style virtual domain, the virtual domain has its
+Besides virtual aliases, the virtual alias table can also be used
+to simulate virtual domains. With a simulated virtual domain, all
+recipient addresses are aliased to non-virtual addresses. These
+non-virtual addresses may be either local or remote.
+
+Simulated virtual domains are not to be confused with the true virtual
+domains that are implemented with the Postfix \fBvirtual\fR(8) mail
+delivery agent. With true virtual domains, each recipient address can
+have its own mailbox.
+
+With a simulated virtual domain, the virtual domain has its
own user name space. Local (i.e. non-virtual) usernames are not
-visible in a Postfix-style virtual domain. In particular, local
+visible in a simulated virtual domain. In particular, local
\fBaliases\fR(5) and mailing lists are not visible as
\fIlocalname@virtual.domain\fR.
-Use a Sendmail-style virtual domain (see below) if local usernames,
-\fBaliases\fR(5) or mailing lists should be visible as
-\fIlocalname@virtual.domain\fR.
+Support for a simulated virtual domain looks like:
-Support for a Postfix-style virtual domain looks like:
-.sp
-/etc/postfix/virtual:
+/etc/postfix/main.cf:
.in +4
+virtual_alias_maps = hash:/etc/postfix/virtual
+
+Note: some systems use \fBdbm\fR databases instead of \fBhash\fR.
+See the output from \fBpostconf -m\fR for available database types.
+
+.ti -4
+/etc/postfix/virtual:
.nf
+.na
\fIvirtual.domain anything\fR (right-hand content does not matter)
\fIpostmaster@virtual.domain postmaster\fR
\fIuser1@virtual.domain address1\fR
\fIuser2@virtual.domain address2, address3\fR
.fi
.in -4
-
-The \fIvirtual.domain anything\fR entry is required for a
-Postfix-style virtual domain.
-
-Do not list a Postfix-style virtual domain in the \fBmain.cf
-mydestination\fR configuration parameter.
-Such an entry is required only for a Sendmail-style virtual domain.
-
-With a Postfix-style virtual domain, the Postfix SMTP server
-accepts mail for \fIknown-user@virtual.domain\fR and rejects
-mail for \fIunknown-user\fR@\fIvirtual.domain\fR as undeliverable.
-.SH SENDMAIL-STYLE VIRTUAL DOMAINS
-.na
-.nf
.ad
.fi
-With a Sendmail-style virtual domain, every local (i.e. non-virtual)
-username is visible in the virtual domain. In particular, every local
-alias and mailing list is visible as \fIlocalname@virtual.domain\fR.
-
-Use a Postfix-style virtual domain (see above) if local usernames,
-\fBaliases\fR(5) or mailing lists should not be visible as
-\fIlocalname@virtual.domain\fR.
-
-Support for a Sendmail-style virtual domain looks like:
-.sp
-/etc/postfix/main.cf:
-.in +4
-.nf
-mydestination = $myhostname localhost.$mydomain $mydomain
-.ti +4
-\fIvirtual.domain\fR
-.fi
-.in -4
.sp
-/etc/postfix/virtual:
-.in +4
-.nf
-\fIuser1@virtual.domain address1\fR
-\fIuser2@virtual.domain address2, address3\fR
-.fi
-.in -4
+The \fIvirtual.domain anything\fR entry is required for a
+simulated virtual domain. Without this entry, mail will
+be rejected with a "relay access denied" error condition.
-The \fBmain.cf mydestination\fR entry is required for a Sendmail-style
-virtual domain.
+Do not list a simulated virtual domain name in the \fBmain.cf
+mydestination\fR configuration parameter.
-Do not specify a \fIvirtual.domain anything\fR virtual map entry
-for a Sendmail-style virtual domain.
-Such an entry is required only with a Postfix-style virtual domain.
+With a simulated virtual domain, the Postfix SMTP server
+accepts mail for \fIknown-user@virtual.domain\fR, and rejects
+mail for \fIunknown-user\fR@\fIvirtual.domain\fR as undeliverable.
-With a Sendmail-style virtual domain, the Postfix local delivery
-agent delivers mail for an unknown \fIuser\fR@\fIvirtual.domain\fR
-to a local (i.e. non-virtual) user that has the same name; if no
-such recipient exists, the Postfix local delivery agent bounces the
-mail to the sender.
+Instead of specifying the simulated virtual domain name via
+the \fBvirtual_alias_maps\fR table, you may also specify it via
+the \fBmain.cf virtual_alias_domains\fR configuration parameter.
+This latter parameter uses the same syntax as the \fBmain.cf
+mydestination\fR configuration parameter.
.SH TABLE FORMAT
.na
.nf
this topic. See the Postfix \fBmain.cf\fR file for syntax details
and for default values. Use the \fBpostfix reload\fR command after
a configuration change.
-.IP \fBvirtual_maps\fR
-List of virtual mapping tables.
+.IP \fBvirtual_alias_maps\fR
+List of virtual aliasing tables.
+.IP \fBvirtual_alias_domains\fR
+List of simulated virtual domains. This uses the same syntax
+as the \fBmydestination\fR parameter.
.PP
Other parameters of interest:
.IP \fBinet_interfaces\fR
List of domains that hide their subdomain structure.
.IP \fBmasquerade_exceptions\fR
List of user names that are not subject to address masquerading.
-.IP \fBvirtual_maps\fR
+.IP \fBvirtual_alias_maps\fR
Address mapping lookup table for envelope recipient addresses.
.SH "Resource controls"
.ad
Mail addressed to the local \fBdouble-bounce\fR address is silently
discarded. This stops potential loops caused by undeliverable
bounce notifications.
-
-Mail addressed to a user listed in the optional \fBrelocated\fR
-database is bounced with a "user has moved to \fInew_location\fR"
-message. See \fBrelocated\fR(5) for a precise description.
.SH MAIL QUEUES
.na
.nf
.fi
.IP \fBallow_min_user\fR
Do not bounce recipient addresses that begin with '-'.
-.IP \fBrelocated_maps\fR
-Tables with contact information for users, hosts or domains
-that no longer exist. See \fBrelocated\fR(5).
.IP \fBqueue_directory\fR
Top-level directory of the Postfix queue.
.SH "Active queue controls"
.na
.nf
master(8), process manager
-relocated(5), format of the "user has moved" table
syslogd(8) system logging
trivial-rewrite(8), address routing
.SH LICENSE
Mail addressed to the local \fBdouble-bounce\fR address is silently
discarded. This stops potential loops caused by undeliverable
bounce notifications.
-
-Mail addressed to a user listed in the optional \fBrelocated\fR
-database is bounced with a "user has moved to \fInew_location\fR"
-message. See \fBrelocated\fR(5) for a precise description.
.SH MAIL QUEUES
.na
.nf
.fi
.IP \fBallow_min_user\fR
Do not bounce recipient addresses that begin with '-'.
-.IP \fBrelocated_maps\fR
-Tables with contact information for users, hosts or domains
-that no longer exist. See \fBrelocated\fR(5).
.IP \fBqueue_directory\fR
Top-level directory of the Postfix queue.
.SH "Active queue controls"
.na
.nf
master(8), process manager
-relocated(5), format of the "user has moved" table
syslogd(8) system logging
trivial-rewrite(8), address routing
.SH LICENSE
restriction.
.IP \fBunknown_client_reject_code\fR
Response code when a client without address to name mapping
-violates the \fBreject_unknown_clients\fR restriction.
+violates the \fBreject_unknown_client\fR restriction.
.IP \fBunknown_hostname_reject_code\fR
Response code when a client violates the \fBreject_unknown_hostname\fR
restriction.
This information is used to determine if
\fIuser\fR@[\fInet.work.addr.ess\fR] is local or remote.
.IP \fBmydestination\fR
-List of domains that this machine considers local.
-.IP \fBmyorigin\fR
-The domain that locally-posted mail appears to come from.
+List of domains that are given to the \fB$local_transport\fR.
+.IP \fBvirtual_alias_domains\fT
+List of simulated virtual domains (domains with all recipients
+aliased to some other local or remote domain).
+.IP \fBvirtual_mailbox_domains\fT
+List of domains that are given to the \fB$virtual_transport\fR.
+.IP \fBrelay_domains\fT
+List of domains that are given to the \fB$relay_transport\fR.
.IP \fBresolve_unquoted_address\fR
When resolving an address, do not quote the address localpart as
per RFC 822, so that additional \fB@\fR, \fB%\fR or \fB!\fR
characters remain visible. This is technically incorrect, but
allows us to stop relay attacks when forwarding mail to a Sendmail
primary MX host.
+.IP \fBrelocated_maps\fR
+Tables with contact information for users, hosts or domains
+that no longer exist. See \fBrelocated\fR(5).
.SH Rewriting
.ad
.fi
+.IP \fBmyorigin\fR
+The domain that locally-posted mail appears to come from.
.IP \fBallow_percent_hack\fR
Rewrite \fIuser\fR%\fIdomain\fR to \fIuser\fR@\fIdomain\fR.
.IP \fBappend_at_myorigin\fR
-Rewrite \fIuser\fR to \fIuser\fR@$\fBmyorigin\fR.
+Rewrite \fIuser\fR to \fIuser\fR@\fB$myorigin\fR.
.IP \fBappend_dot_mydomain\fR
-Rewrite \fIuser\fR@\fIhost\fR to \fIuser\fR@\fIhost\fR.$\fBmydomain\fR.
+Rewrite \fIuser\fR@\fIhost\fR to \fIuser\fR@\fIhost\fR.\fB$mydomain\fR.
.IP \fBswap_bangpath\fR
Rewrite \fIsite\fR!\fIuser\fR to \fIuser\fR@\fIsite\fR.
.SH Routing
.ad
.fi
.IP \fBlocal_transport\fR
-Where to deliver mail for destinations that match $\fBmydestination\fR
-or $\fBinet_interfaces\fR.
+Where to deliver mail for destinations that match \fB$mydestination\fR
+or \fB$inet_interfaces\fR.
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.
+The default transport is \fBvirtual\fR.
+.sp
+Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
+for details. The :\fInexthop\fR part is optional.
+.IP \fBrelay_transport\fR
+Where to deliver mail for non-local domains that match
+\fB$relay_domains\fR.
+The default transport is \fBrelay\fR (which normally is a clone
+of the \fBsmtp\fR transport).
+.sp
+Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
+for details. The :\fInexthop\fR part is optional.
.IP \fBdefault_transport\fR
-Where to deliver non-local mail when no information is explicitly
-given in the \fBtransport\fR(5) table.
+Where to deliver all other non-local mail.
The default transport is \fBsmtp\fR.
.sp
Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
Note that \fBvirtual_mailbox_base\fR is unconditionally prepended
to this path.
+.IP \fBvirtual_mailbox_domains\fR
+The list of domains that should be delivered via the Postfix virtual
+delivery agent. This uses the same syntax as the \fBmydestination\fR
+configuration parameter.
.IP \fBvirtual_minimum_uid\fR
Specifies a minimum uid that will be accepted as a return from
a \fBvirtual_owner_maps\fR or \fBvirtual_uid_maps\fR lookup.
# NAME
# virtual 5
# SUMMARY
-# format of Postfix virtual table
+# format of Postfix virtual alias table
# SYNOPSIS
# \fBpostmap /etc/postfix/virtual\fR
#
#
# \fBpostmap -q - /etc/postfix/virtual <\fIinputfile\fR
# DESCRIPTION
-# The optional \fBvirtual\fR table specifies address redirections for
-# local and non-local recipients or domains. The redirections are used
-# by the \fBcleanup\fR(8) daemon. The redirections are recursive.
+# The optional \fBvirtual\fR alias table specifies address aliasing
+# for local and non-local recipients. Virtual aliasing is used
+# by the \fBcleanup\fR(8) daemon. Virtual aliasing is recursive.
#
-# The \fBvirtual\fR redirection is applied only to recipient
+# Virtual aliasing is applied only to recipient
# envelope addresses, and does not affect message headers.
# Think Sendmail rule set \fBS0\fR, if you like. Use \fBcanonical\fR(5)
# mapping to rewrite header and envelope addresses in general.
#
-# Normally, the \fBvirtual\fR table is specified as a text file that
-# serves as input to the \fBpostmap\fR(1) command.
+# Normally, the \fBvirtual\fR alias table is specified as a text file
+# that serves as input to the \fBpostmap\fR(1) command.
# The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
# is used for fast searching by the mail system. Execute the command
# \fBpostmap /etc/postfix/virtual\fR in order to rebuild the indexed
# 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 below.
-# POSTFIX-STYLE VIRTUAL DOMAINS
+# SIMULATED VIRTUAL DOMAINS
# .ad
# .fi
-# With a Postfix-style virtual domain, the virtual domain has its
+# Besides virtual aliases, the virtual alias table can also be used
+# to simulate virtual domains. With a simulated virtual domain, all
+# recipient addresses are aliased to non-virtual addresses. These
+# non-virtual addresses may be either local or remote.
+#
+# Simulated virtual domains are not to be confused with the true virtual
+# domains that are implemented with the Postfix \fBvirtual\fR(8) mail
+# delivery agent. With true virtual domains, each recipient address can
+# have its own mailbox.
+#
+# With a simulated virtual domain, the virtual domain has its
# own user name space. Local (i.e. non-virtual) usernames are not
-# visible in a Postfix-style virtual domain. In particular, local
+# visible in a simulated virtual domain. In particular, local
# \fBaliases\fR(5) and mailing lists are not visible as
# \fIlocalname@virtual.domain\fR.
#
-# Use a Sendmail-style virtual domain (see below) if local usernames,
-# \fBaliases\fR(5) or mailing lists should be visible as
-# \fIlocalname@virtual.domain\fR.
+# Support for a simulated virtual domain looks like:
#
-# Support for a Postfix-style virtual domain looks like:
-# .sp
-# /etc/postfix/virtual:
+# /etc/postfix/main.cf:
# .in +4
+# virtual_alias_maps = hash:/etc/postfix/virtual
+#
+# Note: some systems use \fBdbm\fR databases instead of \fBhash\fR.
+# See the output from \fBpostconf -m\fR for available database types.
+#
+# .ti -4
+# /etc/postfix/virtual:
# .nf
+# .na
# \fIvirtual.domain anything\fR (right-hand content does not matter)
# \fIpostmaster@virtual.domain postmaster\fR
# \fIuser1@virtual.domain address1\fR
# \fIuser2@virtual.domain address2, address3\fR
# .fi
# .in -4
-#
-# The \fIvirtual.domain anything\fR entry is required for a
-# Postfix-style virtual domain.
-#
-# Do not list a Postfix-style virtual domain in the \fBmain.cf
-# mydestination\fR configuration parameter.
-# Such an entry is required only for a Sendmail-style virtual domain.
-#
-# With a Postfix-style virtual domain, the Postfix SMTP server
-# accepts mail for \fIknown-user@virtual.domain\fR and rejects
-# mail for \fIunknown-user\fR@\fIvirtual.domain\fR as undeliverable.
-# SENDMAIL-STYLE VIRTUAL DOMAINS
# .ad
# .fi
-# With a Sendmail-style virtual domain, every local (i.e. non-virtual)
-# username is visible in the virtual domain. In particular, every local
-# alias and mailing list is visible as \fIlocalname@virtual.domain\fR.
-#
-# Use a Postfix-style virtual domain (see above) if local usernames,
-# \fBaliases\fR(5) or mailing lists should not be visible as
-# \fIlocalname@virtual.domain\fR.
-#
-# Support for a Sendmail-style virtual domain looks like:
# .sp
-# /etc/postfix/main.cf:
-# .in +4
-# .nf
-# mydestination = $myhostname localhost.$mydomain $mydomain
-# .ti +4
-# \fIvirtual.domain\fR
-# .fi
-# .in -4
-# .sp
-# /etc/postfix/virtual:
-# .in +4
-# .nf
-# \fIuser1@virtual.domain address1\fR
-# \fIuser2@virtual.domain address2, address3\fR
-# .fi
-# .in -4
+# The \fIvirtual.domain anything\fR entry is required for a
+# simulated virtual domain. Without this entry, mail will
+# be rejected with a "relay access denied" error condition.
#
-# The \fBmain.cf mydestination\fR entry is required for a Sendmail-style
-# virtual domain.
+# Do not list a simulated virtual domain name in the \fBmain.cf
+# mydestination\fR configuration parameter.
#
-# Do not specify a \fIvirtual.domain anything\fR virtual map entry
-# for a Sendmail-style virtual domain.
-# Such an entry is required only with a Postfix-style virtual domain.
+# With a simulated virtual domain, the Postfix SMTP server
+# accepts mail for \fIknown-user@virtual.domain\fR, and rejects
+# mail for \fIunknown-user\fR@\fIvirtual.domain\fR as undeliverable.
#
-# With a Sendmail-style virtual domain, the Postfix local delivery
-# agent delivers mail for an unknown \fIuser\fR@\fIvirtual.domain\fR
-# to a local (i.e. non-virtual) user that has the same name; if no
-# such recipient exists, the Postfix local delivery agent bounces the
-# mail to the sender.
+# Instead of specifying the simulated virtual domain name via
+# the \fBvirtual_alias_maps\fR table, you may also specify it via
+# the \fBmain.cf virtual_alias_domains\fR configuration parameter.
+# This latter parameter uses the same syntax as the \fBmain.cf
+# mydestination\fR configuration parameter.
# TABLE FORMAT
# .ad
# .fi
# this topic. See the Postfix \fBmain.cf\fR file for syntax details
# and for default values. Use the \fBpostfix reload\fR command after
# a configuration change.
-# .IP \fBvirtual_maps\fR
-# List of virtual mapping tables.
+# .IP \fBvirtual_alias_maps\fR
+# List of virtual aliasing tables.
+# .IP \fBvirtual_alias_domains\fR
+# List of simulated virtual domains. This uses the same syntax
+# as the \fBmydestination\fR parameter.
# .PP
# Other parameters of interest:
# .IP \fBinet_interfaces\fR
/* List of domains that hide their subdomain structure.
/* .IP \fBmasquerade_exceptions\fR
/* List of user names that are not subject to address masquerading.
-/* .IP \fBvirtual_maps\fR
+/* .IP \fBvirtual_alias_maps\fR
/* Address mapping lookup table for envelope recipient addresses.
/* .SH "Resource controls"
/* .ad
extern MAPS *cleanup_mimehdr_checks;
extern MAPS *cleanup_nesthdr_checks;
extern MAPS *cleanup_body_checks;
-extern MAPS *cleanup_virtual_maps;
+extern MAPS *cleanup_virt_alias_maps;
extern ARGV *cleanup_masq_domains;
extern int cleanup_masq_flags;
char *var_canonical_maps; /* common canonical maps */
char *var_send_canon_maps; /* sender canonical maps */
char *var_rcpt_canon_maps; /* recipient canonical maps */
-char *var_virtual_maps; /* virtual maps */
+char *var_virt_alias_maps; /* virtual alias maps */
char *var_masq_domains; /* masquerade domains */
char *var_masq_exceptions; /* users not masqueraded */
char *var_header_checks; /* primary header checks */
VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, 0, 0,
VAR_SEND_CANON_MAPS, DEF_SEND_CANON_MAPS, &var_send_canon_maps, 0, 0,
VAR_RCPT_CANON_MAPS, DEF_RCPT_CANON_MAPS, &var_rcpt_canon_maps, 0, 0,
- VAR_VIRTUAL_MAPS, DEF_VIRTUAL_MAPS, &var_virtual_maps, 0, 0,
+ VAR_VIRT_ALIAS_MAPS, DEF_VIRT_ALIAS_MAPS, &var_virt_alias_maps, 0, 0,
VAR_MASQ_DOMAINS, DEF_MASQ_DOMAINS, &var_masq_domains, 0, 0,
VAR_EMPTY_ADDR, DEF_EMPTY_ADDR, &var_empty_addr, 1, 0,
VAR_MASQ_EXCEPTIONS, DEF_MASQ_EXCEPTIONS, &var_masq_exceptions, 0, 0,
MAPS *cleanup_mimehdr_checks;
MAPS *cleanup_nesthdr_checks;
MAPS *cleanup_body_checks;
-MAPS *cleanup_virtual_maps;
+MAPS *cleanup_virt_alias_maps;
ARGV *cleanup_masq_domains;
int cleanup_masq_flags;
cleanup_rcpt_canon_maps =
maps_create(VAR_RCPT_CANON_MAPS, var_rcpt_canon_maps,
DICT_FLAG_LOCK);
- if (*var_virtual_maps)
- cleanup_virtual_maps = maps_create(VAR_VIRTUAL_MAPS, var_virtual_maps,
- DICT_FLAG_LOCK);
+ if (*var_virt_alias_maps)
+ cleanup_virt_alias_maps = maps_create(VAR_VIRT_ALIAS_MAPS,
+ var_virt_alias_maps,
+ DICT_FLAG_LOCK);
if (*var_masq_domains)
cleanup_masq_domains = argv_split(var_masq_domains, " ,\t\r\n");
if (*var_header_checks)
/* Upper bound to the size of the recipient duplicate filter.
/* Zero means no limit; this may cause the mail system to
/* become stuck.
-/* .IP virtual_maps
+/* .IP virtual_alias_maps
/* list of virtual address lookup tables.
/* LICENSE
/* .ad
if (been_here_fixed(state->dups, recip) != 0)
return;
- if (cleanup_virtual_maps == 0) {
+ if (cleanup_virt_alias_maps == 0) {
cleanup_out_string(state, REC_TYPE_ORCP, orcpt);
cleanup_out_string(state, REC_TYPE_RCPT, recip);
state->rcpt_count++;
} else {
- argv = cleanup_map1n_internal(state, recip, cleanup_virtual_maps,
+ argv = cleanup_map1n_internal(state, recip, cleanup_virt_alias_maps,
cleanup_ext_prop_mask & EXT_PROP_VIRTUAL);
for (cpp = argv->argv; *cpp; cpp++) {
cleanup_out_string(state, REC_TYPE_ORCP, orcpt);
DNS_RR *rr;
int resource_found = 0;
int cname_found = 0;
+ int default_status = DNS_NOTFOUND;
/*
* Initialize. Skip over the name server query if we haven't yet.
if (pos + fixed.length > reply->end)
CORRUPT;
if (type == fixed.type || type == T_ANY) { /* requested type */
- resource_found++;
if (rrlist) {
- if ((rr = dns_get_rr(reply, pos, rr_name, &fixed)) == 0)
- CORRUPT;
- *rrlist = dns_rr_append(*rrlist, rr);
- }
+ if ((rr = dns_get_rr(reply, pos, rr_name, &fixed)) != 0) {
+ resource_found++;
+ *rrlist = dns_rr_append(*rrlist, rr);
+ } else
+ default_status = DNS_RETRY;
+ } else
+ resource_found++;
} else if (fixed.type == T_CNAME) { /* cname resource */
cname_found++;
if (cname && c_len > 0)
return (DNS_OK);
if (cname_found)
return (DNS_RECURSE);
- return (DNS_NOTFOUND);
+ return (default_status);
}
/* dns_lookup - DNS lookup user interface */
rcpt = request->rcpt_list.info + nrcpt;
if (rcpt->offset >= 0) {
status = bounce_append(BOUNCE_FLAG_KEEP, request->queue_id,
- rcpt->orig_addr, rcpt->address, "error",
+ rcpt->orig_addr, rcpt->address, "none",
request->arrival_time,
"%s", request->nexthop);
if (status == 0)
int var_strict_8bit_body;
int var_strict_encoding;
-#define MAIN_CONF_FILE "main.cf"
-
/* check_myhostname - lookup hostname and validate */
static const char *check_myhostname(void)
#define DEF_CONFIG_DIRS ""
extern char *var_config_dirs;
+#define MAIN_CONF_FILE "main.cf"
+#define MASTER_CONF_FILE "master.cf"
+
/*
* Preferred type of indexed files. The DEF_DB_TYPE macro value is system
* dependent. It is defined in <sys_defs.h>.
/*
* trivial rewrite/resolve service: mapping tables.
*/
-#define VAR_VIRTUAL_MAPS "virtual_maps"
-#define DEF_VIRTUAL_MAPS ""
-extern char *var_virtual_maps;
+#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;
+
+#define VAR_VIRT_ALIAS_DOMS "virtual_alias_domains"
+#define DEF_VIRT_ALIAS_DOMS "$virtual_alias_maps"
+extern char *var_virt_alias_doms;
#define VAR_CANONICAL_MAPS "canonical_maps"
#define DEF_CANONICAL_MAPS ""
#define DEF_RELAY_DOMAINS "$mydestination"
extern char *var_relay_domains;
+#define VAR_RELAY_TRANSPORT "relay_transport"
+#define DEF_RELAY_TRANSPORT MAIL_SERVICE_RELAY
+extern char *var_relay_transport;
+
#define VAR_CLIENT_CHECKS "smtpd_client_restrictions"
#define DEF_CLIENT_CHECKS ""
extern char *var_client_checks;
/*
* Tunables for the "virtual" local delivery agent
*/
+#define VAR_VIRT_TRANSPORT "virtual_transport"
+#define DEF_VIRT_TRANSPORT MAIL_SERVICE_VIRTUAL
+extern char *var_virt_transport;
+
#define VAR_VIRT_MAILBOX_MAPS "virtual_mailbox_maps"
#define DEF_VIRT_MAILBOX_MAPS ""
extern char *var_virt_mailbox_maps;
+#define VAR_VIRT_MAILBOX_DOMS "virtual_mailbox_domains"
+#define DEF_VIRT_MAILBOX_DOMS "$virtual_mailbox_maps"
+extern char *var_virt_mailbox_doms;
+
#define VAR_VIRT_UID_MAPS "virtual_uid_maps"
#define DEF_VIRT_UID_MAPS ""
extern char *var_virt_uid_maps;
#define MAIL_SERVICE_SHOWQ "showq"
#define MAIL_SERVICE_ERROR "error"
#define MAIL_SERVICE_FLUSH "flush"
+#define MAIL_SERVICE_RELAY "relay"
/*
* Well-known socket or FIFO directories. The main difference is in file
* 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 "20021203"
+#define MAIL_RELEASE_DATE "20021207"
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "1.1.12-" MAIL_RELEASE_DATE
/* const char *key;
/* int flags;
/*
-/* void maps_free(maps)
+/* MAPS *maps_free(maps)
/* MAPS *maps;
/* DESCRIPTION
/* This module implements multi-dictionary searches. it goes
/* the final destination.
/* .IP RESOLVE_FLAG_ERROR
/* The address resolved to something that has invalid syntax.
+/* .IP RESOLVE_FLAG_FAIL
+/* The request could not be completed.
/* DIAGNOSTICS
/* Warnings: communication failure. Fatal error: mail system is down.
/* SEE ALSO
static void resolve(char *addr, RESOLVE_REPLY *reply)
{
resolve_clnt_query(addr, reply);
- vstream_printf("%-10s %s\n", "address", addr);
- vstream_printf("%-10s %s\n", "transport", STR(reply->transport));
- vstream_printf("%-10s %s\n", "nexthop", *STR(reply->nexthop) ?
- STR(reply->nexthop) : "[none]");
- vstream_printf("%-10s %s\n", "recipient", STR(reply->recipient));
- vstream_fflush(VSTREAM_OUT);
+ if (reply->flags & RESOLVE_FLAG_FAIL) {
+ vstream_printf("request failed\n");
+ } else {
+ vstream_printf("%-10s %s\n", "address", addr);
+ vstream_printf("%-10s %s\n", "transport", STR(reply->transport));
+ vstream_printf("%-10s %s\n", "nexthop", *STR(reply->nexthop) ?
+ STR(reply->nexthop) : "[none]");
+ vstream_printf("%-10s %s\n", "recipient", STR(reply->recipient));
+ vstream_fflush(VSTREAM_OUT);
+ }
}
int main(int argc, char **argv)
#define RESOLVE_FLAG_FINAL (1<<0) /* final delivery */
#define RESOLVE_FLAG_ROUTED (1<<1) /* routed destination */
-#define RESOLVE_FLAG_ERROR (1<<2) /* bad destination */
+#define RESOLVE_FLAG_ERROR (1<<2) /* bad destination syntax */
+#define RESOLVE_FLAG_FAIL (1<<3) /* request failed */
+
+#define RESOLVE_CLASS_LOCAL (1<<8) /* mydestination/inet_interfaces */
+#define RESOLVE_CLASS_ERROR (1<<9) /* virtual_alias_domains */
+#define RESOLVE_CLASS_VIRTUAL (1<<10) /* virtual_mailbox_domains */
+#define RESOLVE_CLASS_RELAY (1<<11) /* relay_domains */
+#define RESOLVE_CLASS_DEFAULT (1<<12) /* raise reject_unauth_destination */
typedef struct RESOLVE_REPLY {
VSTRING *transport;
/*
* External interface.
*/
+#define virtual8_maps_create(title, map_names, flags) \
+ maps_create((title), (map_names), (flags) | DICT_FLAG_NO_REGSUB)
extern const char *virtual8_maps_find(MAPS *, const char *);
+#define virtual8_maps_free(maps) maps_free((maps))
/* LICENSE
/* .ad
/* SYNOPSIS
/* #include <virtual8.h>
/*
+/* MAPS *virtual8_maps_create(title, map_names, flags)
+/* const char *title;
+/* const char *map_names;
+/* int flags;
+/*
/* const char *virtual8_maps_find(maps, recipient)
/* MAPS *maps;
/* const char *recipient;
+/*
+/* MAPS *virtual8_maps_free(maps)
+/* MAPS *maps;
/* DESCRIPTION
-/* virtual8_maps_find() does user lookups for the virtual delivery
-/* agent. The code is made available as a library routine so that
+/* This module does user lookups for the virtual delivery
+/* agent. The code is made available as a library module so that
/* other programs can perform compatible queries.
/*
-/* A zero result means that the named user was not found.
+/* virtual8_maps_create() takes list of type:name pairs and opens the
+/* named dictionaries.
+/* The result is a handle that must be specified along with all
+/* other virtual8_maps_xxx() operations.
+/* See dict_open(3) for a description of flags. virtual8_maps_create()
+/* implicitly sets the DICT_FLAG_NO_REGSUB flag in order to disable
+/* regular expression substitution into the lookup result.
+/*
+/* virtual8_maps_find() searches the specified list of dictionaries
+/* in the specified order for the named key. The result is in
+/* memory that is overwritten upon each call.
+/*
+/* virtual8_maps_free() releases storage claimed by virtual8_maps_create()
+/* and conveniently returns a null pointer.
/*
/* Arguments:
+/* .IP title
+/* String used for diagnostics. Typically one specifies the
+/* type of information stored in the lookup tables.
+/* .IP map_names
+/* Null-terminated string with type:name dictionary specifications,
+/* separated by whitespace or commas.
/* .IP maps
-/* List of pre-opened lookup tables.
-/* .IP recipient
-/* Recipient address. An optional address extension is ignored.
+/* A result from maps_create().
+/* .IP key
+/* Null-terminated string with a lookup key. Table lookup is case
+/* sensitive.
/* DIAGNOSTICS
/* The dict_errno variable is non-zero in case of problems.
/* BUGS
/* This code is a temporary solution that implements a hard-coded
/* lookup strategy. In a future version of Postfix, the lookup
/* strategy should become configurable.
+/* SEE ALSO
+/* virtual(8) virtual mailbox delivery agent
+/* maps(3) multi-dictionary search
+/* dict_open(3) low-level dictionary interface
/* LICENSE
/* .ad
/* .fi
* Look up the full address.
*/
if (bare == 0) {
- result = maps_find(maps, recipient, DICT_FLAG_FIXED);
+ result = maps_find(maps, recipient, DICT_FLAG_NONE);
if (result != 0 || dict_errno != 0)
return (result);
}
* sender and owner attributes. Otherwise, the owner attribute is reset
* (the alias is globally visible and could be sent to by anyone).
*
- * Don't match aliases that are based on regexps.
+ * Don't allow regexp substitutions.
*/
for (cpp = alias_maps->argv->argv; *cpp; cpp++) {
if ((dict = dict_handle(*cpp)) == 0)
msg_panic("%s: dictionary not found: %s", myname, *cpp);
- if ((dict->flags & ALIAS_DICT_FLAGS) != ALIAS_DICT_FLAGS) {
- msg_warn("invalid alias map type: %s", *cpp);
- continue;
- }
if ((alias_result = dict_get(dict, name)) != 0) {
if (msg_verbose)
msg_info("%s: %s: %s = %s", myname, *cpp, name, alias_result);
expansion = mystrdup(alias_result);
if (OWNER_ASSIGN(owner) != 0
- && (owner_rhs = maps_find(alias_maps, owner, ALIAS_DICT_FLAGS)) != 0) {
+ && (owner_rhs = maps_find(alias_maps, owner, DICT_FLAG_NONE)) != 0) {
canon_owner = canon_addr_internal(vstring_alloc(10),
var_exp_own_alias ? owner_rhs : owner);
SET_OWNER_ATTR(state.msg_attr, STR(canon_owner), state.level);
VAR_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT);
set_file_limit(var_mailbox_limit);
}
- alias_maps = maps_create("aliases", var_alias_maps, DICT_FLAG_LOCK);
+ alias_maps = maps_create("aliases", var_alias_maps,
+ DICT_FLAG_LOCK | DICT_FLAG_NO_REGSUB);
}
/* main - pass control to the single-threaded skeleton */
* alias.c
*/
extern MAPS *alias_maps;
-#define ALIAS_DICT_FLAGS DICT_FLAG_FIXED
/* LICENSE
/* .ad
#define FIND_OWNER(lhs, rhs, addr) { \
lhs = concatenate("owner-", addr, (char *) 0); \
(void) split_at_right(lhs, '@'); \
- rhs = maps_find(alias_maps, lhs, ALIAS_DICT_FLAGS); \
+ rhs = maps_find(alias_maps, lhs, DICT_FLAG_NONE); \
}
FIND_OWNER(owner_alias, owner_expansion, state.msg_attr.recipient);
#include <rewrite_clnt.h>
#include <tok822.h>
#include <mail_params.h>
+#include <defer.h>
/* Application-specific. */
tok822_rewrite(addr, REWRITE_CANON);
tok822_resolve(addr, &reply);
- /*
- * Splice in the optional unmatched address extension.
- */
- if (state.msg_attr.unmatched) {
- if ((ratsign = strrchr(STR(reply.recipient), '@')) == 0) {
- VSTRING_ADDCH(reply.recipient, *var_rcpt_delim);
- vstring_strcat(reply.recipient, state.msg_attr.unmatched);
+ if (reply.flags & RESOLVE_FLAG_FAIL) {
+ status = defer_append(BOUNCE_FLAG_KEEP, /* XXX */
+ BOUNCE_ATTR(state.msg_attr),
+ "address resolver failure");
+ } else {
+
+ /*
+ * Splice in the optional unmatched address extension.
+ */
+ if (state.msg_attr.unmatched) {
+ if ((ratsign = strrchr(STR(reply.recipient), '@')) == 0) {
+ VSTRING_ADDCH(reply.recipient, *var_rcpt_delim);
+ vstring_strcat(reply.recipient, state.msg_attr.unmatched);
+ } else {
+ ext_len = strlen(state.msg_attr.unmatched);
+ VSTRING_SPACE(reply.recipient, ext_len + 2);
+ if ((ratsign = strrchr(STR(reply.recipient), '@')) == 0)
+ msg_panic("%s: recipient @ botch", myname);
+ memmove(ratsign + ext_len + 1, ratsign, strlen(ratsign) + 1);
+ *ratsign = *var_rcpt_delim;
+ memcpy(ratsign + 1, state.msg_attr.unmatched, ext_len);
+ VSTRING_SKIP(reply.recipient);
+ }
+ }
+ state.msg_attr.recipient = STR(reply.recipient);
+
+ /*
+ * Delivery to a local or non-local address. For a while there was
+ * some ugly code to force local recursive alias expansions on a host
+ * with no authority over the local domain, but that code was just
+ * too unclean.
+ */
+ if (strcmp(state.msg_attr.relay, STR(reply.transport)) == 0) {
+ status = deliver_recipient(state, usr_attr);
} else {
- ext_len = strlen(state.msg_attr.unmatched);
- VSTRING_SPACE(reply.recipient, ext_len + 2);
- if ((ratsign = strrchr(STR(reply.recipient), '@')) == 0)
- msg_panic("%s: recipient @ botch", myname);
- memmove(ratsign + ext_len + 1, ratsign, strlen(ratsign) + 1);
- *ratsign = *var_rcpt_delim;
- memcpy(ratsign + 1, state.msg_attr.unmatched, ext_len);
- VSTRING_SKIP(reply.recipient);
+ status = deliver_indirect(state);
}
}
- state.msg_attr.recipient = STR(reply.recipient);
-
- /*
- * Delivery to a local or non-local address. For a while there was some
- * ugly code to force local recursive alias expansions on a host with no
- * authority over the local domain, but that code was just too unclean.
- */
- if (strcmp(state.msg_attr.relay, STR(reply.transport)) == 0) {
- status = deliver_recipient(state, usr_attr);
- } else {
- status = deliver_indirect(state);
- }
/*
* Cleanup.
mail_conf_read();
get_mail_conf_int_table(int_table);
get_mail_conf_time_table(time_table);
- path = concatenate(var_config_dir, "/master.cf", (char *) 0);
+ path = concatenate(var_config_dir, "/", MASTER_CONF_FILE, (char *) 0);
fset_master_ent(path);
myfree(path);
}
/*
* Do not bother the application when the client disconnected.
*/
+ if (master_notify(var_pid, MASTER_STAT_TAKEN) < 0)
+ multi_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT);
if (peekfd(vstream_fileno(stream)) > 0) {
multi_server_service(stream, multi_server_name, multi_server_argv);
} else {
multi_server_disconnect(stream);
}
+ if (master_notify(var_pid, MASTER_STAT_AVAIL) < 0)
+ multi_server_abort(EVENT_NULL_TYPE, EVENT_NULL_CONTEXT);
if (client_count == 0 && var_idle_limit > 0)
event_request_timer(multi_server_timeout, (char *) 0, var_idle_limit);
}
qmgr.o: ../../include/mail_server.h
qmgr.o: qmgr.h
qmgr.o: ../../include/scan_dir.h
-qmgr.o: ../../include/maps.h
qmgr_active.o: qmgr_active.c
qmgr_active.o: ../../include/sys_defs.h
qmgr_active.o: ../../include/msg.h
qmgr_active.o: ../../include/rec_type.h
qmgr_active.o: qmgr.h
qmgr_active.o: ../../include/scan_dir.h
-qmgr_active.o: ../../include/maps.h
-qmgr_active.o: ../../include/dict.h
-qmgr_active.o: ../../include/argv.h
qmgr_bounce.o: qmgr_bounce.c
qmgr_bounce.o: ../../include/sys_defs.h
qmgr_bounce.o: ../../include/bounce.h
qmgr_bounce.o: ../../include/vbuf.h
qmgr_bounce.o: qmgr.h
qmgr_bounce.o: ../../include/scan_dir.h
-qmgr_bounce.o: ../../include/maps.h
-qmgr_bounce.o: ../../include/dict.h
-qmgr_bounce.o: ../../include/argv.h
qmgr_defer.o: qmgr_defer.c
qmgr_defer.o: ../../include/sys_defs.h
qmgr_defer.o: ../../include/msg.h
qmgr_defer.o: ../../include/bounce.h
qmgr_defer.o: qmgr.h
qmgr_defer.o: ../../include/scan_dir.h
-qmgr_defer.o: ../../include/maps.h
-qmgr_defer.o: ../../include/dict.h
-qmgr_defer.o: ../../include/argv.h
qmgr_deliver.o: qmgr_deliver.c
qmgr_deliver.o: ../../include/sys_defs.h
qmgr_deliver.o: ../../include/msg.h
qmgr_deliver.o: ../../include/verp_sender.h
qmgr_deliver.o: qmgr.h
qmgr_deliver.o: ../../include/scan_dir.h
-qmgr_deliver.o: ../../include/maps.h
-qmgr_deliver.o: ../../include/dict.h
-qmgr_deliver.o: ../../include/argv.h
qmgr_enable.o: qmgr_enable.c
qmgr_enable.o: ../../include/sys_defs.h
qmgr_enable.o: ../../include/msg.h
qmgr_enable.o: ../../include/vbuf.h
qmgr_enable.o: qmgr.h
qmgr_enable.o: ../../include/scan_dir.h
-qmgr_enable.o: ../../include/maps.h
-qmgr_enable.o: ../../include/dict.h
-qmgr_enable.o: ../../include/argv.h
qmgr_entry.o: qmgr_entry.c
qmgr_entry.o: ../../include/sys_defs.h
qmgr_entry.o: ../../include/msg.h
qmgr_entry.o: ../../include/mail_params.h
qmgr_entry.o: qmgr.h
qmgr_entry.o: ../../include/scan_dir.h
-qmgr_entry.o: ../../include/maps.h
-qmgr_entry.o: ../../include/dict.h
-qmgr_entry.o: ../../include/argv.h
qmgr_job.o: qmgr_job.c
qmgr_job.o: ../../include/sys_defs.h
qmgr_job.o: ../../include/msg.h
qmgr_job.o: ../../include/vstream.h
qmgr_job.o: ../../include/vbuf.h
qmgr_job.o: ../../include/scan_dir.h
-qmgr_job.o: ../../include/maps.h
-qmgr_job.o: ../../include/dict.h
-qmgr_job.o: ../../include/argv.h
qmgr_message.o: qmgr_message.c
qmgr_message.o: ../../include/sys_defs.h
qmgr_message.o: ../../include/msg.h
qmgr_message.o: ../../include/rec_type.h
qmgr_message.o: ../../include/sent.h
qmgr_message.o: ../../include/deliver_completed.h
-qmgr_message.o: ../../include/mail_addr_find.h
-qmgr_message.o: ../../include/maps.h
qmgr_message.o: ../../include/opened.h
qmgr_message.o: ../../include/resolve_local.h
qmgr_message.o: ../../include/verp_sender.h
qmgr_move.o: ../../include/vstream.h
qmgr_move.o: ../../include/mail_scan_dir.h
qmgr_move.o: qmgr.h
-qmgr_move.o: ../../include/maps.h
-qmgr_move.o: ../../include/dict.h
-qmgr_move.o: ../../include/argv.h
qmgr_peer.o: qmgr_peer.c
qmgr_peer.o: ../../include/sys_defs.h
qmgr_peer.o: ../../include/msg.h
qmgr_peer.o: ../../include/vstream.h
qmgr_peer.o: ../../include/vbuf.h
qmgr_peer.o: ../../include/scan_dir.h
-qmgr_peer.o: ../../include/maps.h
-qmgr_peer.o: ../../include/dict.h
-qmgr_peer.o: ../../include/argv.h
qmgr_queue.o: qmgr_queue.c
qmgr_queue.o: ../../include/sys_defs.h
qmgr_queue.o: ../../include/msg.h
qmgr_queue.o: ../../include/vstream.h
qmgr_queue.o: ../../include/vbuf.h
qmgr_queue.o: ../../include/scan_dir.h
-qmgr_queue.o: ../../include/maps.h
-qmgr_queue.o: ../../include/dict.h
-qmgr_queue.o: ../../include/argv.h
qmgr_rcpt_list.o: qmgr_rcpt_list.c
qmgr_rcpt_list.o: ../../include/sys_defs.h
qmgr_rcpt_list.o: ../../include/mymalloc.h
qmgr_rcpt_list.o: ../../include/vstream.h
qmgr_rcpt_list.o: ../../include/vbuf.h
qmgr_rcpt_list.o: ../../include/scan_dir.h
-qmgr_rcpt_list.o: ../../include/maps.h
-qmgr_rcpt_list.o: ../../include/dict.h
-qmgr_rcpt_list.o: ../../include/argv.h
qmgr_scan.o: qmgr_scan.c
qmgr_scan.o: ../../include/sys_defs.h
qmgr_scan.o: ../../include/msg.h
qmgr_scan.o: qmgr.h
qmgr_scan.o: ../../include/vstream.h
qmgr_scan.o: ../../include/vbuf.h
-qmgr_scan.o: ../../include/maps.h
-qmgr_scan.o: ../../include/dict.h
-qmgr_scan.o: ../../include/argv.h
qmgr_transport.o: qmgr_transport.c
qmgr_transport.o: ../../include/sys_defs.h
qmgr_transport.o: ../../include/msg.h
qmgr_transport.o: ../../include/mail_params.h
qmgr_transport.o: qmgr.h
qmgr_transport.o: ../../include/scan_dir.h
-qmgr_transport.o: ../../include/maps.h
-qmgr_transport.o: ../../include/dict.h
-qmgr_transport.o: ../../include/argv.h
/* Mail addressed to the local \fBdouble-bounce\fR address is silently
/* discarded. This stops potential loops caused by undeliverable
/* bounce notifications.
-/*
-/* Mail addressed to a user listed in the optional \fBrelocated\fR
-/* database is bounced with a "user has moved to \fInew_location\fR"
-/* message. See \fBrelocated\fR(5) for a precise description.
/* MAIL QUEUES
/* .ad
/* .fi
/* .fi
/* .IP \fBallow_min_user\fR
/* Do not bounce recipient addresses that begin with '-'.
-/* .IP \fBrelocated_maps\fR
-/* Tables with contact information for users, hosts or domains
-/* that no longer exist. See \fBrelocated\fR(5).
/* .IP \fBqueue_directory\fR
/* Top-level directory of the Postfix queue.
/* .SH "Active queue controls"
/* Default values for the transport specific parameters described above.
/* SEE ALSO
/* master(8), process manager
-/* relocated(5), format of the "user has moved" table
/* syslogd(8) system logging
/* trivial-rewrite(8), address routing
/* LICENSE
int var_transport_retry_time;
int var_dest_con_limit;
int var_dest_rcpt_limit;
-char *var_relocated_maps;
-char *var_virtual_maps;
char *var_defer_xports;
bool var_allow_min_user;
int var_local_con_lim;
static QMGR_SCAN *qmgr_incoming;
static QMGR_SCAN *qmgr_deferred;
-MAPS *qmgr_relocated;
-MAPS *qmgr_virtual;
-
/* qmgr_deferred_run_event - queue manager heartbeat */
static void qmgr_deferred_run_event(int unused_event, char *dummy)
}
}
-/* qmgr_pre_init - pre-jail initialization */
-
-static void qmgr_pre_init(char *unused_name, char **unused_argv)
-{
- if (*var_relocated_maps)
- qmgr_relocated = maps_create("relocated", var_relocated_maps,
- DICT_FLAG_LOCK);
- if (*var_virtual_maps)
- qmgr_virtual = maps_create("virtual", var_virtual_maps,
- DICT_FLAG_LOCK);
-}
-
/* qmgr_post_init - post-jail initialization */
static void qmgr_post_init(char *unused_name, char **unused_argv)
int main(int argc, char **argv)
{
static CONFIG_STR_TABLE str_table[] = {
- VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, 0, 0,
- VAR_VIRTUAL_MAPS, DEF_VIRTUAL_MAPS, &var_virtual_maps, 0, 0,
VAR_DEFER_XPORTS, DEF_DEFER_XPORTS, &var_defer_xports, 0, 0,
0,
};
MAIL_SERVER_STR_TABLE, str_table,
MAIL_SERVER_BOOL_TABLE, bool_table,
MAIL_SERVER_TIME_TABLE, time_table,
- MAIL_SERVER_PRE_INIT, qmgr_pre_init,
MAIL_SERVER_POST_INIT, qmgr_post_init,
MAIL_SERVER_LOOP, qmgr_loop,
MAIL_SERVER_PRE_ACCEPT, pre_accept,
#include <vstream.h>
#include <scan_dir.h>
- /*
- * Global library.
- */
-#include <maps.h>
-
/*
* The queue manager is built around lots of mutually-referring structures.
* These typedefs save some typing.
extern int qmgr_message_count;
extern int qmgr_recipient_count;
-extern MAPS *qmgr_relocated;
-extern MAPS *qmgr_virtual;
extern void qmgr_message_free(QMGR_MESSAGE *);
extern void qmgr_message_update_warn(QMGR_MESSAGE *);
*/
extern void qmgr_defer_transport(QMGR_TRANSPORT *, const char *);
extern void qmgr_defer_todo(QMGR_QUEUE *, const char *);
-extern void qmgr_defer_recipient(QMGR_MESSAGE *, const char *, const char *, const char *);
+extern void qmgr_defer_recipient(QMGR_MESSAGE *, QMGR_RCPT *, const char *);
/*
* qmgr_bounce.c
/* SYNOPSIS
/* #include "qmgr.h"
/*
-/* void qmgr_defer_recipient(message, address, reason)
+/* void qmgr_defer_recipient(message, recipient, reason)
/* QMGR_MESSAGE *message;
-/* const char *address;
+/* QMGR_RCPT *recipient;
/* const char *reason;
/*
/* void qmgr_defer_todo(queue, reason)
message = entry->message;
for (nrcpt = 0; nrcpt < entry->rcpt_list.len; nrcpt++) {
recipient = entry->rcpt_list.info + nrcpt;
- qmgr_defer_recipient(message, recipient->orig_rcpt,
- recipient->address, reason);
+ qmgr_defer_recipient(message, recipient, reason);
}
qmgr_entry_done(entry, QMGR_QUEUE_TODO);
}
/* qmgr_defer_recipient - defer delivery of specific recipient */
-void qmgr_defer_recipient(QMGR_MESSAGE *message, const char *orig_addr,
- const char *address, const char *reason)
+void qmgr_defer_recipient(QMGR_MESSAGE *message, QMGR_RCPT *recipient,
+ const char *reason)
{
char *myname = "qmgr_defer_recipient";
* Update the message structure and log the message disposition.
*/
message->flags |= defer_append(BOUNCE_FLAG_KEEP, message->queue_id,
- orig_addr, address, "none",
- message->arrival_time, "%s", reason);
+ recipient->orig_rcpt, recipient->address,
+ "none", message->arrival_time, "%s", reason);
}
#include <rec_type.h>
#include <sent.h>
#include <deliver_completed.h>
-#include <mail_addr_find.h>
#include <opened.h>
#include <resolve_local.h>
#include <verp_sender.h>
QMGR_TRANSPORT *transport = 0;
QMGR_QUEUE *queue = 0;
RESOLVE_REPLY reply;
- const char *newloc;
char *at;
char **cpp;
- char *domain;
- const char *junk;
char *nexthop;
int len;
*/
if (var_sender_routing == 0) {
resolve_clnt_query(recipient->address, &reply);
+ if (reply.flags & RESOLVE_FLAG_FAIL) {
+ qmgr_defer_recipient(message, recipient,
+ "address resolver failure");
+ continue;
+ }
if (reply.flags & RESOLVE_FLAG_ERROR) {
qmgr_bounce_recipient(message, recipient,
"bad address syntax: \"%s\"",
}
} else {
resolve_clnt_query(message->sender, &reply);
+ if (reply.flags & RESOLVE_FLAG_FAIL) {
+ qmgr_defer_recipient(message, recipient,
+ "address resolver failure");
+ continue;
+ }
if (reply.flags & RESOLVE_FLAG_ERROR) {
qmgr_bounce_recipient(message, recipient,
"bad address syntax: \"%s\"",
*/
lowercase(STR(reply.nexthop));
- /*
- * Bounce recipients that have moved. We do it here instead of in the
- * local delivery agent. The benefit is that we can bounce mail for
- * virtual addresses, not just local addresses only, and that there
- * is no need to run a local delivery agent just for the sake of
- * relocation notices. The downside is that this table has no effect
- * on local alias expansion results, so that mail will have to make
- * almost an entire iteration through the mail system.
- */
-#define IGNORE_ADDR_EXTENSION ((char **) 0)
-
- if (qmgr_relocated != 0) {
- if ((newloc = mail_addr_find(qmgr_relocated, recipient->address,
- IGNORE_ADDR_EXTENSION)) != 0) {
- qmgr_bounce_recipient(message, recipient,
- "user has moved to %s", newloc);
- continue;
- } else if (dict_errno != 0) {
- qmgr_defer_recipient(message, recipient->orig_rcpt,
- recipient->address,
- "relocated map lookup failure");
- continue;
- }
- }
-
- /*
- * Bounce mail to non-existent users in virtual domains.
- */
- if (qmgr_virtual != 0
- && (at = strrchr(recipient->address, '@')) != 0
- && !resolve_local(at + 1)) {
- domain = lowercase(mystrdup(at + 1));
- junk = maps_find(qmgr_virtual, domain, 0);
- myfree(domain);
- if (junk) {
- qmgr_bounce_recipient(message, recipient,
- "unknown user: \"%s\"", recipient->address);
- continue;
- }
- }
-
/*
* Bounce recipient addresses that start with `-'. External commands
* may misinterpret such addresses as command-line options.
if (strcmp(*cpp, STR(reply.transport)) == 0)
break;
if (*cpp) {
- qmgr_defer_recipient(message, recipient->orig_rcpt,
- recipient->address,
- "deferred transport");
+ qmgr_defer_recipient(message, recipient, "deferred transport");
continue;
}
}
* This transport is dead. Defer delivery to this recipient.
*/
if ((transport->flags & QMGR_TRANSPORT_STAT_DEAD) != 0) {
- qmgr_defer_recipient(message, recipient->orig_rcpt,
- recipient->address, transport->reason);
+ qmgr_defer_recipient(message, recipient, transport->reason);
continue;
}
* This queue is dead. Defer delivery to this recipient.
*/
if (queue->window == 0) {
- qmgr_defer_recipient(message, recipient->orig_rcpt,
- recipient->address, queue->reason);
+ qmgr_defer_recipient(message, recipient, queue->reason);
continue;
}
qmgr.o: ../../include/mail_server.h
qmgr.o: qmgr.h
qmgr.o: ../../include/scan_dir.h
-qmgr.o: ../../include/maps.h
qmgr_active.o: qmgr_active.c
qmgr_active.o: ../../include/sys_defs.h
qmgr_active.o: ../../include/msg.h
qmgr_active.o: ../../include/rec_type.h
qmgr_active.o: qmgr.h
qmgr_active.o: ../../include/scan_dir.h
-qmgr_active.o: ../../include/maps.h
-qmgr_active.o: ../../include/dict.h
-qmgr_active.o: ../../include/argv.h
qmgr_bounce.o: qmgr_bounce.c
qmgr_bounce.o: ../../include/sys_defs.h
qmgr_bounce.o: ../../include/bounce.h
qmgr_bounce.o: ../../include/vbuf.h
qmgr_bounce.o: qmgr.h
qmgr_bounce.o: ../../include/scan_dir.h
-qmgr_bounce.o: ../../include/maps.h
-qmgr_bounce.o: ../../include/dict.h
-qmgr_bounce.o: ../../include/argv.h
qmgr_defer.o: qmgr_defer.c
qmgr_defer.o: ../../include/sys_defs.h
qmgr_defer.o: ../../include/msg.h
qmgr_defer.o: ../../include/bounce.h
qmgr_defer.o: qmgr.h
qmgr_defer.o: ../../include/scan_dir.h
-qmgr_defer.o: ../../include/maps.h
-qmgr_defer.o: ../../include/dict.h
-qmgr_defer.o: ../../include/argv.h
qmgr_deliver.o: qmgr_deliver.c
qmgr_deliver.o: ../../include/sys_defs.h
qmgr_deliver.o: ../../include/msg.h
qmgr_deliver.o: ../../include/verp_sender.h
qmgr_deliver.o: qmgr.h
qmgr_deliver.o: ../../include/scan_dir.h
-qmgr_deliver.o: ../../include/maps.h
-qmgr_deliver.o: ../../include/dict.h
-qmgr_deliver.o: ../../include/argv.h
qmgr_enable.o: qmgr_enable.c
qmgr_enable.o: ../../include/sys_defs.h
qmgr_enable.o: ../../include/msg.h
qmgr_enable.o: ../../include/vbuf.h
qmgr_enable.o: qmgr.h
qmgr_enable.o: ../../include/scan_dir.h
-qmgr_enable.o: ../../include/maps.h
-qmgr_enable.o: ../../include/dict.h
-qmgr_enable.o: ../../include/argv.h
qmgr_entry.o: qmgr_entry.c
qmgr_entry.o: ../../include/sys_defs.h
qmgr_entry.o: ../../include/msg.h
qmgr_entry.o: ../../include/mail_params.h
qmgr_entry.o: qmgr.h
qmgr_entry.o: ../../include/scan_dir.h
-qmgr_entry.o: ../../include/maps.h
-qmgr_entry.o: ../../include/dict.h
-qmgr_entry.o: ../../include/argv.h
qmgr_message.o: qmgr_message.c
qmgr_message.o: ../../include/sys_defs.h
qmgr_message.o: ../../include/msg.h
qmgr_message.o: ../../include/rec_type.h
qmgr_message.o: ../../include/sent.h
qmgr_message.o: ../../include/deliver_completed.h
-qmgr_message.o: ../../include/mail_addr_find.h
-qmgr_message.o: ../../include/maps.h
qmgr_message.o: ../../include/opened.h
qmgr_message.o: ../../include/resolve_local.h
qmgr_message.o: ../../include/verp_sender.h
qmgr_move.o: ../../include/vstream.h
qmgr_move.o: ../../include/mail_scan_dir.h
qmgr_move.o: qmgr.h
-qmgr_move.o: ../../include/maps.h
-qmgr_move.o: ../../include/dict.h
-qmgr_move.o: ../../include/argv.h
qmgr_queue.o: qmgr_queue.c
qmgr_queue.o: ../../include/sys_defs.h
qmgr_queue.o: ../../include/msg.h
qmgr_queue.o: ../../include/vstream.h
qmgr_queue.o: ../../include/vbuf.h
qmgr_queue.o: ../../include/scan_dir.h
-qmgr_queue.o: ../../include/maps.h
-qmgr_queue.o: ../../include/dict.h
-qmgr_queue.o: ../../include/argv.h
qmgr_rcpt_list.o: qmgr_rcpt_list.c
qmgr_rcpt_list.o: ../../include/sys_defs.h
qmgr_rcpt_list.o: ../../include/mymalloc.h
qmgr_rcpt_list.o: ../../include/vstream.h
qmgr_rcpt_list.o: ../../include/vbuf.h
qmgr_rcpt_list.o: ../../include/scan_dir.h
-qmgr_rcpt_list.o: ../../include/maps.h
-qmgr_rcpt_list.o: ../../include/dict.h
-qmgr_rcpt_list.o: ../../include/argv.h
qmgr_scan.o: qmgr_scan.c
qmgr_scan.o: ../../include/sys_defs.h
qmgr_scan.o: ../../include/msg.h
qmgr_scan.o: qmgr.h
qmgr_scan.o: ../../include/vstream.h
qmgr_scan.o: ../../include/vbuf.h
-qmgr_scan.o: ../../include/maps.h
-qmgr_scan.o: ../../include/dict.h
-qmgr_scan.o: ../../include/argv.h
qmgr_transport.o: qmgr_transport.c
qmgr_transport.o: ../../include/sys_defs.h
qmgr_transport.o: ../../include/msg.h
qmgr_transport.o: ../../include/mail_params.h
qmgr_transport.o: qmgr.h
qmgr_transport.o: ../../include/scan_dir.h
-qmgr_transport.o: ../../include/maps.h
-qmgr_transport.o: ../../include/dict.h
-qmgr_transport.o: ../../include/argv.h
/* Mail addressed to the local \fBdouble-bounce\fR address is silently
/* discarded. This stops potential loops caused by undeliverable
/* bounce notifications.
-/*
-/* Mail addressed to a user listed in the optional \fBrelocated\fR
-/* database is bounced with a "user has moved to \fInew_location\fR"
-/* message. See \fBrelocated\fR(5) for a precise description.
/* MAIL QUEUES
/* .ad
/* .fi
/* .fi
/* .IP \fBallow_min_user\fR
/* Do not bounce recipient addresses that begin with '-'.
-/* .IP \fBrelocated_maps\fR
-/* Tables with contact information for users, hosts or domains
-/* that no longer exist. See \fBrelocated\fR(5).
/* .IP \fBqueue_directory\fR
/* Top-level directory of the Postfix queue.
/* .SH "Active queue controls"
/* named message \fItransport\fR.
/* SEE ALSO
/* master(8), process manager
-/* relocated(5), format of the "user has moved" table
/* syslogd(8) system logging
/* trivial-rewrite(8), address routing
/* LICENSE
int var_transport_retry_time;
int var_dest_con_limit;
int var_dest_rcpt_limit;
-char *var_relocated_maps;
-char *var_virtual_maps;
char *var_defer_xports;
bool var_allow_min_user;
int var_qmgr_fudge;
static QMGR_SCAN *qmgr_incoming;
static QMGR_SCAN *qmgr_deferred;
-MAPS *qmgr_relocated;
-MAPS *qmgr_virtual;
-
/* qmgr_deferred_run_event - queue manager heartbeat */
static void qmgr_deferred_run_event(int unused_event, char *dummy)
}
}
-/* qmgr_pre_init - pre-jail initialization */
-
-static void qmgr_pre_init(char *unused_name, char **unused_argv)
-{
- if (*var_relocated_maps)
- qmgr_relocated = maps_create("relocated", var_relocated_maps,
- DICT_FLAG_LOCK);
- if (*var_virtual_maps)
- qmgr_virtual = maps_create("virtual", var_virtual_maps,
- DICT_FLAG_LOCK);
-}
-
/* qmgr_post_init - post-jail initialization */
static void qmgr_post_init(char *unused_name, char **unused_argv)
int main(int argc, char **argv)
{
static CONFIG_STR_TABLE str_table[] = {
- VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, 0, 0,
- VAR_VIRTUAL_MAPS, DEF_VIRTUAL_MAPS, &var_virtual_maps, 0, 0,
VAR_DEFER_XPORTS, DEF_DEFER_XPORTS, &var_defer_xports, 0, 0,
0,
};
MAIL_SERVER_STR_TABLE, str_table,
MAIL_SERVER_BOOL_TABLE, bool_table,
MAIL_SERVER_TIME_TABLE, time_table,
- MAIL_SERVER_PRE_INIT, qmgr_pre_init,
MAIL_SERVER_POST_INIT, qmgr_post_init,
MAIL_SERVER_LOOP, qmgr_loop,
MAIL_SERVER_PRE_ACCEPT, pre_accept,
#include <vstream.h>
#include <scan_dir.h>
- /*
- * Global library.
- */
-#include <maps.h>
-
/*
* The queue manager is built around lots of mutually-referring structures.
* These typedefs save some typing.
extern int qmgr_message_count;
extern int qmgr_recipient_count;
-extern MAPS *qmgr_relocated;
-extern MAPS *qmgr_virtual;
extern void qmgr_message_free(QMGR_MESSAGE *);
extern void qmgr_message_update_warn(QMGR_MESSAGE *);
*/
extern void qmgr_defer_transport(QMGR_TRANSPORT *, const char *);
extern void qmgr_defer_todo(QMGR_QUEUE *, const char *);
-extern void qmgr_defer_recipient(QMGR_MESSAGE *, const char *, const char *, const char *);
+extern void qmgr_defer_recipient(QMGR_MESSAGE *, QMGR_RCPT *, const char *);
/*
* qmgr_bounce.c
/* SYNOPSIS
/* #include "qmgr.h"
/*
-/* void qmgr_defer_recipient(message, address, reason)
+/* void qmgr_defer_recipient(message, recipient, reason)
/* QMGR_MESSAGE *message;
-/* const char *address;
+/* QMGR_RCPT *recipient;
/* const char *reason;
/*
/* void qmgr_defer_todo(queue, reason)
message = entry->message;
for (nrcpt = 0; nrcpt < entry->rcpt_list.len; nrcpt++) {
recipient = entry->rcpt_list.info + nrcpt;
- qmgr_defer_recipient(message, recipient->orig_rcpt,
- recipient->address, reason);
+ qmgr_defer_recipient(message, recipient, reason);
}
qmgr_entry_done(entry, QMGR_QUEUE_TODO);
}
/* qmgr_defer_recipient - defer delivery of specific recipient */
-void qmgr_defer_recipient(QMGR_MESSAGE *message, const char *orig_addr,
- const char *address, const char *reason)
+void qmgr_defer_recipient(QMGR_MESSAGE *message, QMGR_RCPT *recipient,
+ const char *reason)
{
char *myname = "qmgr_defer_recipient";
* Update the message structure and log the message disposition.
*/
message->flags |= defer_append(BOUNCE_FLAG_KEEP, message->queue_id,
- orig_addr, address, "none",
- message->arrival_time, "%s", reason);
+ recipient->orig_rcpt, recipient->address,
+ "none", message->arrival_time, "%s", reason);
}
#include <rec_type.h>
#include <sent.h>
#include <deliver_completed.h>
-#include <mail_addr_find.h>
#include <opened.h>
#include <resolve_local.h>
#include <verp_sender.h>
QMGR_TRANSPORT *transport = 0;
QMGR_QUEUE *queue = 0;
RESOLVE_REPLY reply;
- const char *newloc;
char *at;
char **cpp;
- char *domain;
- const char *junk;
char *nexthop;
int len;
*/
if (var_sender_routing == 0) {
resolve_clnt_query(recipient->address, &reply);
+ if (reply.flags & RESOLVE_FLAG_FAIL) {
+ qmgr_defer_recipient(message, recipient,
+ "address resolver failure");
+ continue;
+ }
if (reply.flags & RESOLVE_FLAG_ERROR) {
qmgr_bounce_recipient(message, recipient,
"bad address syntax: \"%s\"",
}
} else {
resolve_clnt_query(message->sender, &reply);
+ if (reply.flags & RESOLVE_FLAG_FAIL) {
+ qmgr_defer_recipient(message, recipient,
+ "address resolver failure");
+ continue;
+ }
if (reply.flags & RESOLVE_FLAG_ERROR) {
qmgr_bounce_recipient(message, recipient,
"bad address syntax: \"%s\"",
*/
lowercase(STR(reply.nexthop));
- /*
- * Bounce recipients that have moved. We do it here instead of in the
- * local delivery agent. The benefit is that we can bounce mail for
- * virtual addresses, not just local addresses only, and that there
- * is no need to run a local delivery agent just for the sake of
- * relocation notices. The downside is that this table has no effect
- * on local alias expansion results, so that mail will have to make
- * almost an entire iteration through the mail system.
- */
-#define IGNORE_ADDR_EXTENSION ((char **) 0)
-
- if (qmgr_relocated != 0) {
- if ((newloc = mail_addr_find(qmgr_relocated, recipient->address,
- IGNORE_ADDR_EXTENSION)) != 0) {
- qmgr_bounce_recipient(message, recipient,
- "user has moved to %s", newloc);
- continue;
- } else if (dict_errno != 0) {
- qmgr_defer_recipient(message, recipient->orig_rcpt,
- recipient->address,
- "relocated map lookup failure");
- continue;
- }
- }
-
- /*
- * Bounce mail to non-existent users in virtual domains.
- */
- if (qmgr_virtual != 0
- && (at = strrchr(recipient->address, '@')) != 0
- && !resolve_local(at + 1)) {
- domain = lowercase(mystrdup(at + 1));
- junk = maps_find(qmgr_virtual, domain, 0);
- myfree(domain);
- if (junk) {
- qmgr_bounce_recipient(message, recipient,
- "unknown user: \"%s\"", recipient->address);
- continue;
- }
- }
-
/*
* Bounce recipient addresses that start with `-'. External commands
* may misinterpret such addresses as command-line options.
if (strcasecmp(*cpp, STR(reply.transport)) == 0)
break;
if (*cpp) {
- qmgr_defer_recipient(message, recipient->orig_rcpt,
- recipient->address,
- "deferred transport");
+ qmgr_defer_recipient(message, recipient, "deferred transport");
continue;
}
}
* This transport is dead. Defer delivery to this recipient.
*/
if ((transport->flags & QMGR_TRANSPORT_STAT_DEAD) != 0) {
- qmgr_defer_recipient(message, recipient->orig_rcpt,
- recipient->address, transport->reason);
+ qmgr_defer_recipient(message, recipient, transport->reason);
continue;
}
* This queue is dead. Defer delivery to this recipient.
*/
if (queue->window == 0) {
- qmgr_defer_recipient(message, recipient->orig_rcpt,
- recipient->address, queue->reason);
+ qmgr_defer_recipient(message, recipient, queue->reason);
continue;
}
* Build the MAIL FROM command.
*/
case SMTP_STATE_MAIL:
- if (var_disable_dns == 0) {
- REWRITE_ADDRESS(state->scratch, state->scratch2,
- request->sender);
- } else {
- QUOTE_ADDRESS(state->scratch, request->sender);
- }
+ QUOTE_ADDRESS(state->scratch, request->sender);
vstring_sprintf(next_command, "MAIL FROM:<%s>",
vstring_str(state->scratch));
if (state->features & SMTP_FEATURE_SIZE) /* RFC 1870 */
*/
case SMTP_STATE_RCPT:
rcpt = request->rcpt_list.info + send_rcpt;
- if (var_disable_dns == 0) {
- REWRITE_ADDRESS(state->scratch, state->scratch2,
- rcpt->address);
- } else {
- QUOTE_ADDRESS(state->scratch, rcpt->address);
- }
+ QUOTE_ADDRESS(state->scratch, rcpt->address);
vstring_sprintf(next_command, "RCPT TO:<%s>",
vstring_str(state->scratch));
if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len)
/* restriction.
/* .IP \fBunknown_client_reject_code\fR
/* Response code when a client without address to name mapping
-/* violates the \fBreject_unknown_clients\fR restriction.
+/* violates the \fBreject_unknown_client\fR restriction.
/* .IP \fBunknown_hostname_reject_code\fR
/* Response code when a client violates the \fBreject_unknown_hostname\fR
/* restriction.
bool var_disable_vrfy_cmd;
char *var_canonical_maps;
char *var_rcpt_canon_maps;
-char *var_virtual_maps;
+char *var_virt_alias_maps;
+char *var_virt_alias_doms;
char *var_virt_mailbox_maps;
+char *var_virt_mailbox_doms;
char *var_relocated_maps;
char *var_alias_maps;
char *var_local_rcpt_maps;
VAR_REST_CLASSES, DEF_REST_CLASSES, &var_rest_classes, 0, 0,
VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, 0, 0,
VAR_RCPT_CANON_MAPS, DEF_RCPT_CANON_MAPS, &var_rcpt_canon_maps, 0, 0,
- VAR_VIRTUAL_MAPS, DEF_VIRTUAL_MAPS, &var_virtual_maps, 0, 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,
+ VAR_VIRT_MAILBOX_DOMS, DEF_VIRT_MAILBOX_DOMS, &var_virt_mailbox_doms, 0, 0,
VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, 0, 0,
VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps, 0, 0,
VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0,
/* Permit the request when the resolved recipient domain matches the
/* \fIrelay_domains\fR configuration parameter or a subdomain thereof,
/* or when the destination somehow resolves locally ($inet_interfaces,
-/* $mydestination or $virtual_maps).
+/* $mydestination, $virtual_alias_domains, or $virtual_mailbox_domains).
/* .IP reject_unauth_destination
/* Reject the request when the resolved recipient domain does not match
/* the \fIrelay_domains\fR configuration parameter or a subdomain
/* thereof, and when the destination does not somehow resolve locally
-/* ($inet_interfaces, $mydestination, $virtual_maps, or
-/* $virtual_mailbox_maps).
+/* ($inet_interfaces, $mydestination, $virtual_alias_domains, or
+/* $virtual_mailbox_domains).
/* The \fIrelay_domains_reject_code\fR configuration parameter specifies
/* the reject status code (default: 554).
/* .IP reject_unauth_pipelining
/* Global library. */
+#include <string_list.h>
#include <namadr_list.h>
#include <domain_list.h>
#include <mail_params.h>
static MAPS *local_rcpt_maps;
static MAPS *rcpt_canon_maps;
static MAPS *canonical_maps;
-static MAPS *virtual_maps;
+static MAPS *virt_alias_maps;
static MAPS *virt_mailbox_maps;
static MAPS *relocated_maps;
+static STRING_LIST *virt_alias_doms;
+static STRING_LIST *virt_mailbox_doms;
+
/*
* Response templates for various rbl domains.
*/
DICT_FLAG_LOCK);
canonical_maps = maps_create(VAR_CANONICAL_MAPS, var_canonical_maps,
DICT_FLAG_LOCK);
- virtual_maps = maps_create(VAR_VIRTUAL_MAPS, var_virtual_maps,
- DICT_FLAG_LOCK);
- virt_mailbox_maps = maps_create(VAR_VIRT_MAILBOX_MAPS, var_virt_mailbox_maps,
- DICT_FLAG_LOCK);
+ virt_alias_maps = maps_create(VAR_VIRT_ALIAS_MAPS, var_virt_alias_maps,
+ DICT_FLAG_LOCK);
+ virt_mailbox_maps = virtual8_maps_create(VAR_VIRT_MAILBOX_MAPS,
+ var_virt_mailbox_maps,
+ DICT_FLAG_LOCK);
relocated_maps = maps_create(VAR_RELOCATED_MAPS, var_relocated_maps,
DICT_FLAG_LOCK);
+ virt_alias_doms = string_list_init(MATCH_FLAG_NONE, var_virt_alias_doms);
+ virt_mailbox_doms = string_list_init(MATCH_FLAG_NONE, var_virt_mailbox_doms);
+
access_parent_style = match_parent_style(SMTPD_ACCESS_MAPS);
/*
451, reply_name));
}
-/* check_maps_find - reject with temporary failure if dict lookup fails */
+/* check_str_match - reject with temporary failure if dict lookup fails */
-static const char *check_maps_find(SMTPD_STATE *state, const char *reply_name,
- MAPS *maps, const char *key, int flags)
+static int check_str_match(SMTPD_STATE *state, const char *reply_name,
+ STRING_LIST *list, const char *key)
{
- const char *result;
+ int result;
dict_errno = 0;
- if ((result = maps_find(maps, key, flags)) == 0
+ if ((result = string_list_match(list, key)) == 0
&& dict_errno == DICT_ERR_RETRY)
reject_dict_retry(state, reply_name);
return (result);
/* If matches $mydestination or $inet_interfaces. */
if (resolve_local(domain)) {
- if (*var_virtual_maps
- && check_maps_find(state, reply_name, virtual_maps, domain, 0))
+ if (*var_virt_alias_doms
+ && check_str_match(state, reply_name, virt_alias_doms, domain))
msg_warn("list domain %s in only one of $%s and $%s",
- domain, VAR_MYDEST, VAR_VIRTUAL_MAPS);
- if (*var_virt_mailbox_maps
- && checkv8_maps_find(state, reply_name, virt_mailbox_maps, domain))
+ domain, VAR_MYDEST, VAR_VIRT_ALIAS_DOMS);
+ if (*var_virt_mailbox_doms
+ && check_str_match(state, reply_name, virt_mailbox_doms, domain))
msg_warn("list domain %s in only one of $%s and $%s",
- domain, VAR_MYDEST, VAR_VIRT_MAILBOX_MAPS);
+ domain, VAR_MYDEST, VAR_VIRT_MAILBOX_DOMS);
return (1);
}
/* If Postfix-style virtual domain. */
- if (*var_virtual_maps
- && check_maps_find(state, reply_name, virtual_maps, domain, 0))
+ if (*var_virt_alias_doms
+ && check_str_match(state, reply_name, virt_alias_doms, domain))
return (1);
/* If virtual mailbox domain. */
- if (*var_virt_mailbox_maps
- && checkv8_maps_find(state, reply_name, virt_mailbox_maps, domain))
+ if (*var_virt_mailbox_doms
+ && check_str_match(state, reply_name, virt_mailbox_doms, domain))
return (1);
return (0);
/*
* Permit final delivery: the destination matches mydestination,
- * virtual_maps, or virtual_mailbox_maps.
+ * virtual_alias_domains, or virtual_mailbox_domains.
*/
if (resolve_final(state, recipient, domain))
return (SMTPD_CHECK_OK);
reply_name, reply_class, cmd_text);
log_whatsup(state, "filter", STR(error_text));
#ifndef TEST
- rec_fprintf(state->dest->stream, REC_TYPE_FILT, "%s", value);
+ rec_fprintf(state->dest->stream, REC_TYPE_FILT, "%s", cmd_text);
#endif
return (SMTPD_CHECK_DUNNO);
}
/*
* Reject mail to unknown addresses in Postfix-style virtual domains.
*/
- if (*var_virtual_maps
- && (check_maps_find(state, recipient, virtual_maps, domain, 0))) {
+ if (*var_virt_alias_doms
+ && (check_str_match(state, recipient, virt_alias_doms, domain))) {
if (NOMATCH(rcpt_canon_maps, CONST_STR(reply->recipient))
&& NOMATCH(canonical_maps, CONST_STR(reply->recipient))
&& NOMATCH(relocated_maps, CONST_STR(reply->recipient))
&& NOMATCHV8(virt_mailbox_maps, CONST_STR(reply->recipient))
- && NOMATCH(virtual_maps, CONST_STR(reply->recipient))) {
+ && NOMATCH(virt_alias_maps, CONST_STR(reply->recipient))) {
(void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
"%d <%s>: User unknown", 550, recipient);
SMTPD_CHECK_RCPT_RETURN(STR(error_text));
/*
* Reject mail to unknown addresses in Postfix-style virtual domains.
*/
- if (*var_virt_mailbox_maps
- && (check_maps_find(state, recipient, virt_mailbox_maps, domain, 0))) {
+ if (*var_virt_mailbox_doms
+ && (check_str_match(state, recipient, virt_mailbox_doms, domain))) {
if (NOMATCH(rcpt_canon_maps, CONST_STR(reply->recipient))
&& NOMATCH(canonical_maps, CONST_STR(reply->recipient))
&& NOMATCH(relocated_maps, CONST_STR(reply->recipient))
&& NOMATCHV8(virt_mailbox_maps, CONST_STR(reply->recipient))
- && NOMATCH(virtual_maps, CONST_STR(reply->recipient))) {
+ && NOMATCH(virt_alias_maps, CONST_STR(reply->recipient))) {
(void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
"%d <%s>: User unknown", 550, recipient);
SMTPD_CHECK_RCPT_RETURN(STR(error_text));
&& NOMATCH(canonical_maps, CONST_STR(reply->recipient))
&& NOMATCH(relocated_maps, CONST_STR(reply->recipient))
&& NOMATCHV8(virt_mailbox_maps, CONST_STR(reply->recipient))
- && NOMATCH(virtual_maps, CONST_STR(reply->recipient))
+ && NOMATCH(virt_alias_maps, CONST_STR(reply->recipient))
&& NOMATCH(local_rcpt_maps, CONST_STR(reply->recipient))) {
(void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE,
"%d <%s>: User unknown", 550, recipient);
char *var_alias_maps;
char *var_rcpt_canon_maps;
char *var_canonical_maps;
-char *var_virtual_maps;
+char *var_virt_alias_maps;
+char *var_virt_alias_doms;
char *var_virt_mailbox_maps;
+char *var_virt_mailbox_doms;
char *var_relocated_maps;
char *var_local_rcpt_maps;
char *var_perm_mx_networks;
VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps,
VAR_RCPT_CANON_MAPS, DEF_RCPT_CANON_MAPS, &var_rcpt_canon_maps,
VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps,
- VAR_VIRTUAL_MAPS, DEF_VIRTUAL_MAPS, &var_virtual_maps,
+ VAR_VIRT_ALIAS_MAPS, DEF_VIRT_ALIAS_MAPS, &var_virt_alias_maps,
+ VAR_VIRT_ALIAS_DOMS, DEF_VIRT_ALIAS_DOMS, &var_virt_alias_doms,
VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_virt_mailbox_maps,
+ VAR_VIRT_MAILBOX_DOMS, DEF_VIRT_MAILBOX_DOMS, &var_virt_mailbox_doms,
VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps,
VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps,
VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks,
STRING_TABLE *sp;
for (sp = string_table; sp->name; sp++)
- sp->target[0] = mystrdup(sp->defval);
+ sp->target[0] = mystrdup(sp->defval[0] == '$' ? "" : sp->defval);
}
/* string_update - update string parameter */
#define UPDATE_MAPS(ptr, var, val, lock) \
{ if (ptr) maps_free(ptr); ptr = maps_create(var, val, lock); }
+#define UPDATE_LIST(ptr, val) \
+ { if (ptr) string_list_free(ptr); \
+ ptr = string_list_init(MATCH_FLAG_NONE, val); }
+
case 2:
- if (strcasecmp(args->argv[0], "virtual_maps") == 0) {
- UPDATE_STRING(var_virtual_maps, args->argv[1]);
- UPDATE_MAPS(virtual_maps, VAR_VIRTUAL_MAPS,
- var_virtual_maps, DICT_FLAG_LOCK);
+ if (strcasecmp(args->argv[0], VAR_VIRT_ALIAS_MAPS) == 0) {
+ UPDATE_STRING(var_virt_alias_maps, args->argv[1]);
+ UPDATE_MAPS(virt_alias_maps, VAR_VIRT_ALIAS_MAPS,
+ var_virt_alias_maps, DICT_FLAG_LOCK);
+ resp = 0;
+ break;
+ }
+ if (strcasecmp(args->argv[0], VAR_VIRT_ALIAS_DOMS) == 0) {
+ UPDATE_STRING(var_virt_alias_doms, args->argv[1]);
+ UPDATE_LIST(virt_alias_doms, var_virt_alias_doms);
resp = 0;
break;
}
resp = 0;
break;
}
+ if (strcasecmp(args->argv[0], VAR_VIRT_MAILBOX_DOMS) == 0) {
+ UPDATE_STRING(var_virt_mailbox_doms, args->argv[1]);
+ UPDATE_LIST(virt_mailbox_doms, var_virt_mailbox_doms);
+ resp = 0;
+ break;
+ }
if (strcasecmp(args->argv[0], "local_recipient_maps") == 0) {
UPDATE_STRING(var_local_rcpt_maps, args->argv[1]);
UPDATE_MAPS(local_rcpt_maps, VAR_LOCAL_RCPT_MAPS,
recipient_restrictions permit
rcpt no.such.user@[127.0.0.1]
#
-virtual_maps tcp:localhost:100
+virtual_alias_maps tcp:localhost:100
#
recipient_restrictions permit_mx_backup
rcpt wietse@nowhere1.com
#include <vstring_vstream.h>
#include <split_at.h>
#include <valid_hostname.h>
+#include <stringops.h>
/* Global library. */
#include <mail_conf.h>
#include <quote_822_local.h>
#include <tok822.h>
+#include <domain_list.h>
+#include <string_list.h>
+#include <match_parent_style.h>
+#include <maps.h>
+#include <mail_addr_find.h>
/* Application-specific. */
#define STR vstring_str
+static DOMAIN_LIST *relay_domains;
+static STRING_LIST *virt_alias_doms;
+static STRING_LIST *virt_mailbox_doms;
+static MAPS *relocated_maps;
+
/* resolve_addr - resolve address according to rule set */
void resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
TOK822 *saved_domain = 0;
TOK822 *domain = 0;
char *destination;
+ const char *blame;
*flags = 0;
tok822_internalize(nextrcpt, tree, TOK822_STR_DEFL);
/*
- * Non-local delivery, presumably. Set up the default remote transport
- * specified with var_def_transport. Use the destination's mail exchanger
- * unless a default mail relay is specified with var_relayhost.
+ * With relay or other non-local destinations, the relayhost setting
+ * overrides the destination domain name.
+ *
+ * With virtual, relay, or other non-local destinations, give the highest
+ * precedence to delivery transport associated next-hop information.
*/
+ dict_errno = 0;
if (domain != 0) {
- vstring_strcpy(channel, var_def_transport);
+ tok822_internalize(nexthop, domain->next, TOK822_STR_DEFL);
+ lowercase(STR(nexthop));
+ if (STR(nexthop)[strspn(STR(nexthop), "[]0123456789.")] != 0
+ && valid_hostname(STR(nexthop), DONT_GRIPE) == 0)
+ *flags |= RESOLVE_FLAG_ERROR;
+ if (virt_alias_doms
+ && string_list_match(virt_alias_doms, STR(nexthop))) {
+ vstring_strcpy(channel, var_error_transport);
+ vstring_strcpy(nexthop, "unknown user");
+ blame = VAR_ERROR_TRANSPORT;
+ *flags |= RESOLVE_CLASS_ERROR;
+ } 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))) {
+ vstring_strcpy(channel, var_virt_transport);
+ 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;
+ } else {
+ if (relay_domains
+ && domain_list_match(relay_domains, STR(nexthop))) {
+ 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 {
+ vstring_strcpy(channel, var_def_transport);
+ blame = VAR_DEF_TRANSPORT;
+ *flags |= RESOLVE_CLASS_DEFAULT;
+ }
+ if (*var_relayhost)
+ vstring_strcpy(nexthop, var_relayhost);
+ }
if ((destination = split_at(STR(channel), ':')) != 0 && *destination)
vstring_strcpy(nexthop, destination);
- else if (*var_relayhost)
- vstring_strcpy(nexthop, var_relayhost);
- else {
- tok822_internalize(nexthop, domain->next, TOK822_STR_DEFL);
- if (STR(nexthop)[strspn(STR(nexthop), "[]0123456789.")] != 0
- && valid_hostname(STR(nexthop), DONT_GRIPE) == 0)
- *flags |= RESOLVE_FLAG_ERROR;
- }
- if (*STR(channel) == 0)
- msg_fatal("null transport is not allowed: %s = %s",
- VAR_DEF_TRANSPORT, var_def_transport);
}
/*
*/
else {
vstring_strcpy(channel, var_local_transport);
+ blame = VAR_LOCAL_TRANSPORT;
if ((destination = split_at(STR(channel), ':')) == 0
|| *destination == 0)
destination = var_myhostname;
vstring_strcpy(nexthop, destination);
- if (*STR(channel) == 0)
- msg_fatal("null transport is not allowed: %s = %s",
- VAR_LOCAL_TRANSPORT, var_local_transport);
+ *flags |= RESOLVE_CLASS_LOCAL;
}
+
+ /*
+ * Sanity checks.
+ */
+ if (*STR(channel) == 0)
+ msg_fatal("file %s/%s: parameter %s: null transport is not allowed",
+ var_config_dir, MAIN_CONF_FILE, blame);
if (*STR(nexthop) == 0)
msg_panic("%s: null nexthop", myname);
+ /*
+ * Bounce recipients that have moved. We do it here instead of in the
+ * local delivery agent. The benefit is that we can bounce mail for
+ * virtual addresses, not just local addresses only, and that there is no
+ * need to run a local delivery agent just for the sake of relocation
+ * notices. The downside is that this table has no effect on local alias
+ * expansion results, so that mail will have to make almost an entire
+ * iteration through the mail system.
+ */
+#define IGNORE_ADDR_EXTENSION ((char **) 0)
+
+ if ((*flags & RESOLVE_FLAG_FAIL) == 0 && 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_sprintf(nexthop, "user has moved to %s", newloc);
+ *flags |= RESOLVE_CLASS_ERROR;
+ } else if (dict_errno != 0) {
+ msg_warn("%s lookup failure", VAR_RELOCATED_MAPS);
+ *flags |= RESOLVE_FLAG_FAIL;
+ }
+ }
+
/*
* The transport map overrides any transport and next-hop host info that
- * is set up above. For a long time, it was not possible to override
- * routing of mail that resolves locally, because Postfix used a
- * zero-length next-hop hostname result to indicate local delivery, and
- * transport maps cannot return zero-length hostnames.
+ * is set up above.
+ *
+ * XXX Don't override the error transport :-(
*/
- if (*var_transport_maps)
- transport_lookup(STR(nextrcpt), channel, nexthop);
+ if ((*flags & RESOLVE_FLAG_FAIL) == 0
+ && (*flags & RESOLVE_CLASS_ERROR) != 0
+ && *var_transport_maps) {
+ if (transport_lookup(STR(nextrcpt), channel, nexthop) == 0
+ && dict_errno != 0) {
+ msg_warn("%s lookup failure", VAR_TRANSPORT_MAPS);
+ *flags |= RESOLVE_FLAG_FAIL;
+ }
+ }
/*
* Clean up.
channel = vstring_alloc(100);
nexthop = vstring_alloc(100);
nextrcpt = vstring_alloc(100);
+
+ if (*var_virt_alias_doms)
+ virt_alias_doms =
+ string_list_init(MATCH_FLAG_NONE, var_virt_alias_doms);
+
+ if (*var_virt_mailbox_doms)
+ virt_mailbox_doms =
+ string_list_init(MATCH_FLAG_NONE, var_virt_mailbox_doms);
+
+ if (*var_relay_domains)
+ relay_domains =
+ domain_list_init(match_parent_style(VAR_RELAY_DOMAINS),
+ var_relay_domains);
+
+ if (*var_relocated_maps)
+ relocated_maps =
+ maps_create(VAR_RELOCATED_MAPS, var_relocated_maps,
+ DICT_FLAG_LOCK);
}
/* This information is used to determine if
/* \fIuser\fR@[\fInet.work.addr.ess\fR] is local or remote.
/* .IP \fBmydestination\fR
-/* List of domains that this machine considers local.
-/* .IP \fBmyorigin\fR
-/* The domain that locally-posted mail appears to come from.
+/* List of domains that are given to the \fB$local_transport\fR.
+/* .IP \fBvirtual_alias_domains\fT
+/* List of simulated virtual domains (domains with all recipients
+/* aliased to some other local or remote domain).
+/* .IP \fBvirtual_mailbox_domains\fT
+/* List of domains that are given to the \fB$virtual_transport\fR.
+/* .IP \fBrelay_domains\fT
+/* List of domains that are given to the \fB$relay_transport\fR.
/* .IP \fBresolve_unquoted_address\fR
/* When resolving an address, do not quote the address localpart as
/* per RFC 822, so that additional \fB@\fR, \fB%\fR or \fB!\fR
/* characters remain visible. This is technically incorrect, but
/* allows us to stop relay attacks when forwarding mail to a Sendmail
/* primary MX host.
+/* .IP \fBrelocated_maps\fR
+/* Tables with contact information for users, hosts or domains
+/* that no longer exist. See \fBrelocated\fR(5).
/* .SH Rewriting
/* .ad
/* .fi
+/* .IP \fBmyorigin\fR
+/* The domain that locally-posted mail appears to come from.
/* .IP \fBallow_percent_hack\fR
/* Rewrite \fIuser\fR%\fIdomain\fR to \fIuser\fR@\fIdomain\fR.
/* .IP \fBappend_at_myorigin\fR
-/* Rewrite \fIuser\fR to \fIuser\fR@$\fBmyorigin\fR.
+/* Rewrite \fIuser\fR to \fIuser\fR@\fB$myorigin\fR.
/* .IP \fBappend_dot_mydomain\fR
-/* Rewrite \fIuser\fR@\fIhost\fR to \fIuser\fR@\fIhost\fR.$\fBmydomain\fR.
+/* Rewrite \fIuser\fR@\fIhost\fR to \fIuser\fR@\fIhost\fR.\fB$mydomain\fR.
/* .IP \fBswap_bangpath\fR
/* Rewrite \fIsite\fR!\fIuser\fR to \fIuser\fR@\fIsite\fR.
/* .SH Routing
/* .ad
/* .fi
/* .IP \fBlocal_transport\fR
-/* Where to deliver mail for destinations that match $\fBmydestination\fR
-/* or $\fBinet_interfaces\fR.
+/* Where to deliver mail for destinations that match \fB$mydestination\fR
+/* or \fB$inet_interfaces\fR.
/* 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.
+/* The default transport is \fBvirtual\fR.
+/* .sp
+/* Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
+/* for details. The :\fInexthop\fR part is optional.
+/* .IP \fBrelay_transport\fR
+/* Where to deliver mail for non-local domains that match
+/* \fB$relay_domains\fR.
+/* The default transport is \fBrelay\fR (which normally is a clone
+/* of the \fBsmtp\fR transport).
+/* .sp
+/* Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
+/* for details. The :\fInexthop\fR part is optional.
/* .IP \fBdefault_transport\fR
-/* Where to deliver non-local mail when no information is explicitly
-/* given in the \fBtransport\fR(5) table.
+/* Where to deliver all other non-local mail.
/* The default transport is \fBsmtp\fR.
/* .sp
/* Syntax is \fItransport\fR:\fInexthop\fR; see \fBtransport\fR(5)
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;
+char *var_virt_mailbox_doms;
+char *var_relocated_maps;
/* rewrite_service - read request and send reply */
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, 0, 0,
+ VAR_ERROR_TRANSPORT, DEF_ERROR_TRANSPORT, &var_error_transport, 0, 0,
+ VAR_VIRT_TRANSPORT, DEF_VIRT_TRANSPORT, &var_virt_transport, 0, 0,
+ VAR_RELAY_TRANSPORT, DEF_RELAY_TRANSPORT, &var_relay_transport, 0, 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,
+ VAR_VIRT_MAILBOX_DOMS, DEF_VIRT_MAILBOX_DOMS, &var_virt_mailbox_doms, 0, 0,
+ VAR_VIRT_TRANSPORT, DEF_VIRT_TRANSPORT, &var_virt_transport, 1, 0,
+ VAR_RELAY_TRANSPORT, DEF_RELAY_TRANSPORT, &var_relay_transport, 1, 0,
+ VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, 0, 0,
0,
};
static CONFIG_BOOL_TABLE bool_table[] = {
extern DICT *dict_debug(DICT *);
#define DICT_DEBUG(d) ((d)->flags & DICT_FLAG_DEBUG ? dict_debug(d) : (d))
+#define DICT_FLAG_NONE (0)
#define DICT_FLAG_DUP_WARN (1<<0) /* if file, warn about dups */
#define DICT_FLAG_DUP_IGNORE (1<<1) /* if file, ignore dups */
#define DICT_FLAG_TRY0NULL (1<<2) /* do not append 0 to key/value */
#define DICT_FLAG_SYNC_UPDATE (1<<8) /* if file, sync updates */
#define DICT_FLAG_DEBUG (1<<9) /* log access */
#define DICT_FLAG_FOLD_KEY (1<<10) /* lowercase the lookup key */
+#define DICT_FLAG_NO_REGSUB (1<<11) /* no lhs->rhs regexp substitution */
extern int dict_unknown_allowed;
extern int dict_errno;
/* .IP DICT_FLAG_SYNC_UPDATE
/* With file-based maps, flush I/O buffers to file after each update.
/* Thus feature is not supported with some file-based dictionaries.
-/* .IP DICT_FLAG_FOLD_KEY
-/* Fold the lookup key to lower case.
+/* .IP DICT_FLAG_NO_REGSUB
+/* Disallow regular expression substitution from left-hand side data
+/* into the right-hand side.
/* .PP
+/* Specify DICT_FLAG_NONE for no special processing.
+/*
/* The dictionary types are as follows:
/* .IP environ
/* The process environment array. The \fIdict_name\fR argument is ignored.
typedef struct {
const char *mapname; /* name of regexp map */
int lineno; /* where in file */
+ int flags; /* dict_flags */
} DICT_PCRE_PRESCAN_CONTEXT;
/*
size_t n;
if (type == MAC_PARSE_VARNAME) {
+ if (ctxt->flags & DICT_FLAG_NO_REGSUB) {
+ msg_warn("pcre map %s, line %d: "
+ "regular expression substitution is not allowed"
+ ctxt->mapname, ctxt->lineno);
+ return (MAC_PARSE_ERROR);
+ }
+
if (!alldig(vstring_str(buf))) {
msg_warn("pcre map %s, line %d: non-numeric replacement index \"%s\"",
ctxt->mapname, ctxt->lineno, vstring_str(buf));
/* dict_pcre_parse_rule - parse and compile one rule */
static DICT_PCRE_RULE *dict_pcre_parse_rule(const char *mapname, int lineno,
- char *line, int nesting)
+ char *line, int nesting,
+ int dict_flags)
{
char *p;
*/
prescan_context.mapname = mapname;
prescan_context.lineno = lineno;
+ prescan_context.flags = dict_flags;
if (mac_parse(p, dict_pcre_prescan, (char *) &prescan_context)
& MAC_PARSE_ERROR) {
trimblanks(p, 0)[0] = 0; /* Trim space at end */
if (*p == 0)
continue;
- rule = dict_pcre_parse_rule(mapname, lineno, p, nesting);
+ rule = dict_pcre_parse_rule(mapname, lineno, p, nesting, dict_flags);
if (rule == 0)
continue;
if (rule->op == DICT_PCRE_OP_IF) {
/* dict_regexp_parseline - parse one rule */
static DICT_REGEXP_RULE *dict_regexp_parseline(const char *mapname, int lineno,
- char *line, int nesting)
+ char *line, int nesting,
+ int dict_flags)
{
char *p;
#define FREE_EXPR_AND_RETURN(expr, rval) \
{ regfree(expr); myfree((char *) (expr)); return (rval); }
- if (prescan_context.max_sub == 0 || first_pat.match == 0)
+ if (prescan_context.max_sub == 0 || first_pat.match == 0) {
first_pat.options |= REG_NOSUB;
+ } else if (dict_flags & DICT_FLAG_NO_REGSUB) {
+ msg_warn("regexp map %s, line %d: "
+ "regular expression substitution is not allowed: "
+ "skipping this rule", mapname, lineno);
+ return(0);
+ }
if ((first_exp = dict_regexp_compile_pat(mapname, lineno,
&first_pat)) == 0)
return (0);
trimblanks(p, 0)[0] = 0;
if (*p == 0)
continue;
- rule = dict_regexp_parseline(mapname, lineno, p, nesting);
+ rule = dict_regexp_parseline(mapname, lineno, p, nesting, dict_flags);
if (rule == 0)
continue;
if (rule->op == DICT_REGEXP_OP_MATCH) {
virtual.o: ../../include/deliver_completed.h
virtual.o: ../../include/mail_params.h
virtual.o: ../../include/mail_conf.h
+virtual.o: ../../include/virtual8.h
+virtual.o: ../../include/maps.h
virtual.o: ../../include/mail_server.h
virtual.o: virtual.h
-virtual.o: ../../include/maps.h
virtual.o: ../../include/mbox_conf.h
/*
/* Note that \fBvirtual_mailbox_base\fR is unconditionally prepended
/* to this path.
+/* .IP \fBvirtual_mailbox_domains\fR
+/* The list of domains that should be delivered via the Postfix virtual
+/* delivery agent. This uses the same syntax as the \fBmydestination\fR
+/* configuration parameter.
/* .IP \fBvirtual_minimum_uid\fR
/* Specifies a minimum uid that will be accepted as a return from
/* a \fBvirtual_owner_maps\fR or \fBvirtual_uid_maps\fR lookup.
#include <sys_defs.h>
#include <stdlib.h>
+#ifdef USE_PATHS_H
+#include <paths.h> /* XXX mail_spool_dir dependency */
+#endif
/* Utility library. */
#include <mail_params.h>
#include <mail_conf.h>
#include <mail_params.h>
+#include <virtual8.h>
/* Single server skeleton. */
char *var_virt_mailbox_base;
char *var_virt_mailbox_lock;
int var_virt_mailbox_limit;
+char *var_mail_spool_dir; /* XXX dependency fix */
/*
* Mappings.
set_eugid(var_owner_uid, var_owner_gid);
virtual_mailbox_maps =
- maps_create(VAR_VIRT_MAILBOX_MAPS, var_virt_mailbox_maps,
- DICT_FLAG_LOCK);
+ virtual8_maps_create(VAR_VIRT_MAILBOX_MAPS, var_virt_mailbox_maps,
+ DICT_FLAG_LOCK);
virtual_uid_maps =
- maps_create(VAR_VIRT_UID_MAPS, var_virt_uid_maps, DICT_FLAG_LOCK);
+ virtual8_maps_create(VAR_VIRT_UID_MAPS, var_virt_uid_maps,
+ DICT_FLAG_LOCK);
virtual_gid_maps =
- maps_create(VAR_VIRT_GID_MAPS, var_virt_gid_maps, DICT_FLAG_LOCK);
+ virtual8_maps_create(VAR_VIRT_GID_MAPS, var_virt_gid_maps,
+ DICT_FLAG_LOCK);
virtual_mbox_lock_mask = mbox_lock_mask(var_virt_mailbox_lock);
}
0,
};
static CONFIG_STR_TABLE str_table[] = {
+ VAR_MAIL_SPOOL_DIR, DEF_MAIL_SPOOL_DIR, &var_mail_spool_dir, 0, 0,
VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_virt_mailbox_maps, 0, 0,
VAR_VIRT_UID_MAPS, DEF_VIRT_UID_MAPS, &var_virt_uid_maps, 0, 0,
VAR_VIRT_GID_MAPS, DEF_VIRT_GID_MAPS, &var_virt_gid_maps, 0, 0,