summaryrefslogtreecommitdiffstats
path: root/conf
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 01:46:30 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 01:46:30 +0000
commitb5896ba9f6047e7031e2bdee0622d543e11a6734 (patch)
treefd7b460593a2fee1be579bec5697e6d887ea3421 /conf
parentInitial commit. (diff)
downloadpostfix-2f07919848e7bd4a084699d26e8821e3a00696d9.tar.xz
postfix-2f07919848e7bd4a084699d26e8821e3a00696d9.zip
Adding upstream version 3.4.23.upstream/3.4.23upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
l---------conf/LICENSE1
l---------conf/TLS_LICENSE1
-rw-r--r--conf/access493
-rw-r--r--conf/aliases264
-rw-r--r--conf/canonical307
-rw-r--r--conf/dynamicmaps.cf9
-rw-r--r--conf/generic250
-rw-r--r--conf/header_checks549
-rw-r--r--conf/main.cf676
-rw-r--r--conf/master.cf133
-rw-r--r--conf/post-install925
-rw-r--r--conf/postfix-files459
-rwxr-xr-xconf/postfix-script446
-rw-r--r--conf/postfix-tls-script1154
-rw-r--r--conf/postfix-wrapper224
-rw-r--r--conf/postmulti-script312
-rw-r--r--conf/relocated176
-rw-r--r--conf/transport299
-rw-r--r--conf/virtual324
19 files changed, 7002 insertions, 0 deletions
diff --git a/conf/LICENSE b/conf/LICENSE
new file mode 120000
index 0000000..ea5b606
--- /dev/null
+++ b/conf/LICENSE
@@ -0,0 +1 @@
+../LICENSE \ No newline at end of file
diff --git a/conf/TLS_LICENSE b/conf/TLS_LICENSE
new file mode 120000
index 0000000..ff36e26
--- /dev/null
+++ b/conf/TLS_LICENSE
@@ -0,0 +1 @@
+../TLS_LICENSE \ No newline at end of file
diff --git a/conf/access b/conf/access
new file mode 100644
index 0000000..9d67b94
--- /dev/null
+++ b/conf/access
@@ -0,0 +1,493 @@
+# ACCESS(5) ACCESS(5)
+#
+# NAME
+# access - Postfix SMTP server access table
+#
+# SYNOPSIS
+# postmap /etc/postfix/access
+#
+# postmap -q "string" /etc/postfix/access
+#
+# postmap -q - /etc/postfix/access <inputfile
+#
+# DESCRIPTION
+# This document describes access control on remote SMTP
+# client information: host names, network addresses, and
+# envelope sender or recipient addresses; it is implemented
+# by the Postfix SMTP server. See header_checks(5) or
+# body_checks(5) for access control on the content of email
+# messages.
+#
+# Normally, the access(5) 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/access" to rebuild an indexed file
+# after changing the corresponding text file.
+#
+# When the table is provided via other means such as NIS,
+# LDAP or SQL, the same lookups are done as for ordinary
+# indexed files.
+#
+# Alternatively, the table can be provided as a regu-
+# lar-expression map where patterns are given as regular
+# expressions, or lookups can be directed to TCP-based
+# server. In those cases, the lookups are done in a slightly
+# different way as described below under "REGULAR EXPRESSION
+# TABLES" or "TCP-BASED TABLES".
+#
+# CASE FOLDING
+# The search string is folded to lowercase before database
+# lookup. As of Postfix 2.3, the search string is not case
+# folded with database types such as regexp: or pcre: whose
+# lookup fields can match both upper and lower case.
+#
+# TABLE FORMAT
+# The input format for the postmap(1) command is as follows:
+#
+# pattern action
+# When pattern matches a mail address, domain or host
+# address, perform the corresponding action.
+#
+# blank lines and comments
+# Empty lines and whitespace-only lines are ignored,
+# as are lines whose first non-whitespace character
+# is a `#'.
+#
+# multi-line text
+# A logical line starts with non-whitespace text. A
+# line that starts with whitespace continues a logi-
+# cal line.
+#
+# EMAIL ADDRESS PATTERNS
+# With lookups from indexed files such as DB or DBM, or from
+# networked tables such as NIS, LDAP or SQL, patterns are
+# tried in the order as listed below:
+#
+# user@domain
+# Matches the specified mail address.
+#
+# domain.tld
+# Matches domain.tld as the domain part of an email
+# address.
+#
+# The pattern domain.tld also matches subdomains, but
+# only when the string smtpd_access_maps is listed in
+# the Postfix parent_domain_matches_subdomains con-
+# figuration setting.
+#
+# .domain.tld
+# Matches subdomains of domain.tld, but only when the
+# string smtpd_access_maps is not listed in the Post-
+# fix parent_domain_matches_subdomains configuration
+# setting.
+#
+# user@ Matches all mail addresses with the specified user
+# part.
+#
+# Note: lookup of the null sender address is not possible
+# with some types of lookup table. By default, Postfix uses
+# <> as the lookup key for such addresses. The value is
+# specified with the smtpd_null_access_lookup_key parameter
+# in the Postfix main.cf file.
+#
+# EMAIL ADDRESS EXTENSION
+# When a mail address localpart contains the optional recip-
+# ient delimiter (e.g., user+foo@domain), the lookup order
+# becomes: user+foo@domain, user@domain, domain, user+foo@,
+# and user@.
+#
+# HOST NAME/ADDRESS PATTERNS
+# With lookups from indexed files such as DB or DBM, or from
+# networked tables such as NIS, LDAP or SQL, the following
+# lookup patterns are examined in the order as listed:
+#
+# domain.tld
+# Matches domain.tld.
+#
+# The pattern domain.tld also matches subdomains, but
+# only when the string smtpd_access_maps is listed in
+# the Postfix parent_domain_matches_subdomains con-
+# figuration setting.
+#
+# .domain.tld
+# Matches subdomains of domain.tld, but only when the
+# string smtpd_access_maps is not listed in the Post-
+# fix parent_domain_matches_subdomains configuration
+# setting.
+#
+# net.work.addr.ess
+#
+# net.work.addr
+#
+# net.work
+#
+# net Matches the specified IPv4 host address or subnet-
+# work. An IPv4 host address is a sequence of four
+# decimal octets separated by ".".
+#
+# Subnetworks are matched by repeatedly truncating
+# the last ".octet" from the remote IPv4 host address
+# string until a match is found in the access table,
+# or until further truncation is not possible.
+#
+# NOTE 1: The access map lookup key must be in canon-
+# ical form: do not specify unnecessary null charac-
+# ters, and do not enclose network address informa-
+# tion with "[]" characters.
+#
+# NOTE 2: use the cidr lookup table type to specify
+# network/netmask patterns. See cidr_table(5) for
+# details.
+#
+# net:work:addr:ess
+#
+# net:work:addr
+#
+# net:work
+#
+# net Matches the specified IPv6 host address or subnet-
+# work. An IPv6 host address is a sequence of three
+# to eight hexadecimal octet pairs separated by ":".
+#
+# Subnetworks are matched by repeatedly truncating
+# the last ":octetpair" from the remote IPv6 host
+# address string until a match is found in the access
+# table, or until further truncation is not possible.
+#
+# NOTE 1: the truncation and comparison are done with
+# the string representation of the IPv6 host address.
+# Thus, not all the ":" subnetworks will be tried.
+#
+# NOTE 2: The access map lookup key must be in canon-
+# ical form: do not specify unnecessary null charac-
+# ters, and do not enclose network address informa-
+# tion with "[]" characters.
+#
+# NOTE 3: use the cidr lookup table type to specify
+# network/netmask patterns. See cidr_table(5) for
+# details.
+#
+# IPv6 support is available in Postfix 2.2 and later.
+#
+# ACCEPT ACTIONS
+# OK Accept the address etc. that matches the pattern.
+#
+# all-numerical
+# An all-numerical result is treated as OK. This for-
+# mat is generated by address-based relay authoriza-
+# tion schemes such as pop-before-smtp.
+#
+# For other accept actions, see "OTHER ACTIONS" below.
+#
+# REJECT ACTIONS
+# Postfix version 2.3 and later support enhanced status
+# codes as defined in RFC 3463. When no code is specified
+# at the beginning of the text below, Postfix inserts a
+# default enhanced status code of "5.7.1" in the case of
+# reject actions, and "4.7.1" in the case of defer actions.
+# See "ENHANCED STATUS CODES" below.
+#
+# 4NN text
+#
+# 5NN text
+# Reject the address etc. that matches the pattern,
+# and respond with the numerical three-digit code and
+# text. 4NN means "try again later", while 5NN means
+# "do not try again".
+#
+# The following responses have special meaning for
+# the Postfix SMTP server:
+#
+# 421 text (Postfix 2.3 and later)
+#
+# 521 text (Postfix 2.6 and later)
+# After responding with the numerical
+# three-digit code and text, disconnect imme-
+# diately from the SMTP client. This frees up
+# SMTP server resources so that they can be
+# made available to another SMTP client.
+#
+# Note: The "521" response should be used only
+# with botnets and other malware where inter-
+# operability is of no concern. The "send 521
+# and disconnect" behavior is NOT defined in
+# the SMTP standard.
+#
+# REJECT optional text...
+# Reject the address etc. that matches the pattern.
+# Reply with "$access_map_reject_code optional
+# text..." when the optional text is specified, oth-
+# erwise reply with a generic error response message.
+#
+# DEFER optional text...
+# Reject the address etc. that matches the pattern.
+# Reply with "$access_map_defer_code optional
+# text..." when the optional text is specified, oth-
+# erwise reply with a generic error response message.
+#
+# This feature is available in Postfix 2.6 and later.
+#
+# DEFER_IF_REJECT optional text...
+# Defer the request if some later restriction would
+# result in a REJECT action. Reply with
+# "$access_map_defer_code 4.7.1 optional text..."
+# when the optional text is specified, otherwise
+# reply with a generic error response message.
+#
+# Prior to Postfix 2.6, the SMTP reply code is 450.
+#
+# This feature is available in Postfix 2.1 and later.
+#
+# DEFER_IF_PERMIT optional text...
+# Defer the request if some later restriction would
+# result in a an explicit or implicit PERMIT action.
+# Reply with "$access_map_defer_code 4.7.1 optional
+# text..." when the optional text is specified, oth-
+# erwise reply with a generic error response message.
+#
+# Prior to Postfix 2.6, the SMTP reply code is 450.
+#
+# This feature is available in Postfix 2.1 and later.
+#
+# For other reject actions, see "OTHER ACTIONS" below.
+#
+# OTHER ACTIONS
+# restriction...
+# Apply the named UCE restriction(s) (permit, reject,
+# reject_unauth_destination, and so on).
+#
+# BCC user@domain
+# Send one copy of the message to the specified
+# recipient.
+#
+# If multiple BCC actions are specified within the
+# same SMTP MAIL transaction, with Postfix 3.0 only
+# the last action will be used.
+#
+# This feature is available in Postfix 3.0 and later.
+#
+# DISCARD optional text...
+# Claim successful delivery and silently discard the
+# message. Log the optional text if specified, oth-
+# erwise log a generic message.
+#
+# Note: this action currently affects all recipients
+# of the message. To discard only one recipient
+# without discarding the entire message, use the
+# transport(5) table to direct mail to the discard(8)
+# service.
+#
+# This feature is available in Postfix 2.0 and later.
+#
+# DUNNO Pretend that the lookup key was not found. This
+# prevents Postfix from trying substrings of the
+# lookup key (such as a subdomain name, or a network
+# address subnetwork).
+#
+# This feature is available in Postfix 2.0 and later.
+#
+# FILTER transport:destination
+# After the message is queued, send the entire mes-
+# sage through the specified external content filter.
+# The transport name specifies the first field of a
+# mail delivery agent definition in master.cf; the
+# syntax of the next-hop destination is described in
+# the manual page of the corresponding delivery
+# agent. More information about external content
+# filters is in the Postfix FILTER_README file.
+#
+# Note 1: do not use $number regular expression sub-
+# stitutions for transport or destination unless you
+# know that the information has a trusted origin.
+#
+# Note 2: this action overrides the main.cf con-
+# tent_filter setting, and affects all recipients of
+# the message. In the case that multiple FILTER
+# actions fire, only the last one is executed.
+#
+# Note 3: the purpose of the FILTER command is to
+# override message routing. To override the recipi-
+# ent's transport but not the next-hop destination,
+# specify an empty filter destination (Postfix 2.7
+# and later), or specify a transport:destination that
+# delivers through a different Postfix instance
+# (Postfix 2.6 and earlier). Other options are using
+# the recipient-dependent transport_maps or the sen-
+# der-dependent sender_dependent_default_transport-
+# _maps features.
+#
+# This feature is available in Postfix 2.0 and later.
+#
+# HOLD optional text...
+# Place the message on the hold queue, where it will
+# sit until someone either deletes it or releases it
+# for delivery. Log the optional text if specified,
+# otherwise log a generic message.
+#
+# Mail that is placed on hold can be examined with
+# the postcat(1) command, and can be destroyed or
+# released with the postsuper(1) command.
+#
+# Note: use "postsuper -r" to release mail that was
+# kept on hold for a significant fraction of $maxi-
+# mal_queue_lifetime or $bounce_queue_lifetime, or
+# longer. Use "postsuper -H" only for mail that will
+# not expire within a few delivery attempts.
+#
+# Note: this action currently affects all recipients
+# of the message.
+#
+# This feature is available in Postfix 2.0 and later.
+#
+# PREPEND headername: headervalue
+# Prepend the specified message header to the mes-
+# sage. When more than one PREPEND action executes,
+# the first prepended header appears before the sec-
+# ond etc. prepended header.
+#
+# Note: this action must execute before the message
+# content is received; it cannot execute in the con-
+# text of smtpd_end_of_data_restrictions.
+#
+# This feature is available in Postfix 2.1 and later.
+#
+# REDIRECT user@domain
+# After the message is queued, send the message to
+# the specified address instead of the intended
+# recipient(s). When multiple REDIRECT actions fire,
+# only the last one takes effect.
+#
+# Note: this action overrides the FILTER action, and
+# currently overrides all recipients of the message.
+#
+# This feature is available in Postfix 2.1 and later.
+#
+# INFO optional text...
+# Log an informational record with the optional text,
+# together with client information and if available,
+# with helo, sender, recipient and protocol informa-
+# tion.
+#
+# This feature is available in Postfix 3.0 and later.
+#
+# WARN optional text...
+# Log a warning with the optional text, together with
+# client information and if available, with helo,
+# sender, recipient and protocol information.
+#
+# This feature is available in Postfix 2.1 and later.
+#
+# ENHANCED STATUS CODES
+# Postfix version 2.3 and later support enhanced status
+# codes as defined in RFC 3463. When an enhanced status
+# code is specified in an access table, it is subject to
+# modification. The following transformations are needed
+# when the same access table is used for client, helo,
+# sender, or recipient access restrictions; they happen
+# regardless of whether Postfix replies to a MAIL FROM, RCPT
+# TO or other SMTP command.
+#
+# o When a sender address matches a REJECT action, the
+# Postfix SMTP server will transform a recipient DSN
+# status (e.g., 4.1.1-4.1.6) into the corresponding
+# sender DSN status, and vice versa.
+#
+# o When non-address information matches a REJECT
+# action (such as the HELO command argument or the
+# client hostname/address), the Postfix SMTP server
+# will transform a sender or recipient DSN status
+# into a generic non-address DSN status (e.g.,
+# 4.0.0).
+#
+# REGULAR EXPRESSION TABLES
+# This section describes how the table lookups change when
+# the table is given in the form of regular expressions. For
+# a description of regular expression lookup table syntax,
+# see regexp_table(5) or pcre_table(5).
+#
+# Each pattern is a regular expression that is applied to
+# the entire string being looked up. Depending on the appli-
+# cation, that string is an entire client hostname, an
+# entire client IP address, or an entire mail address. Thus,
+# no parent domain or parent network search is done,
+# user@domain mail addresses are not broken up into their
+# user@ and domain constituent parts, nor is user+foo broken
+# up into user and foo.
+#
+# Patterns are applied in the order as specified in the ta-
+# ble, until a pattern is found that matches the search
+# string.
+#
+# Actions are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from
+# the pattern can be interpolated as $1, $2 and so on.
+#
+# TCP-BASED TABLES
+# This section describes how the table lookups change when
+# lookups are directed to a TCP-based server. For a descrip-
+# tion of the TCP client/server lookup protocol, see tcp_ta-
+# ble(5). This feature is not available up to and including
+# Postfix version 2.4.
+#
+# Each lookup operation uses the entire query string once.
+# Depending on the application, that string is an entire
+# client hostname, an entire client IP address, or an entire
+# mail address. Thus, no parent domain or parent network
+# search is done, user@domain mail addresses are not broken
+# up into their user@ and domain constituent parts, nor is
+# user+foo broken up into user and foo.
+#
+# Actions are the same as with indexed file lookups.
+#
+# EXAMPLE
+# The following example uses an indexed file, so that the
+# order of table entries does not matter. The example per-
+# mits access by the client at address 1.2.3.4 but rejects
+# all other clients in 1.2.3.0/24. Instead of hash lookup
+# tables, some systems use dbm. Use the command "postconf
+# -m" to find out what lookup tables Postfix supports on
+# your system.
+#
+# /etc/postfix/main.cf:
+# smtpd_client_restrictions =
+# check_client_access hash:/etc/postfix/access
+#
+# /etc/postfix/access:
+# 1.2.3 REJECT
+# 1.2.3.4 OK
+#
+# Execute the command "postmap /etc/postfix/access" after
+# editing the file.
+#
+# BUGS
+# The table format does not understand quoting conventions.
+#
+# SEE ALSO
+# postmap(1), Postfix lookup table manager
+# smtpd(8), SMTP server
+# postconf(5), configuration parameters
+# transport(5), transport:nexthop syntax
+#
+# README FILES
+# Use "postconf readme_directory" or "postconf html_direc-
+# tory" to locate this information.
+# SMTPD_ACCESS_README, built-in SMTP server access control
+# DATABASE_README, Postfix lookup table overview
+#
+# LICENSE
+# The Secure Mailer license must be distributed with this
+# software.
+#
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#
+# ACCESS(5)
diff --git a/conf/aliases b/conf/aliases
new file mode 100644
index 0000000..941551e
--- /dev/null
+++ b/conf/aliases
@@ -0,0 +1,264 @@
+#
+# Sample aliases file. Install in the location as specified by the
+# output from the command "postconf alias_maps". Typical path names
+# are /etc/aliases or /etc/mail/aliases.
+#
+# >>>>>>>>>> The program "newaliases" must be run after
+# >> NOTE >> this file is updated for any changes to
+# >>>>>>>>>> show through to Postfix.
+#
+
+# Person who should get root's mail. Don't receive mail as root!
+#root: you
+
+# Basic system aliases -- these MUST be present
+MAILER-DAEMON: postmaster
+postmaster: root
+
+# General redirections for pseudo accounts
+bin: root
+daemon: root
+named: root
+nobody: root
+uucp: root
+www: root
+ftp-bugs: root
+postfix: root
+
+# Put your local aliases here.
+
+# Well-known aliases
+manager: root
+dumper: root
+operator: root
+abuse: postmaster
+
+# trap decode to catch security attacks
+decode: root
+
+# ALIASES(5) ALIASES(5)
+#
+# NAME
+# aliases - Postfix local alias database format
+#
+# SYNOPSIS
+# newaliases
+#
+# DESCRIPTION
+# The aliases(5) table provides a system-wide mechanism to
+# redirect mail for local recipients. The redirections are
+# processed by the Postfix local(8) delivery agent.
+#
+# Normally, the aliases(5) table is specified as a text file
+# that serves as input to the postalias(1) command. The
+# result, an indexed file in dbm or db format, is used for
+# fast lookup by the mail system. Execute the command
+# newaliases in order to rebuild the indexed file after
+# changing the Postfix alias database.
+#
+# When the table is provided via other means such as NIS,
+# LDAP or SQL, the same lookups are done as for ordinary
+# indexed files.
+#
+# Alternatively, the table can be provided as a regu-
+# lar-expression map where patterns are given as regular
+# expressions. In this case, the lookups are done in a
+# slightly different way as described below under "REGULAR
+# EXPRESSION TABLES".
+#
+# Users can control delivery of their own mail by setting up
+# .forward files in their home directory. Lines in per-user
+# .forward files have the same syntax as the right-hand side
+# of aliases(5) entries.
+#
+# The format of the alias database input file is as follows:
+#
+# o An alias definition has the form
+#
+# name: value1, value2, ...
+#
+# o Empty lines and whitespace-only lines are ignored,
+# as are lines whose first non-whitespace character
+# is a `#'.
+#
+# o A logical line starts with non-whitespace text. A
+# line that starts with whitespace continues a logi-
+# cal line.
+#
+# The name is a local address (no domain part). Use double
+# quotes when the name contains any special characters such
+# as whitespace, `#', `:', or `@'. The name is folded to
+# lowercase, in order to make database lookups case insensi-
+# tive.
+#
+# In addition, when an alias exists for owner-name, this
+# will override the envelope sender address, so that deliv-
+# ery diagnostics are directed to owner-name, instead of the
+# originator of the message (for details, see
+# owner_request_special, expand_owner_alias and
+# reset_owner_alias). This is typically used to direct
+# delivery errors to the maintainer of a mailing list, who
+# is in a better position to deal with mailing list delivery
+# problems than the originator of the undelivered mail.
+#
+# The value contains one or more of the following:
+#
+# address
+# Mail is forwarded to address, which is compatible
+# with the RFC 822 standard.
+#
+# /file/name
+# Mail is appended to /file/name. See local(8) for
+# details of delivery to file. Delivery is not lim-
+# ited to regular files. For example, to dispose of
+# unwanted mail, deflect it to /dev/null.
+#
+# |command
+# Mail is piped into command. Commands that contain
+# special characters, such as whitespace, should be
+# enclosed between double quotes. See local(8) for
+# details of delivery to command.
+#
+# When the command fails, a limited amount of command
+# output is mailed back to the sender. The file
+# /usr/include/sysexits.h defines the expected exit
+# status codes. For example, use "|exit 67" to simu-
+# late a "user unknown" error, and "|exit 0" to
+# implement an expensive black hole.
+#
+# :include:/file/name
+# Mail is sent to the destinations listed in the
+# named file. Lines in :include: files have the same
+# syntax as the right-hand side of alias entries.
+#
+# A destination can be any destination that is
+# described in this manual page. However, delivery to
+# "|command" and /file/name is disallowed by default.
+# To enable, edit the allow_mail_to_commands and
+# allow_mail_to_files configuration parameters.
+#
+# ADDRESS EXTENSION
+# When alias database search fails, and the recipient local-
+# part contains the optional recipient delimiter (e.g.,
+# user+foo), the search is repeated for the unextended
+# address (e.g., user).
+#
+# The propagate_unmatched_extensions parameter controls
+# whether an unmatched address extension (+foo) is propa-
+# gated to the result of table lookup.
+#
+# CASE FOLDING
+# The local(8) delivery agent always folds the search string
+# to lowercase before database lookup.
+#
+# REGULAR EXPRESSION TABLES
+# This section describes how the table lookups change when
+# the table is given in the form of regular expressions. For
+# a description of regular expression lookup table syntax,
+# see regexp_table(5) or pcre_table(5). NOTE: these formats
+# do not use ":" at the end of a pattern.
+#
+# Each regular expression is applied to the entire search
+# string. Thus, a search string user+foo is not broken up
+# into user and foo.
+#
+# Regular expressions are applied in the order as specified
+# in the table, until a regular expression is found that
+# matches the search string.
+#
+# Lookup results are the same as with indexed file lookups.
+# For security reasons there is no support for $1, $2 etc.
+# substring interpolation.
+#
+# SECURITY
+# The local(8) delivery agent disallows regular expression
+# substitution of $1 etc. in alias_maps, because that would
+# open a security hole.
+#
+# The local(8) delivery agent will silently ignore requests
+# to use the proxymap(8) server within alias_maps. Instead
+# it will open the table directly. Before Postfix version
+# 2.2, the local(8) delivery agent will terminate with a
+# fatal error.
+#
+# CONFIGURATION PARAMETERS
+# The following main.cf parameters are especially relevant.
+# The text below provides only a parameter summary. See
+# postconf(5) for more details including examples.
+#
+# alias_database (see 'postconf -d' output)
+# The alias databases for local(8) delivery that are
+# updated with "newaliases" or with "sendmail -bi".
+#
+# alias_maps (see 'postconf -d' output)
+# The alias databases that are used for local(8)
+# delivery.
+#
+# allow_mail_to_commands (alias, forward)
+# Restrict local(8) mail delivery to external com-
+# mands.
+#
+# allow_mail_to_files (alias, forward)
+# Restrict local(8) mail delivery to external files.
+#
+# expand_owner_alias (no)
+# When delivering to an alias "aliasname" that has an
+# "owner-aliasname" companion alias, set the envelope
+# sender address to the expansion of the
+# "owner-aliasname" alias.
+#
+# propagate_unmatched_extensions (canonical, virtual)
+# What address lookup tables copy an address exten-
+# sion from the lookup key to the lookup result.
+#
+# owner_request_special (yes)
+# Enable special treatment for owner-listname entries
+# in the aliases(5) file, and don't split owner-list-
+# name and listname-request address localparts when
+# the recipient_delimiter is set to "-".
+#
+# recipient_delimiter (empty)
+# The set of characters that can separate a user name
+# from its extension (example: user+foo), or a .for-
+# ward file name from its extension (example: .for-
+# ward+foo).
+#
+# Available in Postfix version 2.3 and later:
+#
+# frozen_delivered_to (yes)
+# Update the local(8) delivery agent's idea of the
+# Delivered-To: address (see prepend_deliv-
+# ered_header) only once, at the start of a delivery
+# attempt; do not update the Delivered-To: address
+# while expanding aliases or .forward files.
+#
+# STANDARDS
+# RFC 822 (ARPA Internet Text Messages)
+#
+# SEE ALSO
+# local(8), local delivery agent
+# newaliases(1), create/update alias database
+# postalias(1), create/update alias database
+# postconf(5), configuration parameters
+#
+# README FILES
+# Use "postconf readme_directory" or "postconf html_direc-
+# tory" to locate this information.
+# DATABASE_README, Postfix lookup table overview
+#
+# LICENSE
+# The Secure Mailer license must be distributed with this
+# software.
+#
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#
+# ALIASES(5)
diff --git a/conf/canonical b/conf/canonical
new file mode 100644
index 0000000..9881f4e
--- /dev/null
+++ b/conf/canonical
@@ -0,0 +1,307 @@
+# CANONICAL(5) CANONICAL(5)
+#
+# NAME
+# canonical - Postfix canonical table format
+#
+# SYNOPSIS
+# postmap /etc/postfix/canonical
+#
+# postmap -q "string" /etc/postfix/canonical
+#
+# postmap -q - /etc/postfix/canonical <inputfile
+#
+# DESCRIPTION
+# The optional canonical(5) table specifies an address map-
+# ping for local and non-local addresses. The mapping is
+# used by the cleanup(8) daemon, before mail is stored into
+# the queue. The address mapping is recursive.
+#
+# Normally, the canonical(5) 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/canonical" to rebuild an indexed
+# file after changing the corresponding text file.
+#
+# When the table is provided via other means such as NIS,
+# LDAP or SQL, the same lookups are done as for ordinary
+# indexed files.
+#
+# Alternatively, the table can be provided as a regu-
+# lar-expression map where patterns are given as regular
+# expressions, or lookups can be directed to TCP-based
+# server. In those cases, the lookups are done in a slightly
+# different way as described below under "REGULAR EXPRESSION
+# TABLES" or "TCP-BASED TABLES".
+#
+# By default the canonical(5) mapping affects both message
+# header addresses (i.e. addresses that appear inside mes-
+# sages) and message envelope addresses (for example, the
+# addresses that are used in SMTP protocol commands). This
+# is controlled with the canonical_classes parameter.
+#
+# NOTE: Postfix versions 2.2 and later rewrite message head-
+# ers from remote SMTP clients only if the client matches
+# the local_header_rewrite_clients parameter, or if the
+# remote_header_rewrite_domain configuration parameter spec-
+# ifies a non-empty value. To get the behavior before Post-
+# fix 2.2, specify "local_header_rewrite_clients =
+# static:all".
+#
+# Typically, one would use the canonical(5) table to replace
+# login names by Firstname.Lastname, or to clean up
+# addresses produced by legacy mail systems.
+#
+# The canonical(5) mapping is not to be confused with vir-
+# tual alias support or with local aliasing. To change the
+# destination but not the headers, use the virtual(5) or
+# aliases(5) map instead.
+#
+# CASE FOLDING
+# The search string is folded to lowercase before database
+# lookup. As of Postfix 2.3, the search string is not case
+# folded with database types such as regexp: or pcre: whose
+# lookup fields can match both upper and lower case.
+#
+# TABLE FORMAT
+# The input format for the postmap(1) command is as follows:
+#
+# pattern address
+# When pattern matches a mail address, replace it by
+# the corresponding address.
+#
+# blank lines and comments
+# Empty lines and whitespace-only lines are ignored,
+# as are lines whose first non-whitespace character
+# is a `#'.
+#
+# multi-line text
+# A logical line starts with non-whitespace text. A
+# line that starts with whitespace continues a logi-
+# cal line.
+#
+# TABLE SEARCH ORDER
+# With lookups from indexed files such as DB or DBM, or from
+# networked tables such as NIS, LDAP or SQL, each
+# user@domain query produces a sequence of query patterns as
+# described below.
+#
+# Each query pattern is sent to each specified lookup table
+# before trying the next query pattern, until a match is
+# found.
+#
+# user@domain address
+# Replace user@domain by address. This form has the
+# highest precedence.
+#
+# This is useful to clean up addresses produced by
+# legacy mail systems. It can also be used to pro-
+# duce Firstname.Lastname style addresses, but see
+# below for a simpler solution.
+#
+# user address
+# Replace user@site by address when site is equal to
+# $myorigin, when site is listed in $mydestination,
+# or when it is listed in $inet_interfaces or
+# $proxy_interfaces.
+#
+# This form is useful for replacing login names by
+# Firstname.Lastname.
+#
+# @domain address
+# Replace other addresses in domain by address. This
+# form has the lowest precedence.
+#
+# Note: @domain is a wild-card. When this form is
+# applied to recipient addresses, the Postfix SMTP
+# server accepts mail for any recipient in domain,
+# regardless of whether that recipient exists. This
+# may turn your mail system into a backscatter
+# source: Postfix first accepts mail for non-existent
+# recipients and then tries to return that mail as
+# "undeliverable" to the often forged sender address.
+#
+# To avoid backscatter with mail for a wild-card
+# domain, replace the wild-card mapping with explicit
+# 1:1 mappings, or add a reject_unverified_recipient
+# restriction for that domain:
+#
+# smtpd_recipient_restrictions =
+# ...
+# reject_unauth_destination
+# check_recipient_access
+# inline:{example.com=reject_unverified_recipient}
+# unverified_recipient_reject_code = 550
+#
+# In the above example, Postfix may contact a remote
+# server if the recipient is rewritten to a remote
+# address.
+#
+# RESULT ADDRESS REWRITING
+# The lookup result is subject to address rewriting:
+#
+# o When the result has the form @otherdomain, the
+# result becomes the same user in otherdomain.
+#
+# o When "append_at_myorigin=yes", append "@$myorigin"
+# to addresses without "@domain".
+#
+# o When "append_dot_mydomain=yes", append ".$mydomain"
+# to addresses without ".domain".
+#
+# ADDRESS EXTENSION
+# When a mail address localpart contains the optional recip-
+# ient delimiter (e.g., user+foo@domain), the lookup order
+# becomes: user+foo@domain, user@domain, user+foo, user, and
+# @domain.
+#
+# The propagate_unmatched_extensions parameter controls
+# whether an unmatched address extension (+foo) is propa-
+# gated to the result of table lookup.
+#
+# REGULAR EXPRESSION TABLES
+# This section describes how the table lookups change when
+# the table is given in the form of regular expressions. For
+# a description of regular expression lookup table syntax,
+# see regexp_table(5) or pcre_table(5).
+#
+# Each pattern is a regular expression that is applied to
+# the entire address being looked up. Thus, user@domain mail
+# addresses are not broken up into their user and @domain
+# constituent parts, nor is user+foo broken up into user and
+# foo.
+#
+# Patterns are applied in the order as specified in the ta-
+# ble, until a pattern is found that matches the search
+# string.
+#
+# Results are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from
+# the pattern can be interpolated as $1, $2 and so on.
+#
+# TCP-BASED TABLES
+# This section describes how the table lookups change when
+# lookups are directed to a TCP-based server. For a descrip-
+# tion of the TCP client/server lookup protocol, see tcp_ta-
+# ble(5). This feature is not available up to and including
+# Postfix version 2.4.
+#
+# Each lookup operation uses the entire address once. Thus,
+# user@domain mail addresses are not broken up into their
+# user and @domain constituent parts, nor is user+foo broken
+# up into user and foo.
+#
+# Results are the same as with indexed file lookups.
+#
+# BUGS
+# The table format does not understand quoting conventions.
+#
+# CONFIGURATION PARAMETERS
+# The following main.cf parameters are especially relevant.
+# The text below provides only a parameter summary. See
+# postconf(5) for more details including examples.
+#
+# canonical_classes (envelope_sender, envelope_recipient,
+# header_sender, header_recipient)
+# What addresses are subject to canonical_maps
+# address mapping.
+#
+# canonical_maps (empty)
+# Optional address mapping lookup tables for message
+# headers and envelopes.
+#
+# recipient_canonical_maps (empty)
+# Optional address mapping lookup tables for envelope
+# and header recipient addresses.
+#
+# sender_canonical_maps (empty)
+# Optional address mapping lookup tables for envelope
+# and header sender addresses.
+#
+# propagate_unmatched_extensions (canonical, virtual)
+# What address lookup tables copy an address exten-
+# sion from the lookup key to the lookup result.
+#
+# Other parameters of interest:
+#
+# inet_interfaces (all)
+# The network interface addresses that this mail sys-
+# tem receives mail on.
+#
+# local_header_rewrite_clients (permit_inet_interfaces)
+# Rewrite message header addresses in mail from these
+# clients and update incomplete addresses with the
+# domain name in $myorigin or $mydomain; either don't
+# rewrite message headers from other clients at all,
+# or rewrite message headers and update incomplete
+# addresses with the domain specified in the
+# remote_header_rewrite_domain parameter.
+#
+# proxy_interfaces (empty)
+# The network interface addresses that this mail sys-
+# tem receives mail on by way of a proxy or network
+# address translation unit.
+#
+# masquerade_classes (envelope_sender, header_sender,
+# header_recipient)
+# What addresses are subject to address masquerading.
+#
+# masquerade_domains (empty)
+# Optional list of domains whose subdomain structure
+# will be stripped off in email addresses.
+#
+# masquerade_exceptions (empty)
+# Optional list of user names that are not subjected
+# to address masquerading, even when their address
+# matches $masquerade_domains.
+#
+# mydestination ($myhostname, localhost.$mydomain, local-
+# host)
+# The list of domains that are delivered via the
+# $local_transport mail delivery transport.
+#
+# myorigin ($myhostname)
+# The domain name that locally-posted mail appears to
+# come from, and that locally posted mail is deliv-
+# ered to.
+#
+# owner_request_special (yes)
+# Enable special treatment for owner-listname entries
+# in the aliases(5) file, and don't split owner-list-
+# name and listname-request address localparts when
+# the recipient_delimiter is set to "-".
+#
+# remote_header_rewrite_domain (empty)
+# Don't rewrite message headers from remote clients
+# at all when this parameter is empty; otherwise, re-
+# write message headers and append the specified
+# domain name to incomplete addresses.
+#
+# SEE ALSO
+# cleanup(8), canonicalize and enqueue mail
+# postmap(1), Postfix lookup table manager
+# postconf(5), configuration parameters
+# virtual(5), virtual aliasing
+#
+# README FILES
+# Use "postconf readme_directory" or "postconf html_direc-
+# tory" to locate this information.
+# DATABASE_README, Postfix lookup table overview
+# ADDRESS_REWRITING_README, address rewriting guide
+#
+# LICENSE
+# The Secure Mailer license must be distributed with this
+# software.
+#
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#
+# CANONICAL(5)
diff --git a/conf/dynamicmaps.cf b/conf/dynamicmaps.cf
new file mode 100644
index 0000000..5179f66
--- /dev/null
+++ b/conf/dynamicmaps.cf
@@ -0,0 +1,9 @@
+# dict-type so-name (pathname) dict-function mkmap-function
+cdb ${LIB_PREFIX}cdb${LIB_SUFFIX} dict_cdb_open mkmap_cdb_open
+ldap ${LIB_PREFIX}ldap${LIB_SUFFIX} dict_ldap_open
+lmdb ${LIB_PREFIX}lmdb${LIB_SUFFIX} dict_lmdb_open mkmap_lmdb_open
+mysql ${LIB_PREFIX}mysql${LIB_SUFFIX} dict_mysql_open
+pcre ${LIB_PREFIX}pcre${LIB_SUFFIX} dict_pcre_open
+pgsql ${LIB_PREFIX}pgsql${LIB_SUFFIX} dict_pgsql_open
+sdbm ${LIB_PREFIX}sdbm${LIB_SUFFIX} dict_sdbm_open mkmap_sdbm_open
+sqlite ${LIB_PREFIX}sqlite${LIB_SUFFIX} dict_sqlite_open
diff --git a/conf/generic b/conf/generic
new file mode 100644
index 0000000..9d29368
--- /dev/null
+++ b/conf/generic
@@ -0,0 +1,250 @@
+# GENERIC(5) GENERIC(5)
+#
+# NAME
+# generic - Postfix generic table format
+#
+# SYNOPSIS
+# postmap /etc/postfix/generic
+#
+# postmap -q "string" /etc/postfix/generic
+#
+# postmap -q - /etc/postfix/generic <inputfile
+#
+# DESCRIPTION
+# The optional generic(5) table specifies an address mapping
+# that applies when mail is delivered. This is the opposite
+# of canonical(5) mapping, which applies when mail is
+# received.
+#
+# Typically, one would use the generic(5) table on a system
+# that does not have a valid Internet domain name and that
+# uses something like localdomain.local instead. The
+# generic(5) table is then used by the smtp(8) client to
+# transform local mail addresses into valid Internet mail
+# addresses when mail has to be sent across the Internet.
+# See the EXAMPLE section at the end of this document.
+#
+# The generic(5) mapping affects both message header
+# addresses (i.e. addresses that appear inside messages) and
+# message envelope addresses (for example, the addresses
+# that are used in SMTP protocol commands).
+#
+# Normally, the generic(5) 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/generic" to rebuild an indexed file
+# after changing the corresponding text file.
+#
+# When the table is provided via other means such as NIS,
+# LDAP or SQL, the same lookups are done as for ordinary
+# indexed files.
+#
+# Alternatively, the table can be provided as a regu-
+# lar-expression map where patterns are given as regular
+# expressions, or lookups can be directed to TCP-based
+# server. In those case, the lookups are done in a slightly
+# different way as described below under "REGULAR EXPRESSION
+# TABLES" or "TCP-BASED TABLES".
+#
+# CASE FOLDING
+# The search string is folded to lowercase before database
+# lookup. As of Postfix 2.3, the search string is not case
+# folded with database types such as regexp: or pcre: whose
+# lookup fields can match both upper and lower case.
+#
+# TABLE FORMAT
+# The input format for the postmap(1) command is as follows:
+#
+# pattern result
+# When pattern matches a mail address, replace it by
+# the corresponding result.
+#
+# blank lines and comments
+# Empty lines and whitespace-only lines are ignored,
+# as are lines whose first non-whitespace character
+# is a `#'.
+#
+# multi-line text
+# A logical line starts with non-whitespace text. A
+# line that starts with whitespace continues a logi-
+# cal line.
+#
+# TABLE SEARCH ORDER
+# With lookups from indexed files such as DB or DBM, or from
+# networked tables such as NIS, LDAP or SQL, each
+# user@domain query produces a sequence of query patterns as
+# described below.
+#
+# Each query pattern is sent to each specified lookup table
+# before trying the next query pattern, until a match is
+# found.
+#
+# user@domain address
+# Replace user@domain by address. This form has the
+# highest precedence.
+#
+# user address
+# Replace user@site by address when site is equal to
+# $myorigin, when site is listed in $mydestination,
+# or when it is listed in $inet_interfaces or
+# $proxy_interfaces.
+#
+# @domain address
+# Replace other addresses in domain by address. This
+# form has the lowest precedence.
+#
+# RESULT ADDRESS REWRITING
+# The lookup result is subject to address rewriting:
+#
+# o When the result has the form @otherdomain, the
+# result becomes the same user in otherdomain.
+#
+# o When "append_at_myorigin=yes", append "@$myorigin"
+# to addresses without "@domain".
+#
+# o When "append_dot_mydomain=yes", append ".$mydomain"
+# to addresses without ".domain".
+#
+# ADDRESS EXTENSION
+# When a mail address localpart contains the optional recip-
+# ient delimiter (e.g., user+foo@domain), the lookup order
+# becomes: user+foo@domain, user@domain, user+foo, user, and
+# @domain.
+#
+# The propagate_unmatched_extensions parameter controls
+# whether an unmatched address extension (+foo) is propa-
+# gated to the result of table lookup.
+#
+# REGULAR EXPRESSION TABLES
+# This section describes how the table lookups change when
+# the table is given in the form of regular expressions. For
+# a description of regular expression lookup table syntax,
+# see regexp_table(5) or pcre_table(5).
+#
+# Each pattern is a regular expression that is applied to
+# the entire address being looked up. Thus, user@domain mail
+# addresses are not broken up into their user and @domain
+# constituent parts, nor is user+foo broken up into user and
+# foo.
+#
+# Patterns are applied in the order as specified in the ta-
+# ble, until a pattern is found that matches the search
+# string.
+#
+# Results are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from
+# the pattern can be interpolated as $1, $2 and so on.
+#
+# TCP-BASED TABLES
+# This section describes how the table lookups change when
+# lookups are directed to a TCP-based server. For a descrip-
+# tion of the TCP client/server lookup protocol, see tcp_ta-
+# ble(5). This feature is not available up to and including
+# Postfix version 2.4.
+#
+# Each lookup operation uses the entire address once. Thus,
+# user@domain mail addresses are not broken up into their
+# user and @domain constituent parts, nor is user+foo broken
+# up into user and foo.
+#
+# Results are the same as with indexed file lookups.
+#
+# EXAMPLE
+# The following shows a generic mapping with an indexed
+# file. When mail is sent to a remote host via SMTP, this
+# replaces his@localdomain.local by his ISP mail address,
+# replaces her@localdomain.local by her ISP mail address,
+# and replaces other local addresses by his ISP account,
+# with an address extension of +local (this example assumes
+# that the ISP supports "+" style address extensions).
+#
+# /etc/postfix/main.cf:
+# smtp_generic_maps = hash:/etc/postfix/generic
+#
+# /etc/postfix/generic:
+# his@localdomain.local hisaccount@hisisp.example
+# her@localdomain.local heraccount@herisp.example
+# @localdomain.local hisaccount+local@hisisp.example
+#
+# Execute the command "postmap /etc/postfix/generic" when-
+# ever the table is changed. Instead of hash, some systems
+# use dbm database files. To find out what tables your sys-
+# tem supports use the command "postconf -m".
+#
+# BUGS
+# The table format does not understand quoting conventions.
+#
+# CONFIGURATION PARAMETERS
+# The following main.cf parameters are especially relevant.
+# The text below provides only a parameter summary. See
+# postconf(5) for more details including examples.
+#
+# smtp_generic_maps
+# Address mapping lookup table for envelope and
+# header sender and recipient addresses while deliv-
+# ering mail via SMTP.
+#
+# propagate_unmatched_extensions
+# A list of address rewriting or forwarding mecha-
+# nisms that propagate an address extension from the
+# original address to the result. Specify zero or
+# more of canonical, virtual, alias, forward,
+# include, or generic.
+#
+# Other parameters of interest:
+#
+# inet_interfaces
+# The network interface addresses that this system
+# receives mail on. You need to stop and start Post-
+# fix when this parameter changes.
+#
+# proxy_interfaces
+# Other interfaces that this machine receives mail on
+# by way of a proxy agent or network address transla-
+# tor.
+#
+# mydestination
+# List of domains that this mail system considers
+# local.
+#
+# myorigin
+# The domain that is appended to locally-posted mail.
+#
+# owner_request_special
+# Give special treatment to owner-xxx and xxx-request
+# addresses.
+#
+# SEE ALSO
+# postmap(1), Postfix lookup table manager
+# postconf(5), configuration parameters
+# smtp(8), Postfix SMTP client
+#
+# README FILES
+# Use "postconf readme_directory" or "postconf html_direc-
+# tory" to locate this information.
+# ADDRESS_REWRITING_README, address rewriting guide
+# DATABASE_README, Postfix lookup table overview
+# STANDARD_CONFIGURATION_README, configuration examples
+#
+# LICENSE
+# The Secure Mailer license must be distributed with this
+# software.
+#
+# HISTORY
+# A genericstable feature appears in the Sendmail MTA.
+#
+# This feature is available in Postfix 2.2 and later.
+#
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#
+# GENERIC(5)
diff --git a/conf/header_checks b/conf/header_checks
new file mode 100644
index 0000000..bcd96a9
--- /dev/null
+++ b/conf/header_checks
@@ -0,0 +1,549 @@
+# HEADER_CHECKS(5) HEADER_CHECKS(5)
+#
+# NAME
+# header_checks - Postfix built-in content inspection
+#
+# SYNOPSIS
+# header_checks = pcre:/etc/postfix/header_checks
+# mime_header_checks = pcre:/etc/postfix/mime_header_checks
+# nested_header_checks = pcre:/etc/postfix/nested_header_checks
+# body_checks = pcre:/etc/postfix/body_checks
+#
+# milter_header_checks = pcre:/etc/postfix/milter_header_checks
+#
+# smtp_header_checks = pcre:/etc/postfix/smtp_header_checks
+# smtp_mime_header_checks = pcre:/etc/postfix/smtp_mime_header_checks
+# smtp_nested_header_checks = pcre:/etc/postfix/smtp_nested_header_checks
+# smtp_body_checks = pcre:/etc/postfix/smtp_body_checks
+#
+# postmap -q "string" pcre:/etc/postfix/filename
+# postmap -q - pcre:/etc/postfix/filename <inputfile
+#
+# DESCRIPTION
+# This document describes access control on the content of
+# message headers and message body lines; it is implemented
+# by the Postfix cleanup(8) server before mail is queued.
+# See access(5) for access control on remote SMTP client
+# information.
+#
+# Each message header or message body line is compared
+# against a list of patterns. When a match is found the
+# corresponding action is executed, and the matching process
+# is repeated for the next message header or message body
+# line.
+#
+# Note: message headers are examined one logical header at a
+# time, even when a message header spans multiple lines.
+# Body lines are always examined one line at a time.
+#
+# For examples, see the EXAMPLES section at the end of this
+# manual page.
+#
+# Postfix header or body_checks are designed to stop a flood
+# of mail from worms or viruses; they do not decode attach-
+# ments, and they do not unzip archives. See the documents
+# referenced below in the README FILES section if you need
+# more sophisticated content analysis.
+#
+# FILTERS WHILE RECEIVING MAIL
+# Postfix implements the following four built-in content
+# inspection classes while receiving mail:
+#
+# header_checks (default: empty)
+# These are applied to initial message headers
+# (except for the headers that are processed with
+# mime_header_checks).
+#
+# mime_header_checks (default: $header_checks)
+# These are applied to MIME related message headers
+# only.
+#
+# This feature is available in Postfix 2.0 and later.
+#
+# nested_header_checks (default: $header_checks)
+# These are applied to message headers of attached
+# email messages (except for the headers that are
+# processed with mime_header_checks).
+#
+# This feature is available in Postfix 2.0 and later.
+#
+# body_checks
+# These are applied to all other content, including
+# multi-part message boundaries.
+#
+# With Postfix versions before 2.0, all content after
+# the initial message headers is treated as body con-
+# tent.
+#
+# FILTERS AFTER RECEIVING MAIL
+# Postfix supports a subset of the built-in content inspec-
+# tion classes after the message is received:
+#
+# milter_header_checks (default: empty)
+# These are applied to headers that are added with
+# Milter applications.
+#
+# This feature is available in Postfix 2.7 and later.
+#
+# FILTERS WHILE DELIVERING MAIL
+# Postfix supports all four content inspection classes while
+# delivering mail via SMTP.
+#
+# smtp_header_checks (default: empty)
+#
+# smtp_mime_header_checks (default: empty)
+#
+# smtp_nested_header_checks (default: empty)
+#
+# smtp_body_checks (default: empty)
+# These features are available in Postfix 2.5 and
+# later.
+#
+# COMPATIBILITY
+# With Postfix version 2.2 and earlier specify "postmap -fq"
+# to query a table that contains case sensitive patterns. By
+# default, regexp: and pcre: patterns are case insensitive.
+#
+# TABLE FORMAT
+# This document assumes that header and body_checks rules
+# are specified in the form of Postfix regular expression
+# lookup tables. Usually the best performance is obtained
+# with pcre (Perl Compatible Regular Expression) tables. The
+# regexp (POSIX regular expressions) tables are usually
+# slower, but more widely available. Use the command "post-
+# conf -m" to find out what lookup table types your Postfix
+# system supports.
+#
+# The general format of Postfix regular expression tables is
+# given below. For a discussion of specific pattern or
+# flags syntax, see pcre_table(5) or regexp_table(5),
+# respectively.
+#
+# /pattern/flags action
+# When /pattern/ matches the input string, execute
+# the corresponding action. See below for a list of
+# possible actions.
+#
+# !/pattern/flags action
+# When /pattern/ does not match the input string,
+# execute the corresponding action.
+#
+# if /pattern/flags
+#
+# endif If the input string matches /pattern/, then match
+# that input string against the patterns between if
+# and endif. The if..endif can nest.
+#
+# Note: do not prepend whitespace to patterns inside
+# if..endif.
+#
+# if !/pattern/flags
+#
+# endif If the input string does not match /pattern/, then
+# match that input string against the patterns
+# between if and endif. The if..endif can nest.
+#
+# blank lines and comments
+# Empty lines and whitespace-only lines are ignored,
+# as are lines whose first non-whitespace character
+# is a `#'.
+#
+# multi-line text
+# A pattern/action line starts with non-whitespace
+# text. A line that starts with whitespace continues
+# a logical line.
+#
+# TABLE SEARCH ORDER
+# For each line of message input, the patterns are applied
+# in the order as specified in the table. When a pattern is
+# found that matches the input line, the corresponding
+# action is executed and then the next input line is
+# inspected.
+#
+# TEXT SUBSTITUTION
+# Substitution of substrings from the matched expression
+# into the action string is possible using the conventional
+# Perl syntax ($1, $2, etc.). The macros in the result
+# string may need to be written as ${n} or $(n) if they
+# aren't followed by whitespace.
+#
+# Note: since negated patterns (those preceded by !) return
+# a result when the expression does not match, substitutions
+# are not available for negated patterns.
+#
+# ACTIONS
+# Action names are case insensitive. They are shown in upper
+# case for consistency with other Postfix documentation.
+#
+# BCC user@domain
+# Add the specified address as a BCC recipient, and
+# inspect the next input line. The address must have
+# a local part and domain part. The number of BCC
+# addresses that can be added is limited only by the
+# amount of available storage space.
+#
+# Note 1: the BCC address is added as if it was spec-
+# ified with NOTIFY=NONE. The sender will not be
+# notified when the BCC address is undeliverable, as
+# long as all down-stream software implements RFC
+# 3461.
+#
+# Note 2: this ignores duplicate addresses (with the
+# same delivery status notification options).
+#
+# This feature is available in Postfix 3.0 and later.
+#
+# This feature is not supported with smtp header/body
+# checks.
+#
+# DISCARD optional text...
+# Claim successful delivery and silently discard the
+# message. Do not inspect the remainder of the input
+# message. Log the optional text if specified, oth-
+# erwise log a generic message.
+#
+# Note: this action disables further header or
+# body_checks inspection of the current message and
+# affects all recipients. To discard only one recip-
+# ient without discarding the entire message, use the
+# transport(5) table to direct mail to the discard(8)
+# service.
+#
+# This feature is available in Postfix 2.0 and later.
+#
+# This feature is not supported with smtp header/body
+# checks.
+#
+# DUNNO Pretend that the input line did not match any pat-
+# tern, and inspect the next input line. This action
+# can be used to shorten the table search.
+#
+# For backwards compatibility reasons, Postfix also
+# accepts OK but it is (and always has been) treated
+# as DUNNO.
+#
+# This feature is available in Postfix 2.1 and later.
+#
+# FILTER transport:destination
+# Override the content_filter parameter setting, and
+# inspect the next input line. After the message is
+# queued, send the entire message through the speci-
+# fied external content filter. The transport name
+# specifies the first field of a mail delivery agent
+# definition in master.cf; the syntax of the next-hop
+# destination is described in the manual page of the
+# corresponding delivery agent. More information
+# about external content filters is in the Postfix
+# FILTER_README file.
+#
+# Note 1: do not use $number regular expression sub-
+# stitutions for transport or destination unless you
+# know that the information has a trusted origin.
+#
+# Note 2: this action overrides the main.cf con-
+# tent_filter setting, and affects all recipients of
+# the message. In the case that multiple FILTER
+# actions fire, only the last one is executed.
+#
+# Note 3: the purpose of the FILTER command is to
+# override message routing. To override the recipi-
+# ent's transport but not the next-hop destination,
+# specify an empty filter destination (Postfix 2.7
+# and later), or specify a transport:destination that
+# delivers through a different Postfix instance
+# (Postfix 2.6 and earlier). Other options are using
+# the recipient-dependent transport_maps or the sen-
+# der-dependent sender_dependent_default_transport-
+# _maps features.
+#
+# This feature is available in Postfix 2.0 and later.
+#
+# This feature is not supported with smtp header/body
+# checks.
+#
+# HOLD optional text...
+# Arrange for the message to be placed on the hold
+# queue, and inspect the next input line. The mes-
+# sage remains on hold until someone either deletes
+# it or releases it for delivery. Log the optional
+# text if specified, otherwise log a generic message.
+#
+# Mail that is placed on hold can be examined with
+# the postcat(1) command, and can be destroyed or
+# released with the postsuper(1) command.
+#
+# Note: use "postsuper -r" to release mail that was
+# kept on hold for a significant fraction of $maxi-
+# mal_queue_lifetime or $bounce_queue_lifetime, or
+# longer. Use "postsuper -H" only for mail that will
+# not expire within a few delivery attempts.
+#
+# Note: this action affects all recipients of the
+# message.
+#
+# This feature is available in Postfix 2.0 and later.
+#
+# This feature is not supported with smtp header/body
+# checks.
+#
+# IGNORE Delete the current line from the input, and inspect
+# the next input line. See STRIP for an alternative
+# that logs the action.
+#
+# INFO optional text...
+# Log an "info:" record with the optional text... (or
+# log a generic text), and inspect the next input
+# line. This action is useful for routine logging or
+# for debugging.
+#
+# This feature is available in Postfix 2.8 and later.
+#
+# PASS optional text...
+# Log a "pass:" record with the optional text... (or
+# log a generic text), and turn off header, body, and
+# Milter inspection for the remainder of this mes-
+# sage.
+#
+# Note: this feature relies on trust in information
+# that is easy to forge.
+#
+# This feature is available in Postfix 3.2 and later.
+#
+# This feature is not supported with smtp header/body
+# checks.
+#
+# PREPEND text...
+# Prepend one line with the specified text, and
+# inspect the next input line.
+#
+# Notes:
+#
+# o The prepended text is output on a separate
+# line, immediately before the input that
+# triggered the PREPEND action.
+#
+# o The prepended text is not considered part of
+# the input stream: it is not subject to
+# header/body checks or address rewriting, and
+# it does not affect the way that Postfix adds
+# missing message headers.
+#
+# o When prepending text before a message header
+# line, the prepended text must begin with a
+# valid message header label.
+#
+# o This action cannot be used to prepend
+# multi-line text.
+#
+# This feature is available in Postfix 2.1 and later.
+#
+# This feature is not supported with mil-
+# ter_header_checks.
+#
+# REDIRECT user@domain
+# Write a message redirection request to the queue
+# file, and inspect the next input line. After the
+# message is queued, it will be sent to the specified
+# address instead of the intended recipient(s).
+#
+# Note: this action overrides the FILTER action, and
+# affects all recipients of the message. If multiple
+# REDIRECT actions fire, only the last one is exe-
+# cuted.
+#
+# This feature is available in Postfix 2.1 and later.
+#
+# This feature is not supported with smtp header/body
+# checks.
+#
+# REPLACE text...
+# Replace the current line with the specified text,
+# and inspect the next input line.
+#
+# This feature is available in Postfix 2.2 and later.
+# The description below applies to Postfix 2.2.2 and
+# later.
+#
+# Notes:
+#
+# o When replacing a message header line, the
+# replacement text must begin with a valid
+# header label.
+#
+# o The replaced text remains part of the input
+# stream. Unlike the result from the PREPEND
+# action, a replaced message header may be
+# subject to address rewriting and may affect
+# the way that Postfix adds missing message
+# headers.
+#
+# REJECT optional text...
+# Reject the entire message. Do not inspect the
+# remainder of the input message. Reply with
+# optional text... when the optional text is speci-
+# fied, otherwise reply with a generic error message.
+#
+# Note: this action disables further header or
+# body_checks inspection of the current message and
+# affects all recipients.
+#
+# Postfix version 2.3 and later support enhanced sta-
+# tus codes. When no code is specified at the begin-
+# ning of optional text..., Postfix inserts a default
+# enhanced status code of "5.7.1".
+#
+# This feature is not supported with smtp header/body
+# checks.
+#
+# STRIP optional text...
+# Log a "strip:" record with the optional text... (or
+# log a generic text), delete the input line from the
+# input, and inspect the next input line. See IGNORE
+# for a silent alternative.
+#
+# This feature is available in Postfix 3.2 and later.
+#
+# WARN optional text...
+# Log a "warning:" record with the optional text...
+# (or log a generic text), and inspect the next input
+# line. This action is useful for debugging and for
+# testing a pattern before applying more drastic
+# actions.
+#
+# BUGS
+# Empty lines never match, because some map types mis-behave
+# when given a zero-length search string. This limitation
+# may be removed for regular expression tables in a future
+# release.
+#
+# Many people overlook the main limitations of header and
+# body_checks rules.
+#
+# o These rules operate on one logical message header
+# or one body line at a time. A decision made for one
+# line is not carried over to the next line.
+#
+# o If text in the message body is encoded (RFC 2045)
+# then the rules need to be specified for the encoded
+# form.
+#
+# o Likewise, when message headers are encoded (RFC
+# 2047) then the rules need to be specified for the
+# encoded form.
+#
+# Message headers added by the cleanup(8) daemon itself are
+# excluded from inspection. Examples of such message headers
+# are From:, To:, Message-ID:, Date:.
+#
+# Message headers deleted by the cleanup(8) daemon will be
+# examined before they are deleted. Examples are: Bcc:, Con-
+# tent-Length:, Return-Path:.
+#
+# CONFIGURATION PARAMETERS
+# body_checks
+# Lookup tables with content filter rules for message
+# body lines. These filters see one physical line at
+# a time, in chunks of at most $line_length_limit
+# bytes.
+#
+# body_checks_size_limit
+# The amount of content per message body segment
+# (attachment) that is subjected to $body_checks fil-
+# tering.
+#
+# header_checks
+#
+# mime_header_checks (default: $header_checks)
+#
+# nested_header_checks (default: $header_checks)
+# Lookup tables with content filter rules for message
+# header lines: respectively, these are applied to
+# the initial message headers (not including MIME
+# headers), to the MIME headers anywhere in the mes-
+# sage, and to the initial headers of attached mes-
+# sages.
+#
+# Note: these filters see one logical message header
+# at a time, even when a message header spans multi-
+# ple lines. Message headers that are longer than
+# $header_size_limit characters are truncated.
+#
+# disable_mime_input_processing
+# While receiving mail, give no special treatment to
+# MIME related message headers; all text after the
+# initial message headers is considered to be part of
+# the message body. This means that header_checks is
+# applied to all the initial message headers, and
+# that body_checks is applied to the remainder of the
+# message.
+#
+# Note: when used in this manner, body_checks will
+# process a multi-line message header one line at a
+# time.
+#
+# EXAMPLES
+# Header pattern to block attachments with bad file name
+# extensions. For convenience, the PCRE /x flag is speci-
+# fied, so that there is no need to collapse the pattern
+# into a single line of text. The purpose of the
+# [[:xdigit:]] sub-expressions is to recognize Windows CLSID
+# strings.
+#
+# /etc/postfix/main.cf:
+# header_checks = pcre:/etc/postfix/header_checks.pcre
+#
+# /etc/postfix/header_checks.pcre:
+# /^Content-(Disposition|Type).*name\s*=\s*"?([^;]*(\.|=2E)(
+# ade|adp|asp|bas|bat|chm|cmd|com|cpl|crt|dll|exe|
+# hlp|ht[at]|
+# inf|ins|isp|jse?|lnk|md[betw]|ms[cipt]|nws|
+# \{[[:xdigit:]]{8}(?:-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}\}|
+# ops|pcd|pif|prf|reg|sc[frt]|sh[bsm]|swf|
+# vb[esx]?|vxd|ws[cfh]))(\?=)?"?\s*(;|$)/x
+# REJECT Attachment name "$2" may not end with ".$4"
+#
+# Body pattern to stop a specific HTML browser vulnerability
+# exploit.
+#
+# /etc/postfix/main.cf:
+# body_checks = regexp:/etc/postfix/body_checks
+#
+# /etc/postfix/body_checks:
+# /^<iframe src=(3D)?cid:.* height=(3D)?0 width=(3D)?0>$/
+# REJECT IFRAME vulnerability exploit
+#
+# SEE ALSO
+# cleanup(8), canonicalize and enqueue Postfix message
+# pcre_table(5), format of PCRE lookup tables
+# regexp_table(5), format of POSIX regular expression tables
+# postconf(1), Postfix configuration utility
+# postmap(1), Postfix lookup table management
+# postsuper(1), Postfix janitor
+# postcat(1), show Postfix queue file contents
+# RFC 2045, base64 and quoted-printable encoding rules
+# RFC 2047, message header encoding for non-ASCII text
+#
+# README FILES
+# Use "postconf readme_directory" or "postconf html_direc-
+# tory" to locate this information.
+# DATABASE_README, Postfix lookup table overview
+# CONTENT_INSPECTION_README, Postfix content inspection overview
+# BUILTIN_FILTER_README, Postfix built-in content inspection
+# BACKSCATTER_README, blocking returned forged mail
+#
+# LICENSE
+# The Secure Mailer license must be distributed with this
+# software.
+#
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#
+# HEADER_CHECKS(5)
diff --git a/conf/main.cf b/conf/main.cf
new file mode 100644
index 0000000..9247ef7
--- /dev/null
+++ b/conf/main.cf
@@ -0,0 +1,676 @@
+# Global Postfix configuration file. This file lists only a subset
+# of all parameters. For the syntax, and for a complete parameter
+# list, see the postconf(5) manual page (command: "man 5 postconf").
+#
+# For common configuration examples, see BASIC_CONFIGURATION_README
+# and STANDARD_CONFIGURATION_README. To find these documents, use
+# the command "postconf html_directory readme_directory", or go to
+# http://www.postfix.org/BASIC_CONFIGURATION_README.html etc.
+#
+# For best results, change no more than 2-3 parameters at a time,
+# and test if Postfix still works after every change.
+
+# COMPATIBILITY
+#
+# The compatibility_level determines what default settings Postfix
+# will use for main.cf and master.cf settings. These defaults will
+# change over time.
+#
+# To avoid breaking things, Postfix will use backwards-compatible
+# default settings and log where it uses those old backwards-compatible
+# default settings, until the system administrator has determined
+# if any backwards-compatible default settings need to be made
+# permanent in main.cf or master.cf.
+#
+# When this review is complete, update the compatibility_level setting
+# below as recommended in the RELEASE_NOTES file.
+#
+# The level below is what should be used with new (not upgrade) installs.
+#
+compatibility_level = 2
+
+# SOFT BOUNCE
+#
+# The soft_bounce parameter provides a limited safety net for
+# testing. When soft_bounce is enabled, mail will remain queued that
+# would otherwise bounce. This parameter disables locally-generated
+# bounces, and prevents the SMTP server from rejecting mail permanently
+# (by changing 5xx replies into 4xx replies). However, soft_bounce
+# is no cure for address rewriting mistakes or mail routing mistakes.
+#
+#soft_bounce = no
+
+# LOCAL PATHNAME INFORMATION
+#
+# The queue_directory specifies the location of the Postfix queue.
+# This is also the root directory of Postfix daemons that run chrooted.
+# See the files in examples/chroot-setup for setting up Postfix chroot
+# environments on different UNIX systems.
+#
+queue_directory = /var/spool/postfix
+
+# The command_directory parameter specifies the location of all
+# postXXX commands.
+#
+command_directory = /usr/sbin
+
+# The daemon_directory parameter specifies the location of all Postfix
+# daemon programs (i.e. programs listed in the master.cf file). This
+# directory must be owned by root.
+#
+daemon_directory = /usr/libexec/postfix
+
+# The data_directory parameter specifies the location of Postfix-writable
+# data files (caches, random numbers). This directory must be owned
+# by the mail_owner account (see below).
+#
+data_directory = /var/lib/postfix
+
+# QUEUE AND PROCESS OWNERSHIP
+#
+# The mail_owner parameter specifies the owner of the Postfix queue
+# and of most Postfix daemon processes. Specify the name of a user
+# account THAT DOES NOT SHARE ITS USER OR GROUP ID WITH OTHER ACCOUNTS
+# AND THAT OWNS NO OTHER FILES OR PROCESSES ON THE SYSTEM. In
+# particular, don't specify nobody or daemon. PLEASE USE A DEDICATED
+# USER.
+#
+mail_owner = postfix
+
+# The default_privs parameter specifies the default rights used by
+# the local delivery agent for delivery to external file or command.
+# These rights are used in the absence of a recipient user context.
+# DO NOT SPECIFY A PRIVILEGED USER OR THE POSTFIX OWNER.
+#
+#default_privs = nobody
+
+# INTERNET HOST AND DOMAIN NAMES
+#
+# The myhostname parameter specifies the internet hostname of this
+# mail system. The default is to use the fully-qualified domain name
+# from gethostname(). $myhostname is used as a default value for many
+# other configuration parameters.
+#
+#myhostname = host.domain.tld
+#myhostname = virtual.domain.tld
+
+# The mydomain parameter specifies the local internet domain name.
+# The default is to use $myhostname minus the first component.
+# $mydomain is used as a default value for many other configuration
+# parameters.
+#
+#mydomain = domain.tld
+
+# SENDING MAIL
+#
+# The myorigin parameter specifies the domain that locally-posted
+# mail appears to come from. The default is to append $myhostname,
+# which is fine for small sites. If you run a domain with multiple
+# machines, you should (1) change this to $mydomain and (2) set up
+# a domain-wide alias database that aliases each user to
+# user@that.users.mailhost.
+#
+# For the sake of consistency between sender and recipient addresses,
+# myorigin also specifies the default domain name that is appended
+# to recipient addresses that have no @domain part.
+#
+#myorigin = $myhostname
+#myorigin = $mydomain
+
+# RECEIVING MAIL
+
+# The inet_interfaces parameter specifies the network interface
+# addresses that this mail system receives mail on. By default,
+# the software claims all active interfaces on the machine. The
+# parameter also controls delivery of mail to user@[ip.address].
+#
+# See also the proxy_interfaces parameter, for network addresses that
+# are forwarded to us via a proxy or network address translator.
+#
+# Note: you need to stop/start Postfix when this parameter changes.
+#
+#inet_interfaces = all
+#inet_interfaces = $myhostname
+#inet_interfaces = $myhostname, localhost
+
+# The proxy_interfaces parameter specifies the network interface
+# addresses that this mail system receives mail on by way of a
+# proxy or network address translation unit. This setting extends
+# the address list specified with the inet_interfaces parameter.
+#
+# You must specify your proxy/NAT addresses when your system is a
+# backup MX host for other domains, otherwise mail delivery loops
+# will happen when the primary MX host is down.
+#
+#proxy_interfaces =
+#proxy_interfaces = 1.2.3.4
+
+# The mydestination parameter specifies the list of domains that this
+# machine considers itself the final destination for.
+#
+# These domains are routed to the delivery agent specified with the
+# local_transport parameter setting. By default, that is the UNIX
+# compatible delivery agent that lookups all recipients in /etc/passwd
+# and /etc/aliases or their equivalent.
+#
+# The default is $myhostname + localhost.$mydomain + localhost. On
+# a mail domain gateway, you should also include $mydomain.
+#
+# Do not specify the names of virtual domains - those domains are
+# specified elsewhere (see VIRTUAL_README).
+#
+# Do not specify the names of domains that this machine is backup MX
+# host for. Specify those names via the relay_domains settings for
+# the SMTP server, or use permit_mx_backup if you are lazy (see
+# STANDARD_CONFIGURATION_README).
+#
+# The local machine is always the final destination for mail addressed
+# to user@[the.net.work.address] of an interface that the mail system
+# receives mail on (see the inet_interfaces parameter).
+#
+# 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.
+#
+# See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
+#
+#mydestination = $myhostname, localhost.$mydomain, localhost
+#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
+#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,
+# mail.$mydomain, www.$mydomain, ftp.$mydomain
+
+# REJECTING MAIL FOR UNKNOWN LOCAL USERS
+#
+# The local_recipient_maps parameter specifies optional lookup tables
+# with all names or addresses of users that are local with respect
+# to $mydestination, $inet_interfaces or $proxy_interfaces.
+#
+# If this parameter is defined, then the SMTP server will reject
+# mail for unknown local users. This parameter is defined by default.
+#
+# To turn off local recipient checking in the SMTP server, specify
+# local_recipient_maps = (i.e. empty).
+#
+# The default setting assumes that you use the default Postfix local
+# delivery agent for local delivery. You need to update the
+# local_recipient_maps setting if:
+#
+# - You define $mydestination domain recipients in files other than
+# /etc/passwd, /etc/aliases, or the $virtual_alias_maps files.
+# For example, you define $mydestination domain recipients in
+# the $virtual_mailbox_maps files.
+#
+# - You redefine the local delivery agent in master.cf.
+#
+# - You redefine the "local_transport" setting in main.cf.
+#
+# - You use the "luser_relay", "mailbox_transport", or "fallback_transport"
+# feature of the Postfix local delivery agent (see local(8)).
+#
+# Details are described in the LOCAL_RECIPIENT_README file.
+#
+# Beware: if the Postfix SMTP server runs chrooted, you probably have
+# to access the passwd file via the proxymap service, in order to
+# overcome chroot restrictions. The alternative, having a copy of
+# the system passwd file in the chroot jail is just not practical.
+#
+# The right-hand side of the lookup tables is conveniently ignored.
+# In the left-hand side, specify a bare username, an @domain.tld
+# wild-card, or specify a user@domain.tld address.
+#
+#local_recipient_maps = unix:passwd.byname $alias_maps
+#local_recipient_maps = proxy:unix:passwd.byname $alias_maps
+#local_recipient_maps =
+
+# The unknown_local_recipient_reject_code specifies the SMTP server
+# response code when a recipient domain matches $mydestination or
+# ${proxy,inet}_interfaces, while $local_recipient_maps is non-empty
+# and the recipient address or address local-part is not found.
+#
+# The default setting is 550 (reject mail) but it is safer to start
+# with 450 (try again later) until you are certain that your
+# local_recipient_maps settings are OK.
+#
+unknown_local_recipient_reject_code = 550
+
+# TRUST AND RELAY CONTROL
+
+# The mynetworks parameter specifies the list of "trusted" SMTP
+# clients that have more privileges than "strangers".
+#
+# In particular, "trusted" SMTP clients are allowed to relay mail
+# through Postfix. See the smtpd_recipient_restrictions parameter
+# in postconf(5).
+#
+# You can specify the list of "trusted" network addresses by hand
+# or you can let Postfix do it for you (which is the default).
+#
+# By default (mynetworks_style = subnet), Postfix "trusts" SMTP
+# clients in the same IP subnetworks as the local machine.
+# On Linux, this works correctly only with interfaces specified
+# with the "ifconfig" command.
+#
+# Specify "mynetworks_style = class" when Postfix should "trust" SMTP
+# clients in the same IP class A/B/C networks as the local machine.
+# Don't do this with a dialup site - it would cause Postfix to "trust"
+# your entire provider's network. Instead, specify an explicit
+# mynetworks list by hand, as described below.
+#
+# Specify "mynetworks_style = host" when Postfix should "trust"
+# only the local machine.
+#
+#mynetworks_style = class
+#mynetworks_style = subnet
+#mynetworks_style = host
+
+# Alternatively, you can specify the mynetworks list by hand, in
+# which case Postfix ignores the mynetworks_style setting.
+#
+# Specify an explicit list of network/netmask patterns, where the
+# mask specifies the number of bits in the network part of a host
+# address.
+#
+# You can also specify the absolute pathname of a pattern file instead
+# of listing the patterns here. Specify type:table for table-based lookups
+# (the value on the table right-hand side is not used).
+#
+#mynetworks = 168.100.189.0/28, 127.0.0.0/8
+#mynetworks = $config_directory/mynetworks
+#mynetworks = hash:/etc/postfix/network_table
+
+# The relay_domains parameter restricts what destinations this system will
+# relay mail to. See the smtpd_recipient_restrictions description in
+# postconf(5) for detailed information.
+#
+# By default, Postfix relays mail
+# - from "trusted" clients (IP address matches $mynetworks) to any destination,
+# - from "untrusted" clients to destinations that match $relay_domains or
+# subdomains thereof, except addresses with sender-specified routing.
+# The default relay_domains value is $mydestination.
+#
+# In addition to the above, the Postfix SMTP server by default accepts mail
+# that Postfix is final destination for:
+# - destinations that match $inet_interfaces or $proxy_interfaces,
+# - destinations that match $mydestination
+# - 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
+# lookup tables, separated by commas and/or whitespace. Continue
+# long lines by starting the next line with whitespace. A file name
+# is replaced by its contents; a type:name table is matched when a
+# (parent) domain appears as lookup key.
+#
+# NOTE: Postfix will not automatically forward mail for domains that
+# list this system as their primary or backup MX host. See the
+# permit_mx_backup restriction description in postconf(5).
+#
+#relay_domains = $mydestination
+
+# INTERNET OR INTRANET
+
+# The relayhost parameter specifies the default host to send mail to
+# when no entry is matched in the optional transport(5) table. When
+# no relayhost is given, mail is routed directly to the destination.
+#
+# On an intranet, specify the organizational domain name. If your
+# internal DNS uses no MX records, specify the name of the intranet
+# gateway host instead.
+#
+# In the case of SMTP, specify a domain, host, host:port, [host]:port,
+# [address] or [address]:port; the form [host] turns off MX lookups.
+#
+# If you're connected via UUCP, see also the default_transport parameter.
+#
+#relayhost = $mydomain
+#relayhost = [gateway.my.domain]
+#relayhost = [mailserver.isp.tld]
+#relayhost = uucphost
+#relayhost = [an.ip.add.ress]
+
+# REJECTING UNKNOWN RELAY USERS
+#
+# The relay_recipient_maps parameter specifies optional lookup tables
+# with all addresses in the domains that match $relay_domains.
+#
+# If this parameter is defined, then the SMTP server will reject
+# mail for unknown relay users. This feature is off by default.
+#
+# The right-hand side of the lookup tables is conveniently ignored.
+# In the left-hand side, specify an @domain.tld wild-card, or specify
+# a user@domain.tld address.
+#
+#relay_recipient_maps = hash:/etc/postfix/relay_recipients
+
+# INPUT RATE CONTROL
+#
+# The in_flow_delay configuration parameter implements mail input
+# flow control. This feature is turned on by default, although it
+# still needs further development (it's disabled on SCO UNIX due
+# to an SCO bug).
+#
+# A Postfix process will pause for $in_flow_delay seconds before
+# accepting a new message, when the message arrival rate exceeds the
+# message delivery rate. With the default 100 SMTP server process
+# limit, this limits the mail inflow to 100 messages a second more
+# than the number of messages delivered per second.
+#
+# Specify 0 to disable the feature. Valid delays are 0..10.
+#
+#in_flow_delay = 1s
+
+# ADDRESS REWRITING
+#
+# The ADDRESS_REWRITING_README document gives information about
+# address masquerading or other forms of address rewriting including
+# username->Firstname.Lastname mapping.
+
+# ADDRESS REDIRECTION (VIRTUAL DOMAIN)
+#
+# The VIRTUAL_README document gives information about the many forms
+# of domain hosting that Postfix supports.
+
+# "USER HAS MOVED" BOUNCE MESSAGES
+#
+# See the discussion in the ADDRESS_REWRITING_README document.
+
+# TRANSPORT MAP
+#
+# See the discussion in the ADDRESS_REWRITING_README document.
+
+# ALIAS DATABASE
+#
+# The alias_maps parameter specifies the list of alias databases used
+# by the local delivery agent. The default list is system dependent.
+#
+# On systems with NIS, the default is to search the local alias
+# database, then the NIS alias database. See aliases(5) for syntax
+# details.
+#
+# If you change the alias database, run "postalias /etc/aliases" (or
+# wherever your system stores the mail alias file), or simply run
+# "newaliases" to build the necessary DBM or DB file.
+#
+# It will take a minute or so before changes become visible. Use
+# "postfix reload" to eliminate the delay.
+#
+#alias_maps = dbm:/etc/aliases
+#alias_maps = hash:/etc/aliases
+#alias_maps = hash:/etc/aliases, nis:mail.aliases
+#alias_maps = netinfo:/aliases
+
+# The alias_database parameter specifies the alias database(s) that
+# are built with "newaliases" or "sendmail -bi". This is a separate
+# configuration parameter, because alias_maps (see above) may specify
+# tables that are not necessarily all under control by Postfix.
+#
+#alias_database = dbm:/etc/aliases
+#alias_database = dbm:/etc/mail/aliases
+#alias_database = hash:/etc/aliases
+#alias_database = hash:/etc/aliases, hash:/opt/majordomo/aliases
+
+# ADDRESS EXTENSIONS (e.g., user+foo)
+#
+# The recipient_delimiter parameter specifies the separator between
+# user names and address extensions (user+foo). See canonical(5),
+# local(8), relocated(5) and virtual(5) for the effects this has on
+# aliases, canonical, virtual, relocated and .forward file lookups.
+# Basically, the software tries user+foo and .forward+foo before
+# trying user and .forward.
+#
+#recipient_delimiter = +
+
+# DELIVERY TO MAILBOX
+#
+# The home_mailbox parameter specifies the optional pathname of a
+# mailbox file relative to a user's home directory. The default
+# mailbox file is /var/spool/mail/user or /var/mail/user. Specify
+# "Maildir/" for qmail-style delivery (the / is required).
+#
+#home_mailbox = Mailbox
+#home_mailbox = Maildir/
+
+# The mail_spool_directory parameter specifies the directory where
+# UNIX-style mailboxes are kept. The default setting depends on the
+# system type.
+#
+#mail_spool_directory = /var/mail
+#mail_spool_directory = /var/spool/mail
+
+# The mailbox_command parameter specifies the optional external
+# command to use instead of mailbox delivery. The command is run as
+# the recipient with proper HOME, SHELL and LOGNAME environment settings.
+# Exception: delivery for root is done as $default_user.
+#
+# Other environment variables of interest: USER (recipient username),
+# EXTENSION (address extension), DOMAIN (domain part of address),
+# and LOCAL (the address localpart).
+#
+# Unlike other Postfix configuration parameters, the mailbox_command
+# parameter is not subjected to $parameter substitutions. This is to
+# make it easier to specify shell syntax (see example below).
+#
+# Avoid shell meta characters because they will force Postfix to run
+# an expensive shell process. Procmail alone is expensive enough.
+#
+# IF YOU USE THIS TO DELIVER MAIL SYSTEM-WIDE, YOU MUST SET UP AN
+# ALIAS THAT FORWARDS MAIL FOR ROOT TO A REAL USER.
+#
+#mailbox_command = /some/where/procmail
+#mailbox_command = /some/where/procmail -a "$EXTENSION"
+
+# The mailbox_transport specifies the optional transport in master.cf
+# to use after processing aliases and .forward files. This parameter
+# has precedence over the mailbox_command, fallback_transport and
+# luser_relay parameters.
+#
+# Specify a string of the form transport:nexthop, where transport is
+# the name of a mail delivery transport defined in master.cf. The
+# :nexthop part is optional. For more details see the sample transport
+# configuration file.
+#
+# NOTE: if you use this feature for accounts not in the UNIX password
+# file, then you must update the "local_recipient_maps" setting in
+# the main.cf file, otherwise the SMTP server will reject mail for
+# non-UNIX accounts with "User unknown in local recipient table".
+#
+# Cyrus IMAP over LMTP. Specify ``lmtpunix cmd="lmtpd"
+# listen="/var/imap/socket/lmtp" prefork=0'' in cyrus.conf.
+#mailbox_transport = lmtp:unix:/var/imap/socket/lmtp
+#
+# Cyrus IMAP via command line. Uncomment the "cyrus...pipe" and
+# subsequent line in master.cf.
+#mailbox_transport = cyrus
+
+# The fallback_transport specifies the optional transport in master.cf
+# to use for recipients that are not found in the UNIX passwd database.
+# This parameter has precedence over the luser_relay parameter.
+#
+# Specify a string of the form transport:nexthop, where transport is
+# the name of a mail delivery transport defined in master.cf. The
+# :nexthop part is optional. For more details see the sample transport
+# configuration file.
+#
+# NOTE: if you use this feature for accounts not in the UNIX password
+# file, then you must update the "local_recipient_maps" setting in
+# the main.cf file, otherwise the SMTP server will reject mail for
+# non-UNIX accounts with "User unknown in local recipient table".
+#
+#fallback_transport = lmtp:unix:/file/name
+#fallback_transport = cyrus
+#fallback_transport =
+
+# The luser_relay parameter specifies an optional destination address
+# for unknown recipients. By default, mail for unknown@$mydestination,
+# unknown@[$inet_interfaces] or unknown@[$proxy_interfaces] is returned
+# as undeliverable.
+#
+# The following expansions are done on luser_relay: $user (recipient
+# username), $shell (recipient shell), $home (recipient home directory),
+# $recipient (full recipient address), $extension (recipient address
+# extension), $domain (recipient domain), $local (entire recipient
+# localpart), $recipient_delimiter. Specify ${name?value} or
+# ${name:value} to expand value only when $name does (does not) exist.
+#
+# luser_relay works only for the default Postfix local delivery agent.
+#
+# NOTE: if you use this feature for accounts not in the UNIX password
+# file, then you must specify "local_recipient_maps =" (i.e. empty) in
+# the main.cf file, otherwise the SMTP server will reject mail for
+# non-UNIX accounts with "User unknown in local recipient table".
+#
+#luser_relay = $user@other.host
+#luser_relay = $local@other.host
+#luser_relay = admin+$local
+
+# JUNK MAIL CONTROLS
+#
+# The controls listed here are only a very small subset. The file
+# SMTPD_ACCESS_README provides an overview.
+
+# The header_checks parameter specifies an optional table with patterns
+# that each logical message header is matched against, including
+# headers that span multiple physical lines.
+#
+# By default, these patterns also apply to MIME headers and to the
+# headers of attached messages. With older Postfix versions, MIME and
+# attached message headers were treated as body text.
+#
+# For details, see "man header_checks".
+#
+#header_checks = regexp:/etc/postfix/header_checks
+
+# FAST ETRN SERVICE
+#
+# Postfix maintains per-destination logfiles with information about
+# deferred mail, so that mail can be flushed quickly with the SMTP
+# "ETRN domain.tld" command, or by executing "sendmail -qRdomain.tld".
+# See the ETRN_README document for a detailed description.
+#
+# The fast_flush_domains parameter controls what destinations are
+# eligible for this service. By default, they are all domains that
+# this server is willing to relay mail to.
+#
+#fast_flush_domains = $relay_domains
+
+# SHOW SOFTWARE VERSION OR NOT
+#
+# The smtpd_banner parameter specifies the text that follows the 220
+# code in the SMTP server's greeting banner. Some people like to see
+# the mail version advertised. By default, Postfix shows no version.
+#
+# You MUST specify $myhostname at the start of the text. That is an
+# RFC requirement. Postfix itself does not care.
+#
+#smtpd_banner = $myhostname ESMTP $mail_name
+#smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
+
+# PARALLEL DELIVERY TO THE SAME DESTINATION
+#
+# How many parallel deliveries to the same user or domain? With local
+# delivery, it does not make sense to do massively parallel delivery
+# to the same user, because mailbox updates must happen sequentially,
+# and expensive pipelines in .forward files can cause disasters when
+# too many are run at the same time. With SMTP deliveries, 10
+# simultaneous connections to the same domain could be sufficient to
+# raise eyebrows.
+#
+# Each message delivery transport has its XXX_destination_concurrency_limit
+# parameter. The default is $default_destination_concurrency_limit for
+# most delivery transports. For the local delivery agent the default is 2.
+
+#local_destination_concurrency_limit = 2
+#default_destination_concurrency_limit = 20
+
+# DEBUGGING CONTROL
+#
+# The debug_peer_level parameter specifies the increment in verbose
+# logging level when an SMTP client or server host name or address
+# matches a pattern in the debug_peer_list parameter.
+#
+debug_peer_level = 2
+
+# The debug_peer_list parameter specifies an optional list of domain
+# or network patterns, /file/name patterns or type:name tables. When
+# an SMTP client or server host name or address matches a pattern,
+# increase the verbose logging level by the amount specified in the
+# debug_peer_level parameter.
+#
+#debug_peer_list = 127.0.0.1
+#debug_peer_list = some.domain
+
+# The debugger_command specifies the external command that is executed
+# when a Postfix daemon program is run with the -D option.
+#
+# Use "command .. & sleep 5" so that the debugger can attach before
+# the process marches on. If you use an X-based debugger, be sure to
+# set up your XAUTHORITY environment variable before starting Postfix.
+#
+debugger_command =
+ PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
+ ddd $daemon_directory/$process_name $process_id & sleep 5
+
+# If you can't use X, use this to capture the call stack when a
+# daemon crashes. The result is in a file in the configuration
+# directory, and is named after the process name and the process ID.
+#
+# debugger_command =
+# PATH=/bin:/usr/bin:/usr/local/bin; export PATH; (echo cont;
+# echo where) | gdb $daemon_directory/$process_name $process_id 2>&1
+# >$config_directory/$process_name.$process_id.log & sleep 5
+#
+# Another possibility is to run gdb under a detached screen session.
+# To attach to the screen session, su root and run "screen -r
+# <id_string>" where <id_string> uniquely matches one of the detached
+# sessions (from "screen -list").
+#
+# debugger_command =
+# PATH=/bin:/usr/bin:/sbin:/usr/sbin; export PATH; screen
+# -dmS $process_name gdb $daemon_directory/$process_name
+# $process_id & sleep 1
+
+# INSTALL-TIME CONFIGURATION INFORMATION
+#
+# The following parameters are used when installing a new Postfix version.
+#
+# sendmail_path: The full pathname of the Postfix sendmail command.
+# This is the Sendmail-compatible mail posting interface.
+#
+sendmail_path =
+
+# newaliases_path: The full pathname of the Postfix newaliases command.
+# This is the Sendmail-compatible command to build alias databases.
+#
+newaliases_path =
+
+# mailq_path: The full pathname of the Postfix mailq command. This
+# is the Sendmail-compatible mail queue listing command.
+#
+mailq_path =
+
+# setgid_group: The group for mail submission and queue management
+# commands. This must be a group name with a numerical group ID that
+# is not shared with other accounts, not even with the Postfix account.
+#
+setgid_group =
+
+# html_directory: The location of the Postfix HTML documentation.
+#
+html_directory =
+
+# manpage_directory: The location of the Postfix on-line manual pages.
+#
+manpage_directory =
+
+# sample_directory: The location of the Postfix sample configuration files.
+# This parameter is obsolete as of Postfix 2.1.
+#
+sample_directory =
+
+# readme_directory: The location of the Postfix README files.
+#
+readme_directory =
+inet_protocols = ipv4
diff --git a/conf/master.cf b/conf/master.cf
new file mode 100644
index 0000000..c0f2508
--- /dev/null
+++ b/conf/master.cf
@@ -0,0 +1,133 @@
+#
+# Postfix master process configuration file. For details on the format
+# of the file, see the master(5) manual page (command: "man 5 master" or
+# on-line: http://www.postfix.org/master.5.html).
+#
+# Do not forget to execute "postfix reload" after editing this file.
+#
+# ==========================================================================
+# service type private unpriv chroot wakeup maxproc command + args
+# (yes) (yes) (no) (never) (100)
+# ==========================================================================
+smtp inet n - n - - smtpd
+#smtp inet n - n - 1 postscreen
+#smtpd pass - - n - - smtpd
+#dnsblog unix - - n - 0 dnsblog
+#tlsproxy unix - - n - 0 tlsproxy
+#submission inet n - n - - smtpd
+# -o syslog_name=postfix/submission
+# -o smtpd_tls_security_level=encrypt
+# -o smtpd_sasl_auth_enable=yes
+# -o smtpd_tls_auth_only=yes
+# -o smtpd_reject_unlisted_recipient=no
+# -o smtpd_client_restrictions=$mua_client_restrictions
+# -o smtpd_helo_restrictions=$mua_helo_restrictions
+# -o smtpd_sender_restrictions=$mua_sender_restrictions
+# -o smtpd_recipient_restrictions=
+# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
+# -o milter_macro_daemon_name=ORIGINATING
+#smtps inet n - n - - smtpd
+# -o syslog_name=postfix/smtps
+# -o smtpd_tls_wrappermode=yes
+# -o smtpd_sasl_auth_enable=yes
+# -o smtpd_reject_unlisted_recipient=no
+# -o smtpd_client_restrictions=$mua_client_restrictions
+# -o smtpd_helo_restrictions=$mua_helo_restrictions
+# -o smtpd_sender_restrictions=$mua_sender_restrictions
+# -o smtpd_recipient_restrictions=
+# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
+# -o milter_macro_daemon_name=ORIGINATING
+#628 inet n - n - - qmqpd
+pickup unix n - n 60 1 pickup
+cleanup unix n - n - 0 cleanup
+qmgr unix n - n 300 1 qmgr
+#qmgr unix n - n 300 1 oqmgr
+tlsmgr unix - - n 1000? 1 tlsmgr
+rewrite unix - - n - - trivial-rewrite
+bounce unix - - n - 0 bounce
+defer unix - - n - 0 bounce
+trace unix - - n - 0 bounce
+verify unix - - n - 1 verify
+flush unix n - n 1000? 0 flush
+proxymap unix - - n - - proxymap
+proxywrite unix - - n - 1 proxymap
+smtp unix - - n - - smtp
+relay unix - - n - - smtp
+ -o syslog_name=postfix/$service_name
+# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
+showq unix n - n - - showq
+error unix - - n - - error
+retry unix - - n - - error
+discard unix - - n - - discard
+local unix - n n - - local
+virtual unix - n n - - virtual
+lmtp unix - - n - - lmtp
+anvil unix - - n - 1 anvil
+scache unix - - n - 1 scache
+postlog unix-dgram n - n - 1 postlogd
+#
+# ====================================================================
+# Interfaces to non-Postfix software. Be sure to examine the manual
+# pages of the non-Postfix software to find out what options it wants.
+#
+# Many of the following services use the Postfix pipe(8) delivery
+# agent. See the pipe(8) man page for information about ${recipient}
+# and other message envelope options.
+# ====================================================================
+#
+# maildrop. See the Postfix MAILDROP_README file for details.
+# Also specify in main.cf: maildrop_destination_recipient_limit=1
+#
+#maildrop unix - n n - - pipe
+# flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient}
+#
+# ====================================================================
+#
+# Recent Cyrus versions can use the existing "lmtp" master.cf entry.
+#
+# Specify in cyrus.conf:
+# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4
+#
+# Specify in main.cf one or more of the following:
+# mailbox_transport = lmtp:inet:localhost
+# virtual_transport = lmtp:inet:localhost
+#
+# ====================================================================
+#
+# Cyrus 2.1.5 (Amos Gouaux)
+# Also specify in main.cf: cyrus_destination_recipient_limit=1
+#
+#cyrus unix - n n - - pipe
+# user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
+#
+# ====================================================================
+#
+# Old example of delivery via Cyrus.
+#
+#old-cyrus unix - n n - - pipe
+# flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
+#
+# ====================================================================
+#
+# See the Postfix UUCP_README file for configuration details.
+#
+#uucp unix - n n - - pipe
+# flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
+#
+# ====================================================================
+#
+# Other external delivery methods.
+#
+#ifmail unix - n n - - pipe
+# flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
+#
+#bsmtp unix - n n - - pipe
+# flags=Fq. user=bsmtp argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient
+#
+#scalemail-backend unix - n n - 2 pipe
+# flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store
+# ${nexthop} ${user} ${extension}
+#
+#mailman unix - n n - - pipe
+# flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
+# ${nexthop} ${user}
diff --git a/conf/post-install b/conf/post-install
new file mode 100644
index 0000000..975266b
--- /dev/null
+++ b/conf/post-install
@@ -0,0 +1,925 @@
+#!/bin/sh
+
+# To view the formatted manual page of this file, type:
+# POSTFIXSOURCE/mantools/srctoman - post-install | nroff -man
+
+#++
+# NAME
+# post-install
+# SUMMARY
+# Postfix post-installation script
+# SYNOPSIS
+# postfix post-install [name=value] command ...
+# DESCRIPTION
+# The post-install script performs the finishing touch of a Postfix
+# installation, after the executable programs and configuration
+# files are installed. Usage is one of the following:
+# .IP o
+# While installing Postfix from source code on the local machine, the
+# script is run by the postfix-install script to update selected file
+# or directory permissions and to update Postfix configuration files.
+# .IP o
+# While installing Postfix from a pre-built package, the script is run
+# by the package management procedure to set all file or directory
+# permissions and to update Postfix configuration files.
+# .IP o
+# The script can be used to change installation parameter settings such
+# as mail_owner or setgid_group after Postfix is already installed.
+# .IP o
+# The script can be used to upgrade configuration files and to upgrade
+# file/directory permissions of a secondary Postfix instance.
+# .IP o
+# At Postfix start-up time, the script is run from "postfix check" to
+# create missing queue directories.
+# .PP
+# The post-install script is controlled by installation parameters.
+# Specific parameters are described at the end of this document.
+# All installation parameters must be specified ahead of time via
+# one of the methods described below.
+#
+# Arguments
+# .IP create-missing
+# Create missing queue directories with ownerships and permissions
+# according to the contents of $meta_directory/postfix-files
+# and optionally in $meta_directory/postfix-files.d/*, using
+# the mail_owner and setgid_group parameter settings from the
+# command line, process environment or from the installed
+# main.cf file.
+#
+# This is required at Postfix start-up time.
+# .IP set-permissions
+# Set all file/directory ownerships and permissions according to the
+# contents of $meta_directory/postfix-files and optionally
+# in $meta_directory/postfix-files.d/*, using the mail_owner
+# and setgid_group parameter settings from the command line,
+# process environment or from the installed main.cf file.
+# Implies create-missing.
+#
+# This is required when installing Postfix from a pre-built package,
+# or when changing the mail_owner or setgid_group installation parameter
+# settings after Postfix is already installed.
+# .IP upgrade-permissions
+# Update ownership and permission of existing files/directories as
+# specified in $meta_directory/postfix-files and optionally
+# in $meta_directory/postfix-files.d/*, using the mail_owner
+# and setgid_group parameter settings from the command line,
+# process environment or from the installed main.cf file.
+# Implies create-missing.
+#
+# This is required when upgrading an existing Postfix instance.
+# .IP upgrade-configuration
+# Edit the installed main.cf and master.cf files, in order to account
+# for missing services and to fix deprecated parameter settings.
+#
+# This is required when upgrading an existing Postfix instance.
+# .IP upgrade-source
+# Short-hand for: upgrade-permissions upgrade-configuration.
+#
+# This is recommended when upgrading Postfix from source code.
+# .IP upgrade-package
+# Short-hand for: set-permissions upgrade-configuration.
+#
+# This is recommended when upgrading Postfix from a pre-built package.
+# .IP first-install-reminder
+# Remind the user that they still need to configure main.cf and the
+# aliases file, and that newaliases still needs to be run.
+#
+# This is recommended when Postfix is installed for the first time.
+# MULTIPLE POSTFIX INSTANCES
+# .ad
+# .fi
+# Multiple Postfix instances on the same machine can share command and
+# daemon program files but must have separate configuration and queue
+# directories.
+#
+# To create a secondary Postfix installation on the same machine,
+# copy the configuration files from the primary Postfix instance to
+# a secondary configuration directory and execute:
+#
+# postfix post-install config_directory=secondary-config-directory \e
+# .in +4
+# queue_directory=secondary-queue-directory \e
+# .br
+# create-missing
+# .PP
+# This creates secondary Postfix queue directories, sets their access
+# permissions, and saves the specified installation parameters to the
+# secondary main.cf file.
+#
+# Be sure to list the secondary configuration directory in the
+# alternate_config_directories parameter in the primary main.cf file.
+#
+# To upgrade a secondary Postfix installation on the same machine,
+# execute:
+#
+# postfix post-install config_directory=secondary-config-directory \e
+# .in +4
+# upgrade-permissions upgrade-configuration
+# INSTALLATION PARAMETER INPUT METHODS
+# .ad
+# .fi
+# Parameter settings can be specified through a variety of
+# mechanisms. In order of decreasing precedence these are:
+# .IP "command line"
+# Parameter settings can be given as name=value arguments on
+# the post-install command line. These have the highest precedence.
+# Settings that override the installed main.cf file are saved.
+# .IP "process environment"
+# Parameter settings can be given as name=value environment
+# variables.
+# Settings that override the installed main.cf file are saved.
+# .IP "installed configuration files"
+# If a parameter is not specified via the command line or via the
+# process environment, post-install will attempt to extract its
+# value from the already installed Postfix main.cf configuration file.
+# These settings have the lowest precedence.
+# INSTALLATION PARAMETER DESCRIPTION
+# .ad
+# .fi
+# The description of installation parameters is as follows:
+# .IP config_directory
+# The directory for Postfix configuration files.
+# .IP daemon_directory
+# The directory for Postfix daemon programs. This directory
+# should not be in the command search path of any users.
+# .IP command_directory
+# The directory for Postfix administrative commands. This
+# directory should be in the command search path of adminstrative users.
+# .IP queue_directory
+# The directory for Postfix queues.
+# .IP data_directory
+# The directory for Postfix writable data files (caches, etc.).
+# .IP sendmail_path
+# The full pathname for the Postfix sendmail command.
+# This is the Sendmail-compatible mail posting interface.
+# .IP newaliases_path
+# The full pathname for the Postfix newaliases command.
+# This is the Sendmail-compatible command to build alias databases
+# for the Postfix local delivery agent.
+# .IP mailq_path
+# The full pathname for the Postfix mailq command.
+# This is the Sendmail-compatible command to list the mail queue.
+# .IP mail_owner
+# The owner of the Postfix queue. Its numerical user ID and group ID
+# must not be used by any other accounts on the system.
+# .IP setgid_group
+# The group for mail submission and for queue management commands.
+# Its numerical group ID must not be used by any other accounts on the
+# system, not even by the mail_owner account.
+# .IP html_directory
+# The directory for the Postfix HTML files.
+# .IP manpage_directory
+# The directory for the Postfix on-line manual pages.
+# .IP sample_directory
+# The directory for the Postfix sample configuration files.
+# This feature is obsolete as of Postfix 2.1.
+# .IP readme_directory
+# The directory for the Postfix README files.
+# .IP shlib_directory
+# The directory for the Postfix shared-library files, and for
+# the Postfix dabatase plugin files with a relative pathname
+# in the file dynamicmaps.cf.
+# .IP meta_directory
+# The directory for non-executable files that are shared
+# among multiple Postfix instances, such as postfix-files,
+# dynamicmaps.cf, as well as the multi-instance template files
+# main.cf.proto and master.cf.proto.
+# SEE ALSO
+# postfix-install(1) Postfix primary installation script.
+# FILES
+# $config_directory/main.cf, Postfix installation parameters.
+# $meta_directory/postfix-files, installation control file.
+# $meta_directory/postfix-files.d/*, optional control files.
+# $config_directory/install.cf, obsolete configuration file.
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
+
+umask 022
+
+PATH=/bin:/usr/bin:/usr/sbin:/usr/etc:/sbin:/etc:/usr/contrib/bin:/usr/gnu/bin:/usr/ucb:/usr/bsd
+SHELL=/bin/sh
+IFS="
+"
+BACKUP_IFS="$IFS"
+debug=:
+#debug=echo
+MOST_PARAMETERS="command_directory daemon_directory data_directory
+ html_directory mail_owner mailq_path manpage_directory
+ newaliases_path queue_directory readme_directory sample_directory
+ sendmail_path setgid_group shlib_directory meta_directory"
+NON_SHARED="config_directory queue_directory data_directory"
+
+USAGE="Usage: $0 [name=value] command
+ create-missing Create missing queue directories.
+ upgrade-source When installing or upgrading from source code.
+ upgrade-package When installing or upgrading from pre-built package.
+ first-install-reminder Remind of mandatory first-time configuration steps.
+ name=value Specify an installation parameter".
+
+# Process command-line options and parameter settings. Work around
+# brain damaged shells. "IFS=value command" should not make the
+# IFS=value setting permanent. But some broken standard allows it.
+
+create=; set_perms=; upgrade_perms=; upgrade_conf=; first_install_reminder=
+obsolete=; keep_list=;
+
+for arg
+do
+ case $arg in
+ *[" "]*) echo $0: "Error: argument contains whitespace: '$arg'"
+ exit 1;;
+ *=*) IFS= eval $arg; IFS="$BACKUP_IFS";;
+ create-missing) create=1;;
+ set-perm*) create=1; set_perms=1;;
+ upgrade-perm*) create=1; upgrade_perms=1;;
+ upgrade-conf*) upgrade_conf=1;;
+ upgrade-source) create=1; upgrade_conf=1; upgrade_perms=1;;
+ upgrade-package) create=1; upgrade_conf=1; set_perms=1;;
+ first-install*) first_install_reminder=1;;
+ *) echo "$0: Error: $USAGE" 1>&2; exit 1;;
+ esac
+ shift
+done
+
+# Sanity checks.
+
+test -n "$create$upgrade_conf$first_install_reminder" || {
+ echo "$0: Error: $USAGE" 1>&2
+ exit 1
+}
+
+# Bootstrapping problem.
+
+if [ -n "$command_directory" ]
+then
+ POSTCONF="$command_directory/postconf"
+else
+ POSTCONF="postconf"
+fi
+
+$POSTCONF -d mail_version >/dev/null 2>/dev/null || {
+ echo $0: Error: no $POSTCONF command found. 1>&2
+ echo Re-run this command as $0 command_directory=/some/where. 1>&2
+ exit 1
+}
+
+# Also used to require license etc. files only in the default instance.
+
+def_config_directory=`$POSTCONF -d -h config_directory` || exit 1
+test -n "$config_directory" ||
+ config_directory="$def_config_directory"
+
+test -d "$config_directory" || {
+ echo $0: Error: $config_directory is not a directory. 1>&2
+ exit 1
+}
+
+# If this is a secondary instance, don't touch shared files.
+# XXX Solaris does not have "test -e".
+
+instances=`test ! -f $def_config_directory/main.cf ||
+ $POSTCONF -c $def_config_directory -h multi_instance_directories |
+ sed 's/,/ /'` || exit 1
+
+update_shared_files=1
+for name in $instances
+do
+ case "$name" in
+ "$def_config_directory") ;;
+ "$config_directory") update_shared_files=; break;;
+ esac
+done
+
+test -f $meta_directory/postfix-files || {
+ echo $0: Error: $meta_directory/postfix-files is not a file. 1>&2
+ exit 1
+}
+
+# SunOS5 fmt(1) truncates lines > 1000 characters.
+
+fake_fmt() {
+ sed '
+ :top
+ /^\( *\)\([^ ][^ ]*\) */{
+ s//\1\2\
+\1/
+ P
+ D
+ b top
+ }
+ ' | fmt
+}
+
+case `uname -s` in
+HP-UX*) FMT=cat;;
+SunOS*) FMT=fake_fmt;;
+ *) FMT=fmt;;
+esac
+
+# If a parameter is not set via the command line or environment,
+# try to use settings from installed configuration files.
+
+# Extract parameter settings from the obsolete install.cf file, as
+# a transitional aid.
+
+grep setgid_group $config_directory/main.cf >/dev/null 2>&1 || {
+ test -f $config_directory/install.cf && {
+ for name in sendmail_path newaliases_path mailq_path setgid manpages
+ do
+ eval junk=\$$name
+ case "$junk" in
+ "") eval unset $name;;
+ esac
+ eval : \${$name="\`. $config_directory/install.cf; echo \$$name\`"} \
+ || exit 1
+ done
+ : ${setgid_group=$setgid}
+ : ${manpage_directory=$manpages}
+ }
+}
+
+# Extract parameter settings from the installed main.cf file.
+
+test -f $config_directory/main.cf && {
+ for name in $MOST_PARAMETERS
+ do
+ eval junk=\$$name
+ case "$junk" in
+ "") eval unset $name;;
+ esac
+ eval : \${$name=\`$POSTCONF -c $config_directory -h $name\`} || exit 1
+ done
+}
+
+# Sanity checks
+
+case $manpage_directory in
+ no) echo $0: Error: manpage_directory no longer accepts \"no\" values. 1>&2
+ echo Try again with \"$0 manpage_directory=/pathname ...\". 1>&2; exit 1;;
+esac
+
+case $setgid_group in
+ no) echo $0: Error: setgid_group no longer accepts \"no\" values. 1>&2
+ echo Try again with \"$0 setgid_group=groupname ...\" 1>&2; exit 1;;
+esac
+
+for path in "$daemon_directory" "$command_directory" "$queue_directory" \
+ "$sendmail_path" "$newaliases_path" "$mailq_path" "$manpage_directory" \
+ "$meta_directory"
+do
+ case "$path" in
+ /*) ;;
+ *) echo $0: Error: \"$path\" should be an absolute path name. 1>&2; exit 1;;
+ esac
+done
+
+for path in "$html_directory" "$readme_directory" "$shlib_directory"
+do
+ case "$path" in
+ /*) ;;
+ no) ;;
+ *) echo $0: Error: \"$path\" should be \"no\" or an absolute path name. 1>&2; exit 1;;
+ esac
+done
+
+# Find out what parameters were not specified via command line,
+# via environment, or via installed configuration files.
+
+missing=
+for name in $MOST_PARAMETERS
+do
+ eval test -n \"\$$name\" || missing="$missing $name"
+done
+
+# All parameters must be specified at this point.
+
+test -n "$non_interactive" -a -n "$missing" && {
+ cat <<EOF | ${FMT} 1>&2
+$0: Error: some required installation parameters are not defined.
+
+- Either the parameters need to be given in the $config_directory/main.cf
+file from a recent Postfix installation,
+
+- Or the parameters need to be specified through the process
+environment.
+
+- Or the parameters need to be specified as name=value arguments
+on the $0 command line,
+
+The following parameters were missing:
+
+ $missing
+
+EOF
+ exit 1
+}
+
+POSTCONF="$command_directory/postconf"
+
+# Save settings, allowing command line/environment override.
+
+# Undo MAIL_VERSION expansion at the end of a parameter value. If
+# someone really wants the expanded mail version in main.cf, then
+# we're sorry.
+
+# Confine side effects from mail_version unexpansion within a subshell.
+
+(case "$mail_version" in
+"") mail_version="`$POSTCONF -dhx mail_version`" || exit 1
+esac
+
+for name in $MOST_PARAMETERS
+do
+ eval junk=\$$name
+ case "$junk" in
+ *"$mail_version"*)
+ case "$pattern" in
+ "") pattern=`echo "$mail_version" | sed 's/\./\\\\./g'` || exit 1
+ esac
+ val=`echo "$junk" | sed "s/$pattern"'$/${mail_version}/g'` || exit 1
+ eval ${name}='"$val"'
+ esac
+done
+
+# XXX Maybe update main.cf only with first install, upgrade, set
+# permissions, and what else? Should there be a warning otherwise?
+
+override=
+for name in $MOST_PARAMETERS
+do
+ eval junk=\"\$$name\"
+ test "$junk" = "`$POSTCONF -c $config_directory -h $name`" || {
+ override=1
+ break
+ }
+done
+
+test -n "$override" && {
+ $POSTCONF -c $config_directory -e \
+ "daemon_directory = $daemon_directory" \
+ "command_directory = $command_directory" \
+ "queue_directory = $queue_directory" \
+ "data_directory = $data_directory" \
+ "mail_owner = $mail_owner" \
+ "setgid_group = $setgid_group" \
+ "sendmail_path = $sendmail_path" \
+ "mailq_path = $mailq_path" \
+ "newaliases_path = $newaliases_path" \
+ "html_directory = $html_directory" \
+ "manpage_directory = $manpage_directory" \
+ "sample_directory = $sample_directory" \
+ "readme_directory = $readme_directory" \
+ "shlib_directory = $shlib_directory" \
+ "meta_directory = $meta_directory" \
+ || exit 1
+} || exit 0) || exit 1
+
+# Use file/directory status information in $meta_directory/postfix-files.
+
+test -n "$create" && {
+ postfix_files_d=$meta_directory/postfix-files.d
+ for postfix_file in $meta_directory/postfix-files \
+ `test -d $postfix_files_d && { find $postfix_files_d -type f | sort; }`
+ do
+ exec <$postfix_file || exit 1
+ while IFS=: read path type owner group mode flags junk
+ do
+ IFS="$BACKUP_IFS"
+ set_permission=
+ # Skip comments. Skip shared files, if updating a secondary instance.
+ case $path in
+ [$]*) case "$update_shared_files" in
+ 1) $debug keep non-shared or shared $path;;
+ *) non_shared=
+ for name in $NON_SHARED
+ do
+ case $path in
+ "\$$name"*) non_shared=1; break;;
+ esac
+ done
+ case "$non_shared" in
+ 1) $debug keep non-shared $path;;
+ *) $debug skip shared $path; continue;;
+ esac;;
+ esac;;
+ *) continue;;
+ esac
+ # Skip hard links and symbolic links.
+ case $type in
+ [hl]) continue;;
+ [df]) ;;
+ *) echo unknown type $type for $path in $postfix_file 1>&2; exit 1;;
+ esac
+ # Expand $name, and canonicalize null fields.
+ for name in path owner group flags
+ do
+ eval junk=\${$name}
+ case $junk in
+ [$]*) eval $name=$junk;;
+ -) eval $name=;;
+ *) ;;
+ esac
+ done
+ # Skip uninstalled files.
+ case $path in
+ no|no/*) continue;;
+ esac
+ # Pick up the flags.
+ case $flags in *u*) upgrade_flag=1;; *) upgrade_flag=;; esac
+ case $flags in *c*) create_flag=1;; *) create_flag=;; esac
+ case $flags in *r*) recursive="-R";; *) recursive=;; esac
+ case $flags in *o*) obsolete_flag=1;; *) obsolete_flag=;; esac
+ case $flags in *[1i]*) test ! -r "$path" -a "$config_directory" != \
+ "$def_config_directory" && continue;; esac
+ # Flag obsolete objects. XXX Solaris 2..9 does not have "test -e".
+ if [ -n "$obsolete_flag" ]
+ then
+ test -r $path -a "$type" != "d" && obsolete="$obsolete $path"
+ continue;
+ else
+ keep_list="$keep_list $path"
+ fi
+ # Create missing directories with proper owner/group/mode settings.
+ if [ -n "$create" -a "$type" = "d" -a -n "$create_flag" -a ! -d "$path" ]
+ then
+ mkdir $path || exit 1
+ set_permission=1
+ # Update all owner/group/mode settings.
+ elif [ -n "$set_perms" ]
+ then
+ set_permission=1
+ # Update obsolete owner/group/mode settings.
+ elif [ -n "$upgrade_perms" -a -n "$upgrade_flag" ]
+ then
+ set_permission=1
+ fi
+ test -n "$set_permission" && {
+ chown $recursive $owner $path || exit 1
+ test -z "$group" || chgrp $recursive $group $path || exit 1
+ # Don't "chmod -R"; queue file status is encoded in mode bits.
+ if [ "$type" = "d" -a -n "$recursive" ]
+ then
+ find $path -type d -exec chmod $mode "{}" ";"
+ else
+ chmod $mode $path
+ fi || exit 1
+ }
+ done
+ IFS="$BACKUP_IFS"
+ done
+}
+
+# Upgrade existing Postfix configuration files if necessary.
+
+test -n "$upgrade_conf" && {
+
+ # Postfix 2.0.
+ # 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
+ }
+
+ # Postfix 1.1.
+ # Add missing flush service to master.cf.
+
+ 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
+EOF
+ }
+
+ # Postfix 2.1.
+ # Add missing trace service to master.cf.
+
+ grep 'trace.*bounce' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for trace service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+trace unix - - n - 0 bounce
+EOF
+ }
+
+ # Postfix 2.1.
+ # Add missing verify service to master.cf.
+
+ grep '^verify.*verify' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for verify service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+verify unix - - n - 1 verify
+EOF
+ }
+
+ # Postfix 2.1.
+ # Fix verify service process limit.
+
+ grep '^verify.*[ ]0[ ]*verify' \
+ $config_directory/master.cf >/dev/null && {
+ echo Editing $config_directory/master.cf, setting verify process limit to 1
+ ed $config_directory/master.cf <<EOF || exit 1
+/^verify.*[ ]0[ ]*verify/
+s/\([ ]\)0\([ ]\)/\11\2/
+p
+w
+q
+EOF
+ }
+
+ # Postfix 1.1.
+ # Change privileged pickup service into unprivileged.
+
+ grep "^pickup[ ]*fifo[ ]*n[ ]*n" \
+ $config_directory/master.cf >/dev/null && {
+ echo Editing $config_directory/master.cf, making the pickup service unprivileged
+ ed $config_directory/master.cf <<EOF || exit 1
+/^pickup[ ]*fifo[ ]*n[ ]*n/
+s/\(n[ ]*\)n/\1-/
+p
+w
+q
+EOF
+ }
+
+ # Postfix 1.1.
+ # Change private cleanup and flush services into public.
+
+ for name in cleanup flush
+ do
+ grep "^$name[ ]*unix[ ]*[-y]" \
+ $config_directory/master.cf >/dev/null && {
+ echo Editing $config_directory/master.cf, making the $name service public
+ ed $config_directory/master.cf <<EOF || exit 1
+/^$name[ ]*unix[ ]*[-y]/
+s/[-y]/n/
+p
+w
+q
+EOF
+ }
+ done
+
+ # Postfix 2.2.
+ # File systems have improved since Postfix came out, and all we
+ # require now is that defer and deferred are hashed because those
+ # can contain lots of files.
+
+ found=`$POSTCONF -c $config_directory -h hash_queue_names`
+ missing=
+ (echo "$found" | grep defer >/dev/null) || missing="$missing defer"
+ (echo "$found" | grep deferred>/dev/null)|| missing="$missing deferred"
+ test -n "$missing" && {
+ echo fixing main.cf hash_queue_names for missing $missing
+ $POSTCONF -c $config_directory -e hash_queue_names="$found$missing" ||
+ exit 1
+ }
+
+ # Turn on safety nets for new features that could bounce mail that
+ # would be accepted by a previous Postfix version.
+
+ # [The "unknown_local_recipient_reject_code = 450" safety net,
+ # introduced with Postfix 2.0 and deleted after Postfix 2.3.]
+
+ # Postfix 2.0.
+ # Add missing proxymap service to master.cf.
+
+ grep '^proxymap.*proxymap' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for proxymap service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+proxymap unix - - n - - proxymap
+EOF
+ }
+
+ # Postfix 2.1.
+ # Add missing anvil service to master.cf.
+
+ grep '^anvil.*anvil' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for anvil service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+anvil unix - - n - 1 anvil
+EOF
+ }
+
+ # Postfix 2.2.
+ # Add missing scache service to master.cf.
+
+ grep '^scache.*scache' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for scache service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+scache unix - - n - 1 scache
+EOF
+ }
+
+ # Postfix 2.2.
+ # Add missing discard service to master.cf.
+
+ grep '^discard.*discard' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for discard service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+discard unix - - n - - discard
+EOF
+ }
+
+ # Postfix 2.2.
+ # Update the tlsmgr fifo->unix service.
+
+ grep "^tlsmgr[ ]*fifo[ ]" \
+ $config_directory/master.cf >/dev/null && {
+ echo Editing $config_directory/master.cf, updating the tlsmgr from fifo to unix service
+ ed $config_directory/master.cf <<EOF || exit 1
+/^tlsmgr[ ]*fifo[ ]/
+s/fifo/unix/
+s/[0-9][0-9]*/&?/
+p
+w
+q
+EOF
+ }
+
+ # Postfix 2.2.
+ # Add missing tlsmgr service to master.cf.
+
+ grep '^tlsmgr.*tlsmgr' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for tlsmgr service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+tlsmgr unix - - n 1000? 1 tlsmgr
+EOF
+ }
+
+ # Postfix 2.2.
+ # Add missing retry service to master.cf.
+
+ grep '^retry.*error' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for retry service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+retry unix - - n - - error
+EOF
+ }
+
+ # Postfix 2.5.
+ # Add missing proxywrite service to master.cf.
+
+ grep '^proxywrite.*proxymap' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for proxywrite service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+proxywrite unix - - n - 1 proxymap
+EOF
+ }
+
+ # Postfix 2.5.
+ # Fix a typo in the default master.cf proxywrite entry.
+
+ grep '^proxywrite.*-[ ]*proxymap' $config_directory/master.cf >/dev/null && {
+ echo Editing $config_directory/master.cf, setting proxywrite process limit to 1
+ ed $config_directory/master.cf <<EOF || exit 1
+/^proxywrite.*-[ ]*proxymap/
+s/-\([ ]*proxymap\)/1\1/
+p
+w
+q
+EOF
+ }
+
+ # Postfix 2.8.
+ # Add missing postscreen service to master.cf.
+
+ grep '^#*smtp.*postscreen' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for postscreen TCP service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+#smtp inet n - n - 1 postscreen
+EOF
+ }
+
+ # Postfix 2.8.
+ # Add missing smtpd (unix-domain) service to master.cf.
+
+ grep '^#*smtpd.*smtpd' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for smtpd unix-domain service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+#smtpd pass - - n - - smtpd
+EOF
+ }
+
+ # Postfix 2.8.
+ # Add temporary dnsblog (unix-domain) service to master.cf.
+
+ grep '^#*dnsblog.*dnsblog' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for dnsblog unix-domain service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+#dnsblog unix - - n - 0 dnsblog
+EOF
+ }
+
+ # Postfix 2.8.
+ # Add tlsproxy (unix-domain) service to master.cf.
+
+ grep '^#*tlsproxy.*tlsproxy' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for tlsproxy unix-domain service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+#tlsproxy unix - - n - 0 tlsproxy
+EOF
+ }
+
+ # Report (but do not remove) obsolete files.
+
+ test -n "$obsolete" && {
+ cat <<EOF | ${FMT}
+
+ Note: the following files or directories still exist but are
+ no longer part of Postfix:
+
+ $obsolete
+
+EOF
+ }
+
+ # Postfix 2.9.
+ # Safety net for incompatible changes in IPv6 defaults.
+ # PLEASE DO NOT REMOVE THIS CODE. ITS PURPOSE IS TO AVOID AN
+ # UNEXPECTED DROP IN PERFORMANCE AFTER UPGRADING FROM POSTFIX
+ # BEFORE 2.9.
+ # This code assumes that the default is "inet_protocols = ipv4"
+ # when IPv6 support is not compiled in. See util/sys_defs.h.
+
+ test "`$POSTCONF -dh inet_protocols`" = "ipv4" ||
+ test -n "`$POSTCONF -c $config_directory -n inet_protocols`" || {
+ cat <<EOF | ${FMT}
+ COMPATIBILITY: editing $config_directory/main.cf, setting
+ inet_protocols=ipv4. Specify inet_protocols explicitly if you
+ want to enable IPv6.
+ In a future release IPv6 will be enabled by default.
+EOF
+ $POSTCONF -c $config_directory inet_protocols=ipv4 || exit 1
+ }
+
+# Disabled because unhelpful down-stream maintainers disable the safety net.
+# # Postfix 2.10.
+# # Safety net for incompatible changes due to the introduction
+# # of the smtpd_relay_restrictions feature to separate the
+# # mail relay policy from the spam blocking policy.
+# # PLEASE DO NOT REMOVE THIS CODE. ITS PURPOSE IS TO PREVENT
+# # INBOUND MAIL FROM UNEXPECTEDLY BOUNCING AFTER UPGRADING FROM
+# # POSTFIX BEFORE 2.10.
+# test -n "`$POSTCONF -c $config_directory -n smtpd_relay_restrictions`" || {
+# cat <<EOF | ${FMT}
+# COMPATIBILITY: editing $config_directory/main.cf, overriding
+# smtpd_relay_restrictions to prevent inbound mail from
+# unexpectedly bouncing.
+# Specify an empty smtpd_relay_restrictions value to keep using
+# smtpd_recipient_restrictions as before.
+#EOF
+# $POSTCONF -c $config_directory "smtpd_relay_restrictions = \
+# permit_mynetworks permit_sasl_authenticated \
+# defer_unauth_destination" || exit 1
+# }
+
+ # Postfix 3.4
+ # Add a postlog service entry.
+
+ grep '^postlog' $config_directory/master.cf >/dev/null || {
+ echo Editing $config_directory/master.cf, adding missing entry for postlog unix-domain datagram service
+ cat >>$config_directory/master.cf <<EOF || exit 1
+postlog unix-dgram n - n - 1 postlogd
+EOF
+ }
+}
+
+# A reminder if this is the first time Postfix is being installed.
+
+test -n "$first_install_reminder" && {
+
+ ALIASES=`$POSTCONF -c $config_directory -h alias_database | sed 's/^[^:]*://'`
+ NEWALIASES_PATH=`$POSTCONF -c $config_directory -h newaliases_path`
+ cat <<EOF | ${FMT}
+
+ Warning: you still need to edit myorigin/mydestination/mynetworks
+ parameter settings in $config_directory/main.cf.
+
+ See also http://www.postfix.org/STANDARD_CONFIGURATION_README.html
+ for information about dialup sites or about sites inside a
+ firewalled network.
+
+ BTW: Check your $ALIASES file and be sure to set up aliases
+ that send mail for root and postmaster to a real person, then
+ run $NEWALIASES_PATH.
+
+EOF
+
+}
+
+exit 0
diff --git a/conf/postfix-files b/conf/postfix-files
new file mode 100644
index 0000000..4ed9d1f
--- /dev/null
+++ b/conf/postfix-files
@@ -0,0 +1,459 @@
+#
+# Do not edit this file.
+#
+# This file controls the postfix-install script for installation of
+# Postfix programs, configuration files and documentation, as well
+# as the post-install script for setting permissions and for updating
+# Postfix configuration files. See the respective manual pages within
+# the script files.
+#
+# Do not list $command_directory or $shlib_directory in this file,
+# or it will be blown away by a future Postfix uninstallation
+# procedure. You would not want to lose all files in /usr/sbin or
+# /usr/local/lib.
+#
+# Each record in this file describes one file or directory.
+# Fields are separated by ":". Specify a null field as "-".
+# Missing fields or separators at the end are OK.
+#
+# File format:
+# name:type:owner:group:permission:flags
+# No group means don't change group ownership.
+#
+# File types:
+# d=directory
+# f=regular file
+# h=hard link (*)
+# l=symbolic link (*)
+#
+# (*) With hard links and symbolic links, the owner field becomes the
+# source pathname, while the group and permissions are ignored.
+#
+# File flags:
+# No flag means the flag is not active.
+# p=preserve existing file, do not replace (postfix-install).
+# u=update owner/group/mode (post-install upgrade-permissions).
+# c=create missing directory (post-install create-missing).
+# r=apply owner/group recursively (post-install set/upgrade-permissions).
+# o=obsolete, no longer part of Postfix
+# 1=optional for non-default instance (config_dir != built-in default).
+#
+# Note: the "u" flag is for upgrading the permissions of existing files
+# or directories after changes in Postfix architecture. For robustness
+# it is a good idea to "u" all the files that have special ownership or
+# permissions, so that running "make install" fixes any glitches.
+#
+# Note: order matters. Update shared libraries and database plugins
+# before daemon/command-line programs.
+$config_directory:d:root:-:755:u
+$data_directory:d:$mail_owner:-:700:uc
+$daemon_directory:d:root:-:755:u
+$queue_directory:d:root:-:755:uc
+$sample_directory:d:root:-:755:o
+$readme_directory:d:root:-:755
+$html_directory:d:root:-:755
+$queue_directory/active:d:$mail_owner:-:700:ucr
+$queue_directory/bounce:d:$mail_owner:-:700:ucr
+$queue_directory/corrupt:d:$mail_owner:-:700:ucr
+$queue_directory/defer:d:$mail_owner:-:700:ucr
+$queue_directory/deferred:d:$mail_owner:-:700:ucr
+$queue_directory/flush:d:$mail_owner:-:700:ucr
+$queue_directory/hold:d:$mail_owner:-:700:ucr
+$queue_directory/incoming:d:$mail_owner:-:700:ucr
+$queue_directory/private:d:$mail_owner:-:700:uc
+$queue_directory/maildrop:d:$mail_owner:$setgid_group:730:uc
+$queue_directory/public:d:$mail_owner:$setgid_group:710:uc
+$queue_directory/pid:d:root:-:755:uc
+$queue_directory/saved:d:$mail_owner:-:700:ucr
+$queue_directory/trace:d:$mail_owner:-:700:ucr
+# Update shared libraries and plugins before daemon or command-line programs.
+$shlib_directory/lib${LIB_PREFIX}util${LIB_SUFFIX}:f:root:-:755
+$shlib_directory/lib${LIB_PREFIX}global${LIB_SUFFIX}:f:root:-:755
+$shlib_directory/lib${LIB_PREFIX}dns${LIB_SUFFIX}:f:root:-:755
+$shlib_directory/lib${LIB_PREFIX}tls${LIB_SUFFIX}:f:root:-:755
+$shlib_directory/lib${LIB_PREFIX}master${LIB_SUFFIX}:f:root:-:755
+$shlib_directory/${LIB_PREFIX}cdb${LIB_SUFFIX}:f:root:-:755
+$shlib_directory/${LIB_PREFIX}ldap${LIB_SUFFIX}:f:root:-:755
+$shlib_directory/${LIB_PREFIX}lmdb${LIB_SUFFIX}:f:root:-:755
+$shlib_directory/${LIB_PREFIX}mysql${LIB_SUFFIX}:f:root:-:755
+$shlib_directory/${LIB_PREFIX}pcre${LIB_SUFFIX}:f:root:-:755
+$shlib_directory/${LIB_PREFIX}pgsql${LIB_SUFFIX}:f:root:-:755
+$shlib_directory/${LIB_PREFIX}sdbm${LIB_SUFFIX}:f:root:-:755
+$shlib_directory/${LIB_PREFIX}sqlite${LIB_SUFFIX}:f:root:-:755
+$meta_directory/dynamicmaps.cf.d:d:root:-:755
+$meta_directory/dynamicmaps.cf:f:root:-:644
+$meta_directory/main.cf.proto:f:root:-:644
+$meta_directory/makedefs.out:f:root:-:644
+$meta_directory/master.cf.proto:f:root:-:644
+$meta_directory/postfix-files.d:d:root:-:755
+$meta_directory/postfix-files:f:root:-:644
+$daemon_directory/anvil:f:root:-:755
+$daemon_directory/bounce:f:root:-:755
+$daemon_directory/cleanup:f:root:-:755
+$daemon_directory/discard:f:root:-:755
+$daemon_directory/dnsblog:f:root:-:755
+$daemon_directory/error:f:root:-:755
+$daemon_directory/flush:f:root:-:755
+$daemon_directory/local:f:root:-:755
+$daemon_directory/main.cf:f:root:-:644:o
+$daemon_directory/master.cf:f:root:-:644:o
+$daemon_directory/master:f:root:-:755
+$daemon_directory/oqmgr:f:root:-:755
+$daemon_directory/pickup:f:root:-:755
+$daemon_directory/pipe:f:root:-:755
+$daemon_directory/post-install:f:root:-:755
+# In case meta_directory == daemon_directory.
+#$daemon_directory/postfix-files:f:root:-:644:o
+#$daemon_directory/postfix-files.d:d:root:-:755:o
+$daemon_directory/postfix-script:f:root:-:755
+$daemon_directory/postfix-tls-script:f:root:-:755
+$daemon_directory/postfix-wrapper:f:root:-:755
+$daemon_directory/postmulti-script:f:root:-:755
+$daemon_directory/postlogd:f:root:-:755
+$daemon_directory/postscreen:f:root:-:755
+$daemon_directory/proxymap:f:root:-:755
+$daemon_directory/qmgr:f:root:-:755
+$daemon_directory/qmqpd:f:root:-:755
+$daemon_directory/scache:f:root:-:755
+$daemon_directory/showq:f:root:-:755
+$daemon_directory/smtp:f:root:-:755
+$daemon_directory/smtpd:f:root:-:755
+$daemon_directory/spawn:f:root:-:755
+$daemon_directory/tlsproxy:f:root:-:755
+$daemon_directory/tlsmgr:f:root:-:755
+$daemon_directory/trivial-rewrite:f:root:-:755
+$daemon_directory/verify:f:root:-:755
+$daemon_directory/virtual:f:root:-:755
+$daemon_directory/nqmgr:h:$daemon_directory/qmgr
+$daemon_directory/lmtp:h:$daemon_directory/smtp
+$command_directory/postalias:f:root:-:755
+$command_directory/postcat:f:root:-:755
+$command_directory/postconf:f:root:-:755
+$command_directory/postfix:f:root:-:755
+$command_directory/postkick:f:root:-:755
+$command_directory/postlock:f:root:-:755
+$command_directory/postlog:f:root:-:755
+$command_directory/postmap:f:root:-:755
+$command_directory/postmulti:f:root:-:755
+$command_directory/postsuper:f:root:-:755
+$command_directory/postdrop:f:root:$setgid_group:2755:u
+$command_directory/postqueue:f:root:$setgid_group:2755:u
+$sendmail_path:f:root:-:755
+$newaliases_path:l:$sendmail_path
+$mailq_path:l:$sendmail_path
+$config_directory/LICENSE:f:root:-:644:1
+$config_directory/TLS_LICENSE:f:root:-:644:1
+$config_directory/access:f:root:-:644:p1
+$config_directory/aliases:f:root:-:644:p1
+$config_directory/bounce.cf.default:f:root:-:644:1
+$config_directory/canonical:f:root:-:644:p1
+$config_directory/cidr_table:f:root:-:644:o
+$config_directory/generic:f:root:-:644:p1
+$config_directory/generics:f:root:-:644:o
+$config_directory/header_checks:f:root:-:644:p1
+$config_directory/install.cf:f:root:-:644:o
+$config_directory/main.cf.default:f:root:-:644:1
+$config_directory/main.cf:f:root:-:644:p
+$config_directory/master.cf:f:root:-:644:p
+$config_directory/pcre_table:f:root:-:644:o
+$config_directory/regexp_table:f:root:-:644:o
+$config_directory/relocated:f:root:-:644:p1
+$config_directory/tcp_table:f:root:-:644:o
+$config_directory/transport:f:root:-:644:p1
+$config_directory/virtual:f:root:-:644:p1
+$config_directory/postfix-script:f:root:-:755:o
+$config_directory/postfix-script-sgid:f:root:-:755:o
+$config_directory/postfix-script-nosgid:f:root:-:755:o
+$config_directory/post-install:f:root:-:755:o
+$manpage_directory/man1/mailq.1:f:root:-:644
+$manpage_directory/man1/newaliases.1:f:root:-:644
+$manpage_directory/man1/postalias.1:f:root:-:644
+$manpage_directory/man1/postcat.1:f:root:-:644
+$manpage_directory/man1/postconf.1:f:root:-:644
+$manpage_directory/man1/postdrop.1:f:root:-:644
+$manpage_directory/man1/postfix.1:f:root:-:644
+$manpage_directory/man1/postfix-tls.1:f:root:-:644
+$manpage_directory/man1/postkick.1:f:root:-:644
+$manpage_directory/man1/postlock.1:f:root:-:644
+$manpage_directory/man1/postlog.1:f:root:-:644
+$manpage_directory/man1/postmap.1:f:root:-:644
+$manpage_directory/man1/postmulti.1:f:root:-:644
+$manpage_directory/man1/postqueue.1:f:root:-:644
+$manpage_directory/man1/postsuper.1:f:root:-:644
+$manpage_directory/man1/sendmail.1:f:root:-:644
+$manpage_directory/man5/access.5:f:root:-:644
+$manpage_directory/man5/aliases.5:f:root:-:644
+$manpage_directory/man5/body_checks.5:f:root:-:644
+$manpage_directory/man5/bounce.5:f:root:-:644
+$manpage_directory/man5/canonical.5:f:root:-:644
+$manpage_directory/man5/cidr_table.5:f:root:-:644
+$manpage_directory/man5/generics.5:f:root:-:644:o
+$manpage_directory/man5/generic.5:f:root:-:644
+$manpage_directory/man5/header_checks.5:f:root:-:644
+$manpage_directory/man5/ldap_table.5:f:root:-:644
+$manpage_directory/man5/lmdb_table.5:f:root:-:644
+$manpage_directory/man5/master.5:f:root:-:644
+$manpage_directory/man5/memcache_table.5:f:root:-:644
+$manpage_directory/man5/mysql_table.5:f:root:-:644
+$manpage_directory/man5/socketmap_table.5:f:root:-:644
+$manpage_directory/man5/sqlite_table.5:f:root:-:644
+$manpage_directory/man5/nisplus_table.5:f:root:-:644
+$manpage_directory/man5/pcre_table.5:f:root:-:644
+$manpage_directory/man5/pgsql_table.5:f:root:-:644
+$manpage_directory/man5/postconf.5:f:root:-:644
+$manpage_directory/man5/postfix-wrapper.5:f:root:-:644
+$manpage_directory/man5/regexp_table.5:f:root:-:644
+$manpage_directory/man5/relocated.5:f:root:-:644
+$manpage_directory/man5/tcp_table.5:f:root:-:644
+$manpage_directory/man5/transport.5:f:root:-:644
+$manpage_directory/man5/virtual.5:f:root:-:644
+$manpage_directory/man8/bounce.8:f:root:-:644
+$manpage_directory/man8/cleanup.8:f:root:-:644
+$manpage_directory/man8/anvil.8:f:root:-:644
+$manpage_directory/man8/defer.8:f:root:-:644
+$manpage_directory/man8/discard.8:f:root:-:644
+$manpage_directory/man8/dnsblog.8:f:root:-:644
+$manpage_directory/man8/error.8:f:root:-:644
+$manpage_directory/man8/flush.8:f:root:-:644
+$manpage_directory/man8/lmtp.8:f:root:-:644
+$manpage_directory/man8/local.8:f:root:-:644
+$manpage_directory/man8/master.8:f:root:-:644
+$manpage_directory/man8/nqmgr.8:f:root:-:644:o
+$manpage_directory/man8/oqmgr.8:f:root:-:644:
+$manpage_directory/man8/pickup.8:f:root:-:644
+$manpage_directory/man8/pipe.8:f:root:-:644
+$manpage_directory/man8/postlogd.8:f:root:-:644
+$manpage_directory/man8/postscreen.8:f:root:-:644
+$manpage_directory/man8/proxymap.8:f:root:-:644
+$manpage_directory/man8/qmgr.8:f:root:-:644
+$manpage_directory/man8/qmqpd.8:f:root:-:644
+$manpage_directory/man8/scache.8:f:root:-:644
+$manpage_directory/man8/showq.8:f:root:-:644
+$manpage_directory/man8/smtp.8:f:root:-:644
+$manpage_directory/man8/smtpd.8:f:root:-:644
+$manpage_directory/man8/spawn.8:f:root:-:644
+$manpage_directory/man8/tlsproxy.8:f:root:-:644
+$manpage_directory/man8/tlsmgr.8:f:root:-:644
+$manpage_directory/man8/trace.8:f:root:-:644
+$manpage_directory/man8/trivial-rewrite.8:f:root:-:644
+$manpage_directory/man8/verify.8:f:root:-:644
+$manpage_directory/man8/virtual.8:f:root:-:644
+$sample_directory/sample-aliases.cf:f:root:-:644:o
+$sample_directory/sample-auth.cf:f:root:-:644:o
+$sample_directory/sample-canonical.cf:f:root:-:644:o
+$sample_directory/sample-compatibility.cf:f:root:-:644:o
+$sample_directory/sample-debug.cf:f:root:-:644:o
+$sample_directory/sample-filter.cf:f:root:-:644:o
+$sample_directory/sample-flush.cf:f:root:-:644:o
+$sample_directory/sample-ipv6.cf:f:root:-:644:o
+$sample_directory/sample-ldap.cf:f:root:-:644:o
+$sample_directory/sample-lmtp.cf:f:root:-:644:o
+$sample_directory/sample-local.cf:f:root:-:644:o
+$sample_directory/sample-mime.cf:f:root:-:644:o
+$sample_directory/sample-misc.cf:f:root:-:644:o
+$sample_directory/sample-pcre-access.cf:f:root:-:644:o
+$sample_directory/sample-pcre-body.cf:f:root:-:644:o
+$sample_directory/sample-pcre-header.cf:f:root:-:644:o
+$sample_directory/sample-pgsql-aliases.cf:f:root:-:644:o
+$sample_directory/sample-qmqpd.cf:f:root:-:644:o
+$sample_directory/sample-rate.cf:f:root:-:644:o
+$sample_directory/sample-regexp-access.cf:f:root:-:644:o
+$sample_directory/sample-regexp-body.cf:f:root:-:644:o
+$sample_directory/sample-regexp-header.cf:f:root:-:644:o
+$sample_directory/sample-relocated.cf:f:root:-:644:o
+$sample_directory/sample-resource.cf:f:root:-:644:o
+$sample_directory/sample-rewrite.cf:f:root:-:644:o
+$sample_directory/sample-scheduler.cf:f:root:-:644:o
+$sample_directory/sample-smtp.cf:f:root:-:644:o
+$sample_directory/sample-smtpd.cf:f:root:-:644:o
+$sample_directory/sample-tls.cf:f:root:-:644:o
+$sample_directory/sample-transport.cf:f:root:-:644:o
+$sample_directory/sample-verify.cf:f:root:-:644:o
+$sample_directory/sample-virtual.cf:f:root:-:644:o
+$readme_directory/AAAREADME:f:root:-:644
+$readme_directory/ADDRESS_CLASS_README:f:root:-:644
+$readme_directory/ADDRESS_REWRITING_README:f:root:-:644
+$readme_directory/ADDRESS_VERIFICATION_README:f:root:-:644
+$readme_directory/BACKSCATTER_README:f:root:-:644
+$readme_directory/BASIC_CONFIGURATION_README:f:root:-:644
+$readme_directory/BUILTIN_FILTER_README:f:root:-:644
+$readme_directory/CDB_README:f:root:-:644
+$readme_directory/COMPATIBILITY_README:f:root:-:644
+$readme_directory/CONNECTION_CACHE_README:f:root:-:644
+$readme_directory/CONTENT_INSPECTION_README:f:root:-:644
+$readme_directory/DATABASE_README:f:root:-:644
+$readme_directory/DB_README:f:root:-:644
+$readme_directory/DEBUG_README:f:root:-:644
+$readme_directory/DSN_README:f:root:-:644
+$readme_directory/ETRN_README:f:root:-:644
+$readme_directory/FILTER_README:f:root:-:644
+$readme_directory/FORWARD_SECRECY_README:f:root:-:644
+$readme_directory/HOSTING_README:f:root:-:644:o
+$readme_directory/INSTALL:f:root:-:644
+$readme_directory/IPV6_README:f:root:-:644
+$readme_directory/LDAP_README:f:root:-:644
+$readme_directory/LINUX_README:f:root:-:644
+$readme_directory/LMDB_README:f:root:-:644
+$readme_directory/LOCAL_RECIPIENT_README:f:root:-:644
+$readme_directory/MACOSX_README:f:root:-:644:o
+$readme_directory/MAILDROP_README:f:root:-:644
+$readme_directory/MEMCACHE_README:f:root:-:644
+$readme_directory/MILTER_README:f:root:-:644
+$readme_directory/MULTI_INSTANCE_README:f:root:-:644
+$readme_directory/MYSQL_README:f:root:-:644
+$readme_directory/SQLITE_README:f:root:-:644
+$readme_directory/NFS_README:f:root:-:644
+$readme_directory/OVERVIEW:f:root:-:644
+$readme_directory/PACKAGE_README:f:root:-:644
+$readme_directory/PCRE_README:f:root:-:644
+$readme_directory/PGSQL_README:f:root:-:644
+$readme_directory/POSTSCREEN_README:f:root:-:644
+$readme_directory/QMQP_README:f:root:-:644:o
+$readme_directory/QSHAPE_README:f:root:-:644
+$readme_directory/RELEASE_NOTES:f:root:-:644
+$readme_directory/RESTRICTION_CLASS_README:f:root:-:644
+$readme_directory/SASL_README:f:root:-:644
+$readme_directory/SCHEDULER_README:f:root:-:644
+$readme_directory/SMTPD_ACCESS_README:f:root:-:644
+$readme_directory/SMTPD_POLICY_README:f:root:-:644
+$readme_directory/SMTPD_PROXY_README:f:root:-:644
+$readme_directory/SOHO_README:f:root:-:644
+$readme_directory/STANDARD_CONFIGURATION_README:f:root:-:644
+$readme_directory/STRESS_README:f:root:-:644
+$readme_directory/TLS_LEGACY_README:f:root:-:644
+$readme_directory/TLS_README:f:root:-:644
+$readme_directory/TUNING_README:f:root:-:644
+$readme_directory/ULTRIX_README:f:root:-:644
+$readme_directory/UUCP_README:f:root:-:644
+$readme_directory/VERP_README:f:root:-:644
+$readme_directory/VIRTUAL_README:f:root:-:644
+$readme_directory/XCLIENT_README:f:root:-:644
+$readme_directory/XFORWARD_README:f:root:-:644
+$html_directory/ADDRESS_CLASS_README.html:f:root:-:644
+$html_directory/ADDRESS_REWRITING_README.html:f:root:-:644
+$html_directory/ADDRESS_VERIFICATION_README.html:f:root:-:644
+$html_directory/BACKSCATTER_README.html:f:root:-:644
+$html_directory/BASIC_CONFIGURATION_README.html:f:root:-:644
+$html_directory/BUILTIN_FILTER_README.html:f:root:-:644
+$html_directory/CDB_README.html:f:root:-:644
+$html_directory/COMPATIBILITY_README.html:f:root:-:644
+$html_directory/CONNECTION_CACHE_README.html:f:root:-:644
+$html_directory/CONTENT_INSPECTION_README.html:f:root:-:644
+$html_directory/CYRUS_README.html:f:root:-:644:o
+$html_directory/DATABASE_README.html:f:root:-:644
+$html_directory/DB_README.html:f:root:-:644
+$html_directory/DEBUG_README.html:f:root:-:644
+$html_directory/DSN_README.html:f:root:-:644
+$html_directory/ETRN_README.html:f:root:-:644
+$html_directory/FILTER_README.html:f:root:-:644
+$html_directory/FORWARD_SECRECY_README.html:f:root:-:644
+$html_directory/INSTALL.html:f:root:-:644
+$html_directory/IPV6_README.html:f:root:-:644
+$html_directory/LDAP_README.html:f:root:-:644
+$html_directory/LINUX_README.html:f:root:-:644
+$html_directory/LMDB_README.html:f:root:-:644
+$html_directory/LOCAL_RECIPIENT_README.html:f:root:-:644
+$html_directory/MAILDROP_README.html:f:root:-:644
+$html_directory/MILTER_README.html:f:root:-:644
+$html_directory/MULTI_INSTANCE_README.html:f:root:-:644
+$html_directory/MYSQL_README.html:f:root:-:644
+$html_directory/SQLITE_README.html:f:root:-:644
+$html_directory/NFS_README.html:f:root:-:644
+$html_directory/OVERVIEW.html:f:root:-:644
+$html_directory/PACKAGE_README.html:f:root:-:644
+$html_directory/PCRE_README.html:f:root:-:644
+$html_directory/PGSQL_README.html:f:root:-:644
+$html_directory/POSTSCREEN_README.html:f:root:-:644
+$html_directory/QMQP_README.html:f:root:-:644:o
+$html_directory/QSHAPE_README.html:f:root:-:644
+$html_directory/RESTRICTION_CLASS_README.html:f:root:-:644
+$html_directory/SASL_README.html:f:root:-:644
+$html_directory/SCHEDULER_README.html:f:root:-:644
+$html_directory/SMTPD_ACCESS_README.html:f:root:-:644
+$html_directory/SMTPD_POLICY_README.html:f:root:-:644
+$html_directory/SMTPD_PROXY_README.html:f:root:-:644
+$html_directory/SOHO_README.html:f:root:-:644
+$html_directory/STANDARD_CONFIGURATION_README.html:f:root:-:644
+$html_directory/STRESS_README.html:f:root:-:644
+$html_directory/TLS_LEGACY_README.html:f:root:-:644
+$html_directory/TLS_README.html:f:root:-:644
+$html_directory/TUNING_README.html:f:root:-:644
+$html_directory/ULTRIX_README.html:f:root:-:644:o
+$html_directory/UUCP_README.html:f:root:-:644
+$html_directory/VERP_README.html:f:root:-:644
+$html_directory/VIRTUAL_README.html:f:root:-:644
+$html_directory/XCLIENT_README.html:f:root:-:644
+$html_directory/XFORWARD_README.html:f:root:-:644
+$html_directory/access.5.html:f:root:-:644
+$html_directory/aliases.5.html:f:root:-:644
+$html_directory/anvil.8.html:f:root:-:644
+$html_directory/bounce.8.html:f:root:-:644
+$html_directory/canonical.5.html:f:root:-:644
+$html_directory/cidr_table.5.html:f:root:-:644
+$html_directory/cleanup.8.html:f:root:-:644
+$html_directory/defer.8.html:h:$html_directory/bounce.8.html:-:644
+$html_directory/discard.8.html:f:root:-:644
+$html_directory/dnsblog.8.html:f:root:-:644
+$html_directory/error.8.html:f:root:-:644
+$html_directory/flush.8.html:f:root:-:644
+$html_directory/generics.5.html:f:root:-:644:o
+$html_directory/generic.5.html:f:root:-:644
+$html_directory/header_checks.5.html:f:root:-:644
+$html_directory/index.html:f:root:-:644
+$html_directory/ldap_table.5.html:f:root:-:644
+$html_directory/lmtp.8.html:f:root:-:644
+$html_directory/local.8.html:f:root:-:644
+$html_directory/mailq.1.html:f:root:-:644
+$html_directory/master.5.html:f:root:-:644
+$html_directory/master.8.html:f:root:-:644
+$html_directory/memcache_table.5.html:f:root:-:644
+$html_directory/mysql_table.5.html:f:root:-:644
+$html_directory/sqlite_table.5.html:f:root:-:644
+$html_directory/nisplus_table.5.html:f:root:-:644
+$html_directory/newaliases.1.html:h:$html_directory/mailq.1.html:-:644
+$html_directory/oqmgr.8.html:f:root:-:644
+$html_directory/pcre_table.5.html:f:root:-:644
+$html_directory/pgsql_table.5.html:f:root:-:644
+$html_directory/pickup.8.html:f:root:-:644
+$html_directory/pipe.8.html:f:root:-:644
+$html_directory/postalias.1.html:f:root:-:644
+$html_directory/postcat.1.html:f:root:-:644
+$html_directory/postconf.1.html:f:root:-:644
+$html_directory/postconf.5.html:f:root:-:644
+$html_directory/postdrop.1.html:f:root:-:644
+$html_directory/postfix-logo.jpg:f:root:-:644
+$html_directory/postfix-manuals.html:f:root:-:644
+$html_directory/postfix-wrapper.5.html:f:root:-:644
+$html_directory/postfix.1.html:f:root:-:644
+$html_directory/postkick.1.html:f:root:-:644
+$html_directory/postlock.1.html:f:root:-:644
+$html_directory/postlog.1.html:f:root:-:644
+$html_directory/postmap.1.html:f:root:-:644
+$html_directory/postmulti.1.html:f:root:-:644
+$html_directory/postlogd.8.html:f:root:-:644
+$html_directory/postqueue.1.html:f:root:-:644
+$html_directory/postscreen.8.html:f:root:-:644
+$html_directory/postsuper.1.html:f:root:-:644
+$html_directory/qshape.1.html:f:root:-:644
+$html_directory/proxymap.8.html:f:root:-:644
+$html_directory/qmgr.8.html:f:root:-:644
+$html_directory/qmqp-sink.1.html:f:root:-:644
+$html_directory/qmqp-source.1.html:f:root:-:644
+$html_directory/qmqpd.8.html:f:root:-:644
+$html_directory/regexp_table.5.html:f:root:-:644
+$html_directory/relocated.5.html:f:root:-:644
+$html_directory/sendmail.1.html:h:$html_directory/mailq.1.html:-:644
+$html_directory/showq.8.html:f:root:-:644
+$html_directory/smtp-sink.1.html:f:root:-:644
+$html_directory/smtp-source.1.html:f:root:-:644
+$html_directory/smtp.8.html:h:$html_directory/lmtp.8.html:-:644
+$html_directory/smtpd.8.html:f:root:-:644
+$html_directory/spawn.8.html:f:root:-:644
+$html_directory/tlsproxy.8.html:f:root:-:644
+$html_directory/tcp_table.5.html:f:root:-:644
+$html_directory/trace.8.html:h:$html_directory/bounce.8.html:-:644
+$html_directory/transport.5.html:f:root:-:644
+$html_directory/trivial-rewrite.8.html:f:root:-:644
+$html_directory/verify.8.html:f:root:-:644
+$html_directory/virtual.5.html:f:root:-:644
+$html_directory/virtual.8.html:f:root:-:644
diff --git a/conf/postfix-script b/conf/postfix-script
new file mode 100755
index 0000000..93d8a1f
--- /dev/null
+++ b/conf/postfix-script
@@ -0,0 +1,446 @@
+#!/bin/sh
+
+#++
+# NAME
+# postfix-script 1
+# SUMMARY
+# execute Postfix administrative commands
+# SYNOPSIS
+# \fBpostfix-script\fR \fIcommand\fR
+# DESCRIPTION
+# The \fBpostfix-script\fR script executes Postfix administrative
+# commands in an environment that is set up by the \fBpostfix\fR(1)
+# command.
+# SEE ALSO
+# master(8) Postfix master program
+# postfix(1) Postfix administrative interface
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
+
+# Avoid POSIX death due to SIGHUP when some parent process exits.
+
+trap '' 1
+
+case $daemon_directory in
+"") echo This script must be run by the postfix command. 1>&2
+ echo Do not run directly. 1>&2
+ exit 1
+esac
+
+LOGGER="$command_directory/postlog -t $MAIL_LOGTAG/postfix-script"
+INFO="$LOGGER -p info"
+WARN="$LOGGER -p warn"
+ERROR="$LOGGER -p error"
+FATAL="$LOGGER -p fatal"
+PANIC="$LOGGER -p panic"
+
+umask 022
+SHELL=/bin/sh
+
+#
+# Can't do much without these in place.
+#
+cd $command_directory || {
+ $FATAL no Postfix command directory $command_directory!
+ exit 1
+}
+cd $daemon_directory || {
+ $FATAL no Postfix daemon directory $daemon_directory!
+ exit 1
+}
+test -f master || {
+ $FATAL no Postfix master program $daemon_directory/master!
+ exit 1
+}
+cd $config_directory || {
+ $FATAL no Postfix configuration directory $config_directory!
+ exit 1
+}
+case $shlib_directory in
+no) ;;
+ *) cd $shlib_directory || {
+ $FATAL no Postfix shared-library directory $shlib_directory!
+ exit 1
+ }
+esac
+cd $meta_directory || {
+ $FATAL no Postfix meta directory $meta_directory!
+ exit 1
+}
+cd $queue_directory || {
+ $FATAL no Postfix queue directory $queue_directory!
+ exit 1
+}
+def_config_directory=`$command_directory/postconf -dh config_directory` || {
+ $FATAL cannot execute $command_directory/postconf!
+ exit 1
+}
+
+# If this is a secondary instance, don't touch shared files.
+
+instances=`test ! -f $def_config_directory/main.cf ||
+ $command_directory/postconf -c $def_config_directory \
+ -h multi_instance_directories | sed 's/,/ /'` || {
+ $FATAL cannot execute $command_directory/postconf!
+ exit 1
+}
+
+check_shared_files=1
+for name in $instances
+do
+ case "$name" in
+ "$def_config_directory") ;;
+ "$config_directory") check_shared_files=; break;;
+ esac
+done
+
+#
+# Parse JCL
+#
+case $1 in
+
+start_msg)
+
+ echo "Start postfix"
+ ;;
+
+stop_msg)
+
+ echo "Stop postfix"
+ ;;
+
+start|start-fg)
+
+ $daemon_directory/master -t 2>/dev/null || {
+ $FATAL the Postfix mail system is already running
+ exit 1
+ }
+ if [ -f $queue_directory/quick-start ]
+ then
+ rm -f $queue_directory/quick-start
+ else
+ $daemon_directory/postfix-script check-fatal || {
+ $FATAL Postfix integrity check failed!
+ exit 1
+ }
+ # Foreground this so it can be stopped. All inodes are cached.
+ $daemon_directory/postfix-script check-warn
+ fi
+ $INFO starting the Postfix mail system || exit 1
+ case $1 in
+ start)
+ # NOTE: wait in foreground process to get the initialization status.
+ $daemon_directory/master -w || {
+ $FATAL "mail system startup failed"
+ exit 1
+ }
+ ;;
+ start-fg)
+ # Foreground start-up is incompatible with multi-instance mode.
+ # Use "exec $daemon_directory/master" only if PID == 1.
+ # Otherwise, doing so would break process group management,
+ # and "postfix stop" would kill too many processes.
+ case $instances in
+ "") case $$ in
+ 1) exec $daemon_directory/master -i
+ $FATAL "cannot start-fg the master daemon"
+ exit 1;;
+ *) $daemon_directory/master -s;;
+ esac
+ ;;
+ *) $FATAL "start-fg does not support multi_instance_directories"
+ exit 1
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+drain)
+
+ $daemon_directory/master -t 2>/dev/null && {
+ $FATAL the Postfix mail system is not running
+ exit 1
+ }
+ $INFO stopping the Postfix mail system
+ kill -9 `sed 1q pid/master.pid`
+ ;;
+
+quick-stop)
+
+ $daemon_directory/postfix-script stop
+ touch $queue_directory/quick-start
+ ;;
+
+stop)
+
+ $daemon_directory/master -t 2>/dev/null && {
+ $FATAL the Postfix mail system is not running
+ exit 1
+ }
+ $INFO stopping the Postfix mail system
+ kill `sed 1q pid/master.pid`
+ for i in 5 4 3 2 1
+ do
+ $daemon_directory/master -t && exit 0
+ $INFO waiting for the Postfix mail system to terminate
+ sleep 1
+ done
+ $WARN stopping the Postfix mail system with force
+ pid=`awk '{ print $1; exit 0 } END { exit 1 }' pid/master.pid` &&
+ kill -9 -$pid
+ ;;
+
+abort)
+
+ $daemon_directory/master -t 2>/dev/null && {
+ $FATAL the Postfix mail system is not running
+ exit 1
+ }
+ $INFO aborting the Postfix mail system
+ kill `sed 1q pid/master.pid`
+ ;;
+
+reload)
+
+ $daemon_directory/master -t 2>/dev/null && {
+ $FATAL the Postfix mail system is not running
+ exit 1
+ }
+ $INFO refreshing the Postfix mail system
+ $command_directory/postsuper active || exit 1
+ kill -HUP `sed 1q pid/master.pid`
+ $command_directory/postsuper &
+ ;;
+
+flush)
+
+ cd $queue_directory || {
+ $FATAL no Postfix queue directory $queue_directory!
+ exit 1
+ }
+ $command_directory/postqueue -f
+ ;;
+
+check)
+
+ $daemon_directory/postfix-script check-fatal || exit 1
+ $daemon_directory/postfix-script check-warn
+ exit 0
+ ;;
+
+status)
+
+ $daemon_directory/master -t 2>/dev/null && {
+ $INFO the Postfix mail system is not running
+ exit 1
+ }
+ $INFO the Postfix mail system is running: PID: `sed 1q pid/master.pid`
+ exit 0
+ ;;
+
+
+check-fatal)
+ # This command is NOT part of the public interface.
+
+ $SHELL $daemon_directory/post-install create-missing || {
+ $FATAL unable to create missing queue directories
+ exit 1
+ }
+
+ # Look for incomplete installations.
+
+ test -f $config_directory/master.cf || {
+ $FATAL no $config_directory/master.cf file found
+ exit 1
+ }
+
+ maillog_file=`$command_directory/postconf -h maillog_file` || {
+ $FATAL cannot execute $command_directory/postconf!
+ exit 1
+ }
+ test -n "$maillog_file" && {
+ $command_directory/postconf -M postlog/unix-dgram 2>/dev/null \
+ | grep . >/dev/null || {
+ $FATAL "missing 'postlog' service in master.cf - run 'postfix upgrade-configuration'"
+ exit 1
+ }
+ }
+
+ # See if all queue files are in the right place. This is slow.
+ # We must scan all queues for mis-named queue files before the
+ # mail system can run.
+
+ $command_directory/postsuper || exit 1
+ exit 0
+ ;;
+
+check-warn)
+ # This command is NOT part of the public interface.
+
+ # Check Postfix root-owned directory owner/permissions.
+
+ find $queue_directory/. $queue_directory/pid \
+ -prune ! -user root \
+ -exec $WARN not owned by root: {} \;
+
+ find $queue_directory/. $queue_directory/pid \
+ -prune \( -perm -020 -o -perm -002 \) \
+ -exec $WARN group or other writable: {} \;
+
+ # Check Postfix root-owned directory tree owner/permissions.
+
+ todo="$config_directory/."
+ test -n "$check_shared_files" && {
+ todo="$daemon_directory/. $meta_directory/. $todo"
+ test "$shlib_directory" = "no" ||
+ todo="$shlib_directory/. $todo"
+ }
+ todo=`echo "$todo" | tr ' ' '\12' | sort -u`
+
+ find $todo ! -user root \
+ -exec $WARN not owned by root: {} \;
+
+ find $todo \( -perm -020 -o -perm -002 \) \
+ -exec $WARN group or other writable: {} \;
+
+ # Check Postfix mail_owner-owned directory tree owner/permissions.
+
+ find $data_directory/. ! -user $mail_owner \
+ -exec $WARN not owned by $mail_owner: {} \;
+
+ find $data_directory/. \( -perm -020 -o -perm -002 \) \
+ -exec $WARN group or other writable: {} \;
+
+ # Check Postfix mail_owner-owned directory tree owner.
+
+ find `ls -d $queue_directory/* | \
+ egrep '/(saved|incoming|active|defer|deferred|bounce|hold|trace|corrupt|public|private|flush)$'` \
+ ! \( -type p -o -type s \) ! -user $mail_owner \
+ -exec $WARN not owned by $mail_owner: {} \;
+
+ # WARNING: this should not descend into the maildrop directory.
+ # maildrop is the least trusted Postfix directory.
+
+ find $queue_directory/maildrop -prune ! -user $mail_owner \
+ -exec $WARN not owned by $mail_owner: $queue_directory/maildrop \;
+
+ # Check Postfix setgid_group-owned directory and file group/permissions.
+
+ todo="$queue_directory/public $queue_directory/maildrop"
+ test -n "$check_shared_files" &&
+ todo="$command_directory/postqueue $command_directory/postdrop $todo"
+
+ find $todo \
+ -prune ! -group $setgid_group \
+ -exec $WARN not owned by group $setgid_group: {} \;
+
+ test -n "$check_shared_files" &&
+ find $command_directory/postqueue $command_directory/postdrop \
+ -prune ! -perm -02111 \
+ -exec $WARN not set-gid or not owner+group+world executable: {} \;
+
+ # Check non-Postfix root-owned directory tree owner/content.
+
+ for dir in bin etc lib sbin usr
+ do
+ test -d $dir && {
+ find $dir ! -user root \
+ -exec $WARN not owned by root: $queue_directory/{} \;
+
+ find $dir -type f -print | while read path
+ do
+ test -f /$path && {
+ cmp -s $path /$path ||
+ $WARN $queue_directory/$path and /$path differ
+ }
+ done
+ }
+ done
+
+ find corrupt -type f -exec $WARN damaged message: {} \;
+
+ # Check for non-Postfix MTA remnants.
+
+ test -n "$check_shared_files" -a -f /usr/sbin/sendmail -a \
+ -f /usr/lib/sendmail && {
+ cmp -s /usr/sbin/sendmail /usr/lib/sendmail || {
+ $WARN /usr/lib/sendmail and /usr/sbin/sendmail differ
+ $WARN Replace one by a symbolic link to the other
+ }
+ }
+ exit 0
+ ;;
+
+set-permissions|upgrade-configuration)
+ $daemon_directory/post-install create-missing "$@"
+ ;;
+
+post-install)
+ # Currently not part of the public interface.
+ shift
+ $daemon_directory/post-install "$@"
+ ;;
+
+tls)
+ shift
+ $daemon_directory/postfix-tls-script "$@"
+ ;;
+
+/*)
+ # Currently not part of the public interface.
+ "$@"
+ ;;
+
+logrotate)
+ case $# in
+ 1) ;;
+ *) $FATAL "usage postfix $1 (no arguments)"; exit 1;;
+ esac
+ for name in maillog_file maillog_file_compressor \
+ maillog_file_rotate_suffix
+ do
+ value="`$command_directory/postconf -h $name`"
+ case "$value" in
+ "") $FATAL "empty '$name' parameter value - logfile rotation failed"
+ exit 1;;
+ esac
+ eval $name='"$value"';
+ done
+
+ case "$maillog_file" in
+ /dev/*) $FATAL "not rotating '$maillog_file'"; exit 1;;
+ esac
+
+ errors=`(
+ suffix="\`date +$maillog_file_rotate_suffix\`" || exit 1
+ mv "$maillog_file" "$maillog_file.$suffix" || exit 1
+ $daemon_directory/master -t 2>/dev/null ||
+ kill -HUP \`sed 1q pid/master.pid\` || exit 1
+ sleep 1
+ "$maillog_file_compressor" "$maillog_file.$suffix" || exit 1
+ ) 2>&1` || {
+ $FATAL "logfile '$maillog_file' rotation failed: $errors"
+ exit 1
+ }
+ ;;
+
+*)
+ $FATAL "unknown command: '$1'. Usage: postfix start (or stop, reload, abort, flush, check, status, set-permissions, upgrade-configuration, logrotate)"
+ exit 1
+ ;;
+
+esac
diff --git a/conf/postfix-tls-script b/conf/postfix-tls-script
new file mode 100644
index 0000000..1a364b7
--- /dev/null
+++ b/conf/postfix-tls-script
@@ -0,0 +1,1154 @@
+#!/bin/sh
+
+#++
+# NAME
+# postfix-tls 1
+# SUMMARY
+# Postfix TLS management
+# SYNOPSIS
+# \fBpostfix tls\fR \fIsubcommand\fR
+# DESCRIPTION
+# The "\fBpostfix tls \fIsubcommand\fR" feature enables
+# opportunistic TLS in the Postfix SMTP client or server, and
+# manages Postfix SMTP server private keys and certificates.
+#
+# The following subcommands are available:
+# .IP "\fBenable-client\fR [\fB-r \fIrandsource\fR]"
+# Enable opportunistic TLS in the Postfix SMTP client, if all
+# SMTP client TLS settings are at their default values.
+# Otherwise, suggest parameter settings without making any
+# changes.
+# .sp
+# Specify \fIrandsource\fR to update the value of the
+# \fBtls_random_source\fR configuration parameter (typically,
+# /dev/urandom). Prepend \fBdev:\fR to device paths or
+# \fBegd:\fR to EGD socket paths.
+# .sp
+# See also the \fBall-default-client\fR subcommand.
+# .IP "\fBenable-server\fR [\fB-r \fIrandsource\fR] [\fB-a \fIalgorithm\fR] [\fB-b \fIbits\fR] [\fIhostname\fB...\fR]"
+# Create a new private key and self-signed server certificate
+# and enable opportunistic TLS in the Postfix SMTP server,
+# if all SMTP server TLS settings are at their default values.
+# Otherwise, suggest parameter settings without making any
+# changes.
+# .sp
+# The \fIrandsource\fR parameter is as with \fBenable-client\fR
+# above, and the remaining options are as with \fBnew-server-key\fR
+# below.
+# .sp
+# See also the \fBall-default-server\fR subcommand.
+# .IP "\fBnew-server-key\fR [\fB-a \fIalgorithm\fR] [\fB-b \fIbits\fR] [\fIhostname\fB...\fR]"
+# Create a new private key and self-signed server certificate,
+# but do not deploy them. Log and display commands to deploy
+# the new key and corresponding certificate. Also log and
+# display commands to output a corresponding CSR or TLSA
+# records which may be needed to obtain a CA certificate or
+# to update DNS before the new key can be deployed.
+# .sp
+# The \fIalgorithm\fR defaults to \fBrsa\fR, and \fIbits\fR
+# defaults to 2048. If you choose the \fBecdsa\fR \fIalgorithm\fR
+# then \fIbits\fR will be an EC curve name (by default
+# \fBsecp256r1\fR, also known as prime256v1). Curves other
+# than \fBsecp256r1\fR, \fBsecp384r1\fR or \fBsecp521r1\fR
+# are unlikely to be widely interoperable. When generating
+# EC keys, use one of these three. DSA keys are obsolete and
+# are not supported.
+# .sp
+# Note: ECDSA support requires OpenSSL 1.0.0 or later and may
+# not be available on your system. Not all client systems
+# will support ECDSA, so you'll generally want to deploy both
+# RSA and ECDSA certificates to make use of ECDSA with
+# compatible clients and RSA with the rest. If you want to
+# deploy certificate chains with intermediate CAs for both
+# RSA and ECDSA, you'll want at least OpenSSL 1.0.2, as earlier
+# versions may not handle multiple chain files correctly.
+# .sp
+# The first \fIhostname\fR argument will be the \fBCommonName\fR
+# of both the subject and issuer of the self-signed certificate.
+# It, and any additional \fIhostname\fR arguments, will also
+# be listed as DNS alternative names in the certificate. If
+# no \fIhostname\fR is provided the value of the \fBmyhostname\fR
+# main.cf parameter will be used.
+# .sp
+# For RSA, the generated private key and certificate files
+# are named \fBkey-\fIyyyymmdd-hhmmss\fB.pem\fR and
+# \fBcert-\fIyyyymmdd-hhmmss\fB.pem\fR, where \fIyyyymmdd\fR
+# is the calendar date and \fIhhmmss\fR is the time of day
+# in UTC. For ECDSA, the file names start with \fBeckey-\fR
+# and \fBeccert-\fR instead of \fBkey-\fR and \fBcert-\fR
+# respectively.
+# .sp
+# Before deploying the new key and certificate with DANE,
+# update the DNS with new DANE TLSA records, then wait for
+# secondary nameservers to update and then for stale records
+# in remote DNS caches to expire.
+# .sp
+# Before deploying a new CA certificate make sure to include
+# all the required intermediate issuing CA certificates in
+# the certificate chain file. The server certificate must
+# be the first certificate in the chain file. Overwrite and
+# deploy the file with the original self-signed certificate
+# that was generated together with the key.
+# .IP "\fBnew-server-cert\fR [\fB-a \fIalgorithm\fR] [\fB-b \fIbits\fR] [\fIhostname\fB...\fR]"
+# This is just like \fBnew-server-key\fR except that, rather
+# than generating a new private key, any currently deployed
+# private key is copied to the new key file. Thus if you're
+# publishing DANE TLSA "3 1 1" or "3 1 2" records, there is
+# no need to update DNS records. The \fIalgorithm\fR and
+# \fIbits\fR arguments are used only if no key of the same
+# algorithm is already configured.
+# .sp
+# This command is rarely needed, because the self-signed
+# certificates generated have a 100-year nominal expiration
+# time. The underlying public key algorithms may well be
+# obsoleted by quantum computers long before then.
+# .sp
+# The most plausible reason for using this command is when
+# the system hostname changes, and you'd like the name in the
+# certificate to match the new hostname (not required for
+# DANE "3 1 1", but some needlessly picky non-DANE opportunistic
+# TLS clients may log warnings or even refuse to communicate).
+# .IP "\fBdeploy-server-cert \fIcertfile\fB \fIkeyfile\fR"
+# This subcommand deploys the certificates in \fIcertfile\fR
+# and private key in \fIkeyfile\fR (which are typically
+# generated by the commands above, which will also log and
+# display the full command needed to deploy the generated key
+# and certificate). After the new certificate and key are
+# deployed any obsolete keys and certificates may be removed
+# by hand. The \fIkeyfile\fR and \fIcertfile\fR filenames
+# may be relative to the Postfix configuration directory.
+# .IP "\fBoutput-server-csr\fR [\fB-k \fIkeyfile\fR] [\fIhostname\fB...\fR]"
+# Write to stdout a certificate signing request (CSR) for the
+# specified \fIkeyfile\fR.
+# .sp
+# Instead of an absolute pathname or a pathname relative to
+# $config_directory, \fIkeyfile\fR may specify one of the
+# supported key algorithm names (see "\fBpostconf -T
+# public-key-algorithms\fR"). In that case, the corresponding
+# setting from main.cf is used to locate the \fIkeyfile\fR.
+# The default \fIkeyfile\fR value is \fBrsa\fR.
+# .sp
+# Zero or more \fIhostname\fR values can be specified. The
+# default \fIhostname\fR is the value of \fBmyhostname\fR
+# main.cf parameter.
+# .IP "\fBoutput-server-tlsa\fR [\fB-h \fIhostname\fR] [\fIkeyfile\fB...\fR]"
+# Write to stdout a DANE TLSA RRset suitable for a port 25
+# SMTP server on host \fIhostname\fR with keys from any of
+# the specified \fIkeyfile\fR values. The default \fIhostname\fR
+# is the value of the \fBmyhostname\fR main.cf parameter.
+# .sp
+# Instead of absolute pathnames or pathnames relative to
+# $config_directory, the \fIkeyfile\fR list may specify
+# names of supported public key algorithms (see "\fBpostconf
+# -T public-key-algorithms\fR"). In that case, the actual
+# \fIkeyfile\fR list uses the values of the corresponding
+# Postfix server TLS key file parameters. If a parameter
+# value is empty or equal to \fBnone\fR, then no TLSA record
+# is output for that algorithm.
+# .sp
+# The default \fIkeyfile\fR list consists of the two supported
+# algorithms \fBrsa\fR and \fBecdsa\fR.
+# AUXILIARY COMMANDS
+# .IP "\fBall-default-client\fR"
+# Exit with status 0 (success) if all SMTP client TLS settings are
+# at their default values. Otherwise, exit with a non-zero status.
+# This is typically used as follows:
+# .sp
+# \fBpostfix tls all-default-client &&
+# postfix tls enable-client\fR
+# .IP "\fBall-default-server\fR"
+# Exit with status 0 (success) if all SMTP server TLS settings are
+# at their default values. Otherwise, exit with a non-zero status.
+# This is typically used as follows:
+# .sp
+# \fBpostfix tls all-default-server &&
+# postfix tls enable-server\fR
+# CONFIGURATION PARAMETERS
+# .ad
+# .fi
+# The "\fBpostfix tls \fIsubcommand\fR" feature reads
+# or updates the following configuration parameters.
+# .IP "\fBcommand_directory (see 'postconf -d' output)\fR"
+# The location of all postfix administrative commands.
+# .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
+# The default location of the Postfix main.cf and master.cf
+# configuration files.
+# .IP "\fBopenssl_path (openssl)\fR"
+# The location of the OpenSSL command line program \fBopenssl\fR(1).
+# .IP "\fBsmtp_tls_loglevel (0)\fR"
+# Enable additional Postfix SMTP client logging of TLS activity.
+# .IP "\fBsmtp_tls_security_level (empty)\fR"
+# The default SMTP TLS security level for the Postfix SMTP client;
+# when a non-empty value is specified, this overrides the obsolete
+# parameters smtp_use_tls, smtp_enforce_tls, and smtp_tls_enforce_peername.
+# .IP "\fBsmtp_tls_session_cache_database (empty)\fR"
+# Name of the file containing the optional Postfix SMTP client
+# TLS session cache.
+# .IP "\fBsmtpd_tls_cert_file (empty)\fR"
+# File with the Postfix SMTP server RSA certificate in PEM format.
+# .IP "\fBsmtpd_tls_eccert_file (empty)\fR"
+# File with the Postfix SMTP server ECDSA certificate in PEM format.
+# .IP "\fBsmtpd_tls_eckey_file ($smtpd_tls_eccert_file)\fR"
+# File with the Postfix SMTP server ECDSA private key in PEM format.
+# .IP "\fBsmtpd_tls_key_file ($smtpd_tls_cert_file)\fR"
+# File with the Postfix SMTP server RSA private key in PEM format.
+# .IP "\fBsmtpd_tls_loglevel (0)\fR"
+# Enable additional Postfix SMTP server logging of TLS activity.
+# .IP "\fBsmtpd_tls_received_header (no)\fR"
+# Request that the Postfix SMTP server produces Received: message
+# headers that include information about the protocol and cipher used,
+# as well as the remote SMTP client CommonName and client certificate issuer
+# CommonName.
+# .IP "\fBsmtpd_tls_security_level (empty)\fR"
+# The SMTP TLS security level for the Postfix SMTP server; when
+# a non-empty value is specified, this overrides the obsolete parameters
+# smtpd_use_tls and smtpd_enforce_tls.
+# .IP "\fBtls_random_source (see 'postconf -d' output)\fR"
+# The external entropy source for the in-memory \fBtlsmgr\fR(8) pseudo
+# random number generator (PRNG) pool.
+# SEE ALSO
+# master(8) Postfix master program
+# postfix(1) Postfix administrative interface
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# TLS_README, Postfix TLS configuration and operation
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# HISTORY
+# The "\fBpostfix tls\fR" command was introduced with Postfix
+# version 3.1.
+# AUTHOR(S)
+# Viktor Dukhovni
+#--
+
+RSA_BITS=2048 # default
+EC_CURVE=secp256r1 # default
+
+case $daemon_directory in
+"") echo This script must be run by the postfix command. 1>&2
+ echo Do not run directly. 1>&2
+ exit 1;;
+esac
+
+umask 022
+SHELL=/bin/sh
+
+postconf=$command_directory/postconf
+LOGGER="$command_directory/postlog -t $MAIL_LOGTAG/postfix-tls-script"
+INFO="$LOGGER -p info"
+WARN="$LOGGER -p warn"
+ERROR="$LOGGER -p error"
+FATAL="$LOGGER -p fatal"
+
+# Overwrite SMTP client and server settings only when these are at defaults.
+client_settings="
+ smtp_use_tls
+ smtp_enforce_tls
+ smtp_tls_enforce_peername
+ smtp_tls_security_level
+ smtp_tls_cert_file
+ smtp_tls_dcert_file
+ smtp_tls_eccert_file
+"
+
+server_settings="
+ smtpd_use_tls
+ smtpd_enforce_tls
+ smtpd_tls_security_level
+ smtpd_tls_cert_file
+ smtpd_tls_dcert_file
+ smtpd_tls_eccert_file
+"
+
+#
+# Can't do much without these in place.
+#
+cd $command_directory || {
+ # Let's hope there's a "postlog" somewhere else on the PATH
+ FATAL="postlog -p fatal -t $MAIL_LOGTAG/postfix-tls-script"
+ msg="no Postfix command directory '${command_directory}'"
+ $FATAL "$msg" || { echo "$msg" >&2; sleep 1; }
+ exit 1
+}
+
+check_getopt() {
+ OPTIND=1
+ a=
+ b=
+ c=
+ set -- -a 1 -b 2 -c -- -pos
+ while getopts :a:b:c o
+ do
+ case $o in
+ a) a="${OPTARG}";;
+ b) b="${OPTARG}";;
+ c) c=3;;
+ *) return 1;;
+ esac
+ done
+ shift `expr ${OPTIND} - 1`
+ if [ "${a}" != "1" -o "${b}" != 2 -o "${c}" != 3 \
+ -o "${OPTIND}" -ne 7 -o "$1" != "-pos" ]; then
+ return 1
+ fi
+}
+
+check_getopt || {
+ $FATAL "/bin/sh does not implement a compatible 'getopts' built-in"
+ exit 1
+}
+
+# ----- BEGIN OpenSSL-specific -----
+
+# No need to set the location of the OpenSSL command in each Postfix instance,
+# the value from the default instance is used for all instances.
+#
+default_config_directory=`$postconf -dh config_directory`
+openssl=`$postconf -c $default_config_directory -xh openssl_path`
+"$openssl" version >/dev/null 2>&1 || {
+ $FATAL "No working openssl(1) command found with 'openssl_path = $openssl'"
+ exit 1
+}
+
+# ----- END OpenSSL-specific -----
+
+test -n "$config_directory" -a -d "$config_directory" || {
+ $FATAL no Postfix configuration directory $config_directory!
+ exit 1
+}
+
+# Do we support TLS and if so which algorithms?
+#
+$postconf -T compile-version | grep . >/dev/null || {
+ mail_version=`$postconf -dh mail_version`
+ $FATAL "Postfix $mail_version is not compiled with TLS support"
+ exit 1
+}
+rsa=
+ecdsa=
+for _algo in `$postconf -T public-key-algorithms | egrep '^(rsa|ecdsa)$'`
+do
+ eval $_algo=$_algo
+done
+
+# ----- BEGIN OpenSSL-specific -----
+
+if [ -n "${ecdsa}" ]; then
+ $openssl ecparam -name secp256r1 >/dev/null 2>&1 || {
+ cat <<-EOM | $WARN
+ Postfix supports ECDSA, but the $openssl command does not. Consider
+ setting the openssl_path parameter to a more capable version of the
+ command-line utility than $openssl (with PATH=$PATH).
+ EOM
+ ecdsa=
+ }
+fi
+if [ -n "${rsa}" ]; then
+ DEFALG=rsa
+elif [ -n "${ecdsa}" ]; then
+ DEFALG=ecdsa
+else
+ mail_version=`$postconf -dh mail_version`
+ $FATAL "Postfix $mail_version does not support either RSA or ECDSA"
+ exit 1
+fi
+
+# Make sure stdin is open when testing
+if [ -r /dev/stdin ] < /dev/null; then
+ stdin=/dev/stdin
+elif [ -r /dev/fd/0 ] </dev/null; then
+ stdin=/dev/fd/0
+else
+ $FATAL No /dev/fd/0 or /dev/stdin found
+ exit 1
+fi
+
+hex_sha256() {
+ $openssl dgst -binary -sha256 | od -An -vtx1 | tr -d ' \012'
+}
+
+# We require SHA2-256 support from openssl(1)
+#
+null256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+tmp=`hex_sha256 </dev/null 2>/dev/null`
+if [ "${tmp}" != "${null256}" ]; then
+ cat <<EOF >&2
+Your $openssl does not support the SHA2-256 digest algorithm. To enable
+'postfix tls', install an OpenSSL that does. Install its openssl(1) command
+at /usr/local/bin/openssl or other suitable location, and set the
+'openssl_path' parameter in $default_config_directory/main.cf accordingly.
+EOF
+ $FATAL "No 'postfix tls' support when openssl(1) is obsolete"
+ exit 1
+fi
+
+read_key() {
+ [ -n "$1" -a -f "$1" ] || return 1
+
+ # Old OpenSSL versions return success even for unsupported sub-commands!
+ # So we inspect the output instead. Don't prompt if the key is password
+ # protected.
+ #
+ while read cmd key_algo key_param cert_param; do
+ $openssl $cmd -passin "pass:umask 077" -in "$1" |
+ grep . && return 0
+ done 2>/dev/null <<-EOF
+ rsa rsa smtpd_tls_key_file smtpd_tls_cert_file
+ ec ecdsa smtpd_tls_eckey_file smtpd_tls_eccert_file
+ EOF
+ return 1
+}
+
+pubkey_dgst() {
+ [ -n "$1" -a -f "$1" ] || return 1
+
+ # Old OpenSSL versions return success even for unsupported sub-commands!
+ # So we inspect the output instead.
+ #
+ for cmd in ec rsa; do
+ $openssl $cmd -passin "pass:umask 077" -in "$1" -pubout |
+ $openssl $cmd -pubin -outform DER |
+ hex_sha256 | egrep -v "${null256}" && return 0
+ done 2>/dev/null
+ return 1
+}
+
+cert_pubkey_dgst() {
+ [ -n "$1" -a -f "$1" ] || return 1
+
+ # Old OpenSSL versions return success even for unsupported sub-commands!
+ # So we inspect the output instead.
+ #
+ for cmd in ec rsa; do
+ $openssl x509 -pubkey -noout -in "$1" |
+ $openssl $cmd -pubin -outform DER |
+ hex_sha256 | egrep -v "${null256}" && return 0
+ done 2>/dev/null
+ return 1
+}
+
+copy_key() {
+ _algo=$1; shift
+ _bits=$1; shift
+ _fold=$1; shift
+ _fnew=$1; shift
+ _umask=`umask`
+
+ umask 077
+ read_key "${_fold}" > "${_fnew}" # sets key_algo of current key
+ _ret=$?
+ umask "${_umask}"
+
+ if [ "${_ret}" -ne 0 ]; then
+ $FATAL "Error copying private key from '${_fold}' to '${_fnew}'"
+ return 1
+ fi
+ if [ "${key_algo}" != "${_algo}" ]; then
+ $FATAL "Key algorithm '$key_algo' of '${_fold}' is not '${_algo}'"
+ return 1
+ fi
+ # XXX: We'd need C-code in postconf to portably check for compatible "bits"
+}
+
+create_key() {
+ _algo=$1
+ _bits=$2
+ _fnew=$3
+ _umask=`umask`
+
+ case $_algo in
+ "") $FATAL "Internal error: empty algorithm"; return 1;;
+ $rsa) set -- "${openssl}" genrsa -out "${_fnew}" "${_bits}";;
+ $ecdsa) set -- "${openssl}" ecparam -param_enc named_curve -genkey \
+ -out "${_fnew}" -name "${_bits}";;
+ *) $FATAL "Internal error: bad algorithm '${_algo}'"
+ return 1;;
+ esac
+
+ umask 077
+ _err=`"$@" 2>&1`
+ _ret=$?
+ umask "${_umask}"
+
+ if [ "${_ret}" -ne 0 ]; then
+ echo "${_err}" | $WARN
+ $FATAL "error generating new ${_algo} ${_bits} private key"
+ return 1
+ fi
+}
+
+create_cert() {
+ _k=$1; shift
+ _c=$1; shift
+ set_fqdn "$1"
+ if [ $# -gt 0 ]; then shift; fi
+ set -- "$fqdn" "$@"
+
+ if [ -r "${_c}" ]; then
+ $FATAL "New certificate file already exists: ${_c}"
+ return 1
+ fi
+
+ # Generate a new self-signed (~100 year) certificate
+ #
+ (
+ echo "default_md = sha256"
+ echo "x509_extensions = v3"
+ echo "prompt = yes"
+ echo "distinguished_name = dn"
+ echo "[dn]"
+ echo "[v3]"
+ echo "basicConstraints = CA:false"
+ echo "subjectKeyIdentifier = hash"
+ echo "extendedKeyUsage = serverAuth, clientAuth"
+ echo "subjectAltName = @alts"
+ echo "[alts]"
+ i=1; for dns in "$@"; do
+ # XXX map empty to $myhostname
+ echo "DNS.$i = $dns"
+ i=`expr $i + 1`
+ done
+ ) | $openssl req -x509 -config $stdin -new -key "${_k}" \
+ -subj "/CN=$fqdn" -days 36525 -out "${_c}" || {
+ rm -f "${_c}" "${_k}"
+ $FATAL "error generating self-signed SSL certificate"
+ return 1
+ }
+}
+
+output_server_csr() {
+ set_keyfile "$1" || return 1
+ shift
+ set_fqdn "$1" || return 1
+ shift
+ set -- "$fqdn" "$@"
+ (
+ echo "default_md = sha256"
+ echo "req_extensions = v3"
+ echo "prompt = yes"
+ echo "distinguished_name = dn"
+ echo "[dn]"
+ echo "[v3]"
+ echo "subjectKeyIdentifier = hash"
+ echo "extendedKeyUsage = serverAuth, clientAuth"
+ echo "subjectAltName = @alts"
+ echo "[alts]"
+ i=1; for dns in "$@"; do
+ echo "DNS.$i = $dns"
+ i=`expr $i + 1`
+ done
+ ) | $openssl req -config $stdin -new -key "$keyfile" -subj /
+}
+
+# ----- END OpenSSL-specific -----
+
+info_enable_client() {
+ cat <<-EOM
+ *** Non-default SMTP client TLS settings detected, no changes made.
+ For opportunistic TLS in the Postfix SMTP client, the below settings
+ are typical:
+ smtp_tls_security_level = may
+ smtp_tls_loglevel = 1
+ EOM
+ if get_cache_db_type dbtype
+ then
+ echo " smtp_tls_session_cache_database = ${dbtype}:\${data_directory}/smtp_scache"
+ fi
+}
+
+info_client_deployed() {
+ cat <<-EOM
+ Enabled opportunistic TLS in the Postfix SMTP client.
+ Run the command:
+ # postfix reload
+ if you want the new settings to take effect immediately.
+ EOM
+}
+
+info_enable_server() {
+ cat <<-EOM
+ *** Non-default SMTP server TLS settings detected, no changes made.
+ For opportunistic TLS in the Postfix SMTP server, the below settings
+ are typical:
+ smtpd_tls_security_level = may
+ smtpd_tls_loglevel = 1
+ You can use "postfix tls new-server-cert" to create a new certificate.
+ Or, "postfix tls new-server-key" to also force a new private key.
+ If you publish DANE TLSA records, see:
+ https://tools.ietf.org/html/rfc7671#section-8
+ https://tools.ietf.org/html/rfc7671#section-5.1
+ https://tools.ietf.org/html/rfc7671#section-5.2
+ https://community.letsencrypt.org/t/please-avoid-3-0-1-and-3-0-2-dane-tlsa-records-with-le-certificates/7022
+ EOM
+}
+
+# args: certfile keyfile deploy
+info_created() {
+ cat <<-EOM
+ New private key and self-signed certificate created. To deploy run:
+ # postfix tls deploy-server-cert $1 $2
+ EOM
+}
+
+# args: certfile keyfile deploy
+info_server_deployed() {
+ if [ "$3" = "enable" ]; then
+ echo "Enabled opportunistic TLS in the Postfix SMTP server"
+ fi
+ cat <<-EOM
+ New TLS private key and certificate deployed.
+ Run the command:
+ # postfix reload
+ if you want the new settings to take effect immediately.
+ EOM
+}
+
+# args: certfile keyfile deploy
+info_csr() {
+ cat <<-EOM
+ To generate a CSR run:
+ # postfix tls output-server-csr -k $2 [<hostname> ...]
+ EOM
+ if [ -z "$3" ]; then
+ echo "Save the signed certificate chain in $1, and deploy as above."
+ else
+ echo "Save the signed certificate chain in $1."
+ fi
+}
+
+# args: certfile keyfile deploy
+info_tlsa() {
+ # If already deployed, info for how to show all the deployed keys.
+ # Otherwise, just the new keys, so that TLSA records can be updated
+ # first.
+ if [ -n "$3" ]; then shift $#; fi
+ cat <<-EOM
+ To generate TLSA records run:
+ # postfix tls output-server-tlsa [-h <hostname>] $2
+ EOM
+}
+
+# args: certfile keyfile deploy
+info_dane_dns() {
+ # If already deployed, too late to wait, otherwise advise updating TLSA
+ # RRs before deployment.
+ if [ -n "$3" ]; then
+ cat <<-EOM
+ (If you have DANE TLSA RRs, update them as soon as possible to match
+ the newly deployed keys).
+ EOM
+ else
+ cat <<-EOM
+ (deploy after updating the DNS and waiting for stale RRs to expire).
+ EOM
+ fi
+}
+
+set_fqdn() {
+ if [ -n "$1" ]; then fqdn=$1; return 0; fi
+ fqdn=`$postconf -xh myhostname` || return 1
+ case $fqdn in /*) fqdn=`cat "${fqdn}"` || return 1;; esac
+}
+
+set_keyfile() {
+ keyfile=$1
+ case $keyfile in
+ rsa) if [ -n "${rsa}" ]; then
+ keyfile=`$postconf -nxh smtpd_tls_key_file`
+ else
+ keyfile=
+ fi
+ ;;
+ ecdsa) if [ -n "${ecdsa}" ]; then
+ keyfile=`$postconf -nxh smtpd_tls_eckey_file`
+ else
+ keyfile=
+ fi
+ ;;
+ "") : empty ok;;
+ none) : see below;;
+ /*) ;;
+ *) # User-specified key pathnames are relative to the configuration
+ # directory
+ keyfile="${config_directory}/${keyfile}";;
+ esac
+ if [ "${keyfile}" = "none" ]; then keyfile= ; fi
+}
+
+check_key() {
+ read_key "$1" >/dev/null && return 0
+ $FATAL "no private key found in file: $1"
+ return 1
+}
+
+# Create new key or copy existing if specified.
+#
+ensure_key() {
+ _algo=$1; shift
+ _bits=$1; shift
+ stamp=`TZ=UTC date +%Y%m%d-%H%M%S`
+
+ case $_algo in
+ "") $FATAL "Internal error: empty algorithm "; return 1;;
+ $rsa) keyfile="${config_directory}/key-${stamp}.pem"
+ certfile="${config_directory}/cert-${stamp}.pem";;
+ $ecdsa) keyfile="${config_directory}/eckey-${stamp}.pem"
+ certfile="${config_directory}/eccert-${stamp}.pem";;
+ *) $FATAL "Internal error: bad algorithm '${_algo}'"
+ return 1;;
+ esac
+
+ if [ -r "${keyfile}" ]; then
+ $FATAL "New private key file already exists: ${keyfile}"
+ return 1
+ fi
+ if [ -r "${certfile}" ]; then
+ $FATAL "New certificate file already exists: ${certfile}"
+ return 1
+ fi
+
+ if [ -n "$1" ]; then
+ copy_key "${_algo}" "${_bits}" "$1" "${keyfile}" && return 0
+ else
+ create_key "${_algo}" "${_bits}" "${keyfile}" && return 0
+ fi
+ rm -f "${keyfile}"
+ return 1
+}
+
+init_random_source() {
+ tls_random_source=$1
+
+ if [ -z "${tls_random_source}" ]; then
+ tls_random_source=`$postconf -xh tls_random_source`
+ fi
+ if [ -n "${tls_random_source}" ]; then
+ return 0
+ fi
+ if [ -r /dev/urandom ]
+ then
+ tls_random_source=dev:/dev/urandom
+ else
+ $FATAL no default TLS random source defined and no /dev/urandom
+ return 1
+ fi
+}
+
+# Don't be too clever by half.
+all_default() {
+ for var in "$@"
+ do
+ val=`$postconf -nh "${var}"`
+ if [ -n "$val" ]; then return 1; fi
+ done
+ return 0
+}
+
+# Select read-write database type for TLS session caches.
+#
+get_cache_db_type() {
+ var=$1; shift
+ prio=0
+ ret=1
+ for _dbtype in `$postconf -m`
+ do
+ _prio=0
+ case $_dbtype in
+ lmdb) _prio=2;;
+ btree) _prio=1;;
+ esac
+ if [ "$_prio" -gt "$prio" ]
+ then
+ eval "$var=\$_dbtype"
+ prio=$_prio
+ ret=0
+ fi
+ done
+ return $ret
+}
+
+deploy_server_cert() {
+ certfile=$1; shift
+ keyfile=$1; shift
+ case $# in 0) deploy=;; *) deploy=$1; shift;; esac
+
+ # Sets key_algo, key_param and cert_param
+ check_key "$keyfile" || return 1
+
+ cd=`cert_pubkey_dgst "${certfile}"` || {
+ $FATAL "error computing certificate public key digest"
+ return 1
+ }
+ kd=`pubkey_dgst "$keyfile"` || {
+ $FATAL "error computing public key digest"
+ return 1
+ }
+
+ if [ "$cd" != "$kd" ]; then
+ $FATAL "Certificate in ${certfile} does not match key in ${keyfile}"
+ return 1
+ fi
+
+ set -- \
+ "${key_param} = ${keyfile}" \
+ "${cert_param} = ${certfile}"
+
+ if [ "${deploy}" = "enable" ]; then
+ set -- "$@" \
+ "smtpd_tls_security_level = may" \
+ "smtpd_tls_received_header = yes" \
+ "smtpd_tls_loglevel = 1"
+ fi
+
+ if [ -n "${tls_random_source}" ]; then
+ set -- "$@" "tls_random_source = ${tls_random_source}"
+ fi
+
+ # All in one shot, since postconf delays modifying "hot" main.cf files.
+ $postconf -e "$@" || return 1
+}
+
+# Prepare a new cert and perhaps re-use any existing private key.
+#
+new_server_cert() {
+ algo=$1; shift
+ bits=$1; shift
+ oldkey=$1; shift
+ deploy=$1; shift
+
+ # resets keyfile (copy or else new) and new certfile
+ ensure_key "$algo" "$bits" "${oldkey}" || return 1
+ create_cert "${keyfile}" "${certfile}" "$@" || return 1
+ if [ -n "${deploy}" ]; then
+ deploy_server_cert "${certfile}" "${keyfile}" "${deploy}" || return 1
+ fi
+
+ (
+ if [ -z "${deploy}" ]; then
+ info_created "${certfile}" "${keyfile}" "${deploy}"
+ else
+ info_server_deployed "${certfile}" "${keyfile}" "${deploy}"
+ fi
+ info_csr "${certfile}" "${keyfile}" "${deploy}"
+ info_tlsa "${certfile}" "${keyfile}" "${deploy}"
+ if [ -z "${oldkey}" ]; then
+ info_dane_dns "${certfile}" "${keyfile}" "${deploy}"
+ fi
+ ) | $INFO
+}
+
+enable_client() {
+ if all_default ${client_settings}
+ then
+ set -- \
+ "smtp_tls_security_level = may" \
+ "smtp_tls_loglevel = 1"
+
+ if get_cache_db_type dbtype
+ then
+ set -- "$@" \
+ "smtp_tls_session_cache_database = ${dbtype}:${data_directory}/smtp_scache"
+ fi
+
+ if [ -n "${tls_random_source}" ]; then
+ set -- "$@" "tls_random_source = ${tls_random_source}"
+ fi
+
+ # All in one shot, since postconf delays modifying "hot" main.cf files.
+ $postconf -e "$@" || return 1
+ info_client_deployed
+ else
+ info_enable_client
+ fi | $INFO
+}
+
+enable_server() {
+ algo=$1; shift
+ bits=$1; shift
+
+ if all_default ${server_settings}
+ then
+ # algo bits keyfile deploy [hostnames ...]
+ new_server_cert "${algo}" "${bits}" "" "enable" "$@" || return 1
+ else
+ info_enable_server | $INFO
+ fi
+}
+
+output_server_tlsa() {
+ hostname=$1
+ check_key "$2" || return 1
+ data=`pubkey_dgst "$2"` || return 1
+ if [ -z "$data" ]
+ then
+ $FATAL error computing SHA2-256 SPKI digest of "$key"
+ return 1
+ fi
+ echo "_25._tcp.$hostname. IN TLSA 3 1 1 $data"
+}
+
+#
+# Parse JCL
+#
+case $1 in
+enable-client)
+ cmd=$1; shift; OPTIND=1
+ rand=
+ while getopts :r: _opt
+ do
+ case $_opt in
+ r) rand="${OPTARG}";;
+ *) $FATAL "usage: postfix tls $cmd [-r devrandom]"
+ exit 1;;
+ esac
+ done
+
+ # No positional arguments supported with enable-client
+ if [ $# -ge "${OPTIND}" ]; then
+ $FATAL "usage: postfix tls $cmd [-r devrandom]"
+ exit 1
+ fi
+ # But, shift anyway
+ shift `expr $OPTIND - 1`
+
+ init_random_source "${rand}" || exit 1
+ enable_client || exit 1
+ ;;
+
+enable-server)
+ cmd=$1; shift; OPTIND=1
+ algo=$DEFALG
+ bits=
+ rand=
+ while getopts :a:b:r: _opt
+ do
+ case $_opt in
+ a) algo="${OPTARG}";;
+ b) bits="${OPTARG}";;
+ r) rand="${OPTARG}";;
+ *) $FATAL "usage: postfix tls $cmd [-a algorithm] [-b bits ] [-r devrandom] [hostname ...]"
+ exit 1;;
+ esac
+ done
+
+ # Here positional arguments are hostnames for the new certificate, as
+ # many as the user wants
+ shift `expr $OPTIND - 1`
+
+ case $algo in
+ "") $FATAL "Internal error: empty algorithm "; return 1;;
+ $rsa) : ${bits:=${RSA_BITS}};;
+ $ecdsa) : ${bits:=${EC_CURVE}};;
+ *) $FATAL "Unsupported private key algorithm: $algo"
+ exit 1;;
+ esac
+
+ init_random_source "${rand}" || exit 1
+ enable_server "${algo}" "${bits}" "$@" || exit 1
+ ;;
+
+new-server-key)
+ cmd=$1; shift; OPTIND=1
+ algo=$DEFALG
+ while getopts :a:b: _opt
+ do
+ case $_opt in
+ a) algo="${OPTARG}";;
+ b) bits="${OPTARG}";;
+ *) $FATAL "usage: postfix tls $cmd [-a algorithm] [-b bits ] [hostname ...]"
+ exit 1;;
+ esac
+ done
+
+ # Here positional arguments are hostnames for the new certificate, as
+ # many as the user wants
+ shift `expr $OPTIND - 1`
+
+ case $algo in
+ "") $FATAL "Internal error: empty algorithm "; return 1;;
+ $rsa) : ${bits:=${RSA_BITS}};;
+ $ecdsa) : ${bits:=${EC_CURVE}};;
+ *) $FATAL "Unsupported public key algorithm: $algo"
+ exit 1;;
+ esac
+
+ # Force new key
+ new_server_cert "${algo}" "${bits}" "" "" "$@" || exit 1
+ ;;
+
+new-server-cert)
+ cmd=$1; shift; OPTIND=1
+ algo=$DEFALG
+ while getopts :a:b: _opt
+ do
+ case $_opt in
+ a) algo="${OPTARG}";;
+ b) bits="${OPTARG}";;
+ *) $FATAL "usage: postfix tls $cmd [-a algorithm] [-b bits ] [hostname ...]"
+ exit 1;;
+ esac
+ done
+
+ # Here positional arguments are hostnames for the new certificate, as
+ # many as the user wants
+ shift `expr $OPTIND - 1`
+
+ case $algo in
+ "") $FATAL "Invalid empty key algorithm"; exit 1;;
+ $rsa) : ${bits:=${RSA_BITS}};;
+ $ecdsa) : ${bits:=${EC_CURVE}};;
+ *) $FATAL "Unsupported private key algorithm: $algo"
+ exit 1;;
+ esac
+
+ # Existing keyfile or empty
+ set_keyfile "${algo}"
+
+ if [ -n "${keyfile}" -a ! -f "${keyfile}" ]; then
+ echo "Key file: ${keyfile} not found, creating new keys" | $WARN
+ keyfile=
+ fi
+
+ # Try to re-use (copy) existing key.
+ new_server_cert "${algo}" "${bits}" "${keyfile}" "" "$@" || exit 1
+ ;;
+
+deploy-server-cert)
+ if [ $# -ne 3 ]; then
+ $FATAL "usage: postfix tls $1 certfile keyfile"
+ exit 1
+ fi
+ shift
+
+ # User-specified key and cert pathnames are relative to the
+ # configuration directory
+ #
+ case "${1}" in
+ /*) certfile="${1}" ;;
+ *) certfile="${config_directory}/${1}" ;;
+ esac
+ case "${2}" in
+ /*) keyfile="${2}" ;;
+ *) keyfile="${config_directory}/${2}" ;;
+ esac
+
+ deploy_server_cert "${certfile}" "${keyfile}" || exit 1
+ info_server_deployed "${certfile}" "${keyfile}" "deploy" | $INFO
+ ;;
+
+output-server-csr)
+ cmd=$1; shift; OPTIND=1
+ k=
+ while getopts :k: _opt
+ do
+ case $_opt in
+ k) k="${OPTARG}";;
+ *) $FATAL "usage: postfix tls $cmd [-k keyfile] [hostname ...]"
+ exit 1;;
+ esac
+ done
+
+ # Here positional arguments are hostnames for the new certificate, as
+ # many as the user wants
+ shift `expr $OPTIND - 1`
+
+ if [ -n "${k}" ]; then
+ set_keyfile "${k}"
+ else
+ for _algo in $rsa $ecdsa
+ do
+ set_keyfile "${_algo}"
+ if [ -n "${keyfile}" ]; then
+ break
+ fi
+ done
+ fi
+
+ if [ -z "${keyfile}" -o ! -r "${keyfile}" ]; then
+ $FATAL "No usable keyfile specified or configured"
+ exit 1
+ fi
+
+ # Default <hostname> from $myhostname
+ if [ $# -eq 0 ]; then
+ set_fqdn
+ set -- "$fqdn"
+ fi
+
+ # Output a CSR for the requested names
+ output_server_csr "$keyfile" "$@" || exit 1
+ ;;
+
+output-server-tlsa)
+ cmd=$1; shift; OPTIND=1
+ hostname=
+ while getopts :h: _opt
+ do
+ case $_opt in
+ h) hostname="${OPTARG}";;
+ *) $FATAL "usage: postfix tls $cmd [-h hostname] [keyfile ...]"
+ exit 1;;
+ esac
+ done
+ set_fqdn "${hostname}"
+
+ # Here positional arguments are keyfiles for which we output "3 1 1"
+ # TLSA RRs, as many keyfiles as the user wants. By default the live
+ # RSA and/or ECDSA keys.
+ shift `expr $OPTIND - 1`
+
+ if [ $# -eq 0 ]; then set -- $rsa $ecdsa; fi
+
+ found=
+ for _k in "$@"
+ do
+ set_keyfile "${_k}"
+ if [ -z "${keyfile}" ]; then continue; fi
+ echo "; ${keyfile}"
+ output_server_tlsa "${fqdn}" "${keyfile}" || exit 1
+ found=1
+ done
+ if [ -z "${found}" ]; then
+ $FATAL "No usable keyfiles specified or configured"
+ exit 1
+ fi
+ ;;
+
+all-default-client)
+ cmd=$1; shift; OPTIND=1
+
+ # No arguments for all-default-client
+ if [ $# -ge "${OPTIND}" ]; then
+ $FATAL "usage: postfix tls $cmd"
+ exit 1
+ fi
+
+ all_default ${client_settings} || exit 1
+ ;;
+
+all-default-server)
+ cmd=$1; shift; OPTIND=1
+
+ # No arguments for all-default-server
+ if [ $# -ge "${OPTIND}" ]; then
+ $FATAL "usage: postfix tls $cmd"
+ exit 1
+ fi
+
+ all_default ${server_settings} || exit 1
+ ;;
+
+*)
+ $ERROR "unknown tls command: '$1'"
+ $FATAL "usage: postfix tls enable-client (or enable-server, new-server-key, new-server-cert, deploy-server-cert, output-server-csr, output-server-tlsa, all-default-client, all-default-server)"
+ exit 1
+ ;;
+
+esac
diff --git a/conf/postfix-wrapper b/conf/postfix-wrapper
new file mode 100644
index 0000000..dd0a517
--- /dev/null
+++ b/conf/postfix-wrapper
@@ -0,0 +1,224 @@
+#!/bin/sh
+
+#++
+# NAME
+# postfix-wrapper 1
+# SUMMARY
+# trivial but useful multi-instance manager
+# SYNOPSIS
+# postfix command
+# DESCRIPTION
+# Postfix versions 2.6 and later provide support for multiple
+# Postfix instances. Instances share executable files and
+# documentation, but have their own directories for configuration,
+# queue and data files. In many cases different instances
+# have different myhostname and inet_interfaces settings,
+# though this is not always necessary.
+#
+# This command implements a trivial Postfix multi-instance
+# manager. It simply applies commands such as "postfix start"
+# to all the applicable Postfix instances.
+# MANAGING MULTIPLE INSTANCES
+# .ad
+# .fi
+# To hook the postfix-wrapper multi-instance manager into
+# Postfix, see the POSTFIX-WRAPPER INITIALIZATION section
+# below. To create a new Postfix instance, see the CREATING
+# A NEW POSTFIX INSTANCE section below.
+#
+# To start, stop, get status, etc., with multiple Postfix
+# instances, use:
+#
+# .nf
+# # postfix command
+# .fi
+#
+# For example, to find out what Postfix instances are configured:
+#
+# .nf
+# # postfix status
+# .fi
+#
+# The postfix(1) command invokes the postfix-wrapper command.
+# This in turn applies the postfix(1) command to the default
+# Postfix instance, and to each instance specified with the
+# default main.cf file's multi_instance_directories parameter
+# value.
+#
+# The postfix-wrapper command will start, stop, reload, etc.,
+# only Postfix instances that have "multi_instance_enable =
+# yes" in their main.cf files. When an instance is disabled,
+# postfix-wrapper replaces "start" commands by "check" so
+# that problems will still be reported.
+#
+# The startup order is taken from the multi_instance_directories
+# parameter; the default instance is prepended to the list.
+# The startup order is used for all postfix(1) commands,
+# except for commands that stop Postfix instances. In those
+# cases the order is reversed.
+# MANAGING INDIVIDUAL INSTANCES
+# .ad
+# .fi
+# To manage an individual Postfix instance, use:
+#
+# .nf
+# # postfix -c /path/to/config_directory command
+# .fi
+#
+# This is also needed to manage the default Postfix instance,
+# after you turn on multi-instance support.
+#
+# To use the Postfix sendmail command with a non-default
+# Postfix instance, use:
+#
+# .nf
+# # sendmail -C /path/to/config_directory ...
+# .fi
+#
+# Note 1: that's capital C, not lower-case c.
+#
+# Note 2: only the default Postfix instance will check or
+# update the shared Postfix files, including the executable
+# files and documentation.
+# POSTFIX-WRAPPER INITIALIZATION
+# .ad
+# .fi
+# To hook this program into Postfix, execute the command
+# shown below.
+#
+# This command should be entered as one line.
+#
+# In the example, replace /etc/postfix with the default Postfix
+# configuration directory, and replace /usr/libexec/postfix
+# with the daemon directory pathname of the default Postfix
+# instance.
+#
+# .nf
+# # postconf -c /etc/postfix -e
+# "multi_instance_enable=yes"
+# "multi_instance_wrapper=/usr/libexec/postfix/postfix-wrapper"
+# .fi
+# CREATING A NEW POSTFIX INSTANCE
+# .ad
+# .fi
+# To create a Postfix instance called "postfix-test", start
+# with generic main.cf and master.cf files and customize the
+# locations of the queue and data directories with the commands
+# shown below. The last command updates main.cf and creates
+# any directories that Postfix will need.
+#
+# Each command below should be entered as one line.
+#
+# In the example, replace /etc/postfix with the default Postfix
+# configuration directory, and replace /usr/libexec/postfix
+# with the daemon directory pathname of the default Postfix
+# instance.
+#
+# .nf
+# # mkdir /etc/postfix-test
+# # cp /usr/libexec/postfix/main.cf /etc/postfix-test
+# # cp /usr/libexec/postfix/master.cf /etc/postfix-test
+# # postconf -c /etc/postfix-test -e
+# "multi_instance_name=postfix-test"
+# # postfix -c /etc/postfix post-install
+# "config_directory=/etc/postfix-test"
+# "queue_directory=/var/spool/postfix-test"
+# "data_directory=/var/lib/postfix-test"
+# create-missing
+# .fi
+#
+# Register this Postfix instance with the default instance.
+# This command should be entered as one line.
+#
+# .nf
+# # postconf -e "multi_instance_directories=`postconf
+# -h multi_instance_directories` /etc/postfix-test"
+# .fi
+#
+# Edit the myhostname and inet_interfaces main.cf parameters,
+# so that they will not conflict with the default Postfix
+# instance, and change whatever else needs to be changed.
+#
+# Test the instance with:
+#
+# .nf
+# # postfix -c /etc/postfix-test start
+# # postfix -c /etc/postfix-test status
+# [ other tests ... ]
+# .fi
+#
+# When everything is working satisfactorily, enable start/stop/etc.
+# by the multi-instance manager:
+#
+# .nf
+# # postconf -c /etc/postfix-test -e multi_instance_enable=yes
+# DIAGNOSTICS
+# .ad
+# .fi
+# When an operation fails, the affected Postfix instance logs
+# a message, and the multi-instance manager skips to the next
+# instance.
+# BUGS
+# Support for the multi_instance_group feature is not implemented.
+# SEE ALSO
+# postfix(1) Postfix control program
+# postfix-wrapper(5) multi-instance manager API
+# postmulti(1) full-blown multi-instance manager
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#--
+
+# Sanity checks.
+
+: ${command_directory?"do not invoke this command directly"}
+: ${daemon_directory?"do not invoke this command directly"}
+
+# Readability.
+
+POSTCONF=$command_directory/postconf
+POSTFIX=$command_directory/postfix
+
+# Canonicalize the instance directory list. The list is specified
+# in startup order.
+
+instance_dirs=`$POSTCONF -h multi_instance_directories | sed 's/,/ /'` ||
+ exit 1
+
+case "$1" in
+ stop|quick-stop|abort|drain)
+ all_dirs=
+ for dir in $config_directory $instance_dirs
+ do
+ all_dirs="$dir $all_dirs"
+ done;;
+ *) all_dirs="$config_directory $instance_dirs";;
+esac
+
+# Execute the command on all applicable instances. When a Postfix
+# instance is disabled, replace "postfix start" by "postfix check"
+# so that problems will still be reported.
+
+err=0
+for dir in $all_dirs
+do
+ case "$1" in
+ start)
+ test "`$POSTCONF -c $dir -h multi_instance_enable`" = yes || {
+ $POSTFIX -c $dir check || err=$?
+ continue
+ };;
+ stop|abort|drain|flush|reload)
+ test "`$POSTCONF -c $dir -h multi_instance_enable`" = yes ||
+ continue;;
+ esac
+ $POSTFIX -c $dir "$@" || err=$?
+done
+
+exit $err
diff --git a/conf/postmulti-script b/conf/postmulti-script
new file mode 100644
index 0000000..b1aea8e
--- /dev/null
+++ b/conf/postmulti-script
@@ -0,0 +1,312 @@
+#! /bin/sh
+
+umask 022
+
+# postmulti(1) contract:
+#
+# Arguments:
+# postmulti-script -e <edit_command>
+#
+# Environment:
+#
+# All actions:
+#
+# MAIL_CONFIG - config_directory of primary instance
+# command_directory - From primary instance
+# daemon_directory - From primary instance
+# meta_directory - From primary instance
+# shlib_directory - From primary instance
+# config_directroy - config_directory of target instance
+# queue_directory - queue_directory of target instance
+# data_directory - data_directory of target instance
+#
+# Create, destroy, import and deport:
+#
+# multi_instance_directories - New value for primary instance
+#
+# Create, import and assign (unset == nochange, "-" == clear):
+#
+# multi_instance_group - New value for target instance
+# multi_instance_name - New value for target instance
+
+: ${MAIL_CONFIG:?"do not invoke this command directly"}
+: ${command_directory:?"do not invoke this command directly"}
+: ${daemon_directory:?"do not invoke this command directly"}
+: ${meta_directory:?"do not invoke this command directly"}
+: ${shlib_directory:?"do not invoke this command directly"}
+
+USAGE="$0 -e create|destroy|import|deport|enable|disable|assign|init"
+usage() { echo "$0: Error: Usage: $USAGE" >&2; exit 1; }
+
+TAG="$MAIL_LOGTAG/postmulti-script"
+fatal() { postlog -p fatal -t "$TAG" "$1"; exit 1; }
+
+# args: add|del $dir
+#
+update_cfdirs() {
+ op=$1
+ dir=$2
+
+ alt=`postconf -h alternate_config_directories` || return 1
+
+ shift $# # Needed on SunOS where bare "set --" is NOP!
+ IFS="$IFS,"; set -- $alt; IFS="$BACKUP_IFS"
+ keep=
+ found=
+ # Portability: SunOS "sh" needs 'in "$@"' for one-line for-loop.
+ for d in "$@"; do [ "$d" = "$dir" ] && found=1 || keep="$keep $d"; done
+
+ set -- "multi_instance_directories = $multi_instance_directories"
+
+ case $op in
+ add) test -n "$found" ||
+ set -- "$@" "alternate_config_directories =$keep $dir";;
+ del) test -n "$found" &&
+ set -- "$@" "alternate_config_directories =$keep";;
+ *) return 1;; # XXX: Internal error
+ esac
+ postconf -e "$@" || return 1
+}
+
+assign_names() {
+ # Set the instance name and group
+ #
+ test -n "$multi_instance_name" && {
+ test "$multi_instance_name" = "-" && multi_instance_name=
+ set -- "$@" "multi_instance_name = $multi_instance_name"
+ }
+ test -n "$multi_instance_group" && {
+ test "$multi_instance_group" = "-" && multi_instance_group=
+ set -- "$@" "multi_instance_group = $multi_instance_group"
+ }
+ test $# -eq 0 || postconf -c "$config_directory" -e "$@" || return 1
+}
+
+# Process command-line options and parameter settings. Work around
+# brain damaged shells. "IFS=value command" should not make the
+# IFS=value setting permanent. But some broken standard allows it.
+
+BACKUP_IFS="$IFS"
+action=
+
+while getopts ":e:" opt
+do
+ case $opt in
+ e) action="$OPTARG";;
+ *) usage;;
+ esac
+done
+shift `expr $OPTIND - 1`
+
+# Check for valid action and required instance name
+case "$action" in
+ create|import|destroy|deport|enable|disable|assign|init) ;;
+ *) usage;;
+esac
+test $# -eq 0 || usage
+
+case $action in
+init)
+ postconf -e \
+ 'multi_instance_wrapper = ${command_directory}/postmulti -p --' \
+ 'multi_instance_enable = yes'
+ exit $? ;;
+esac
+
+# Backport note: "-x" requires 2.10 or later, and is not essential here.
+#
+wrapper=`postconf -hx multi_instance_wrapper` || exit 1
+enable=`postconf -hx multi_instance_enable` || exit 1
+
+test -n "$wrapper" ||
+ fatal "multi_instance_wrapper is empty, run 'postmulti -e init' first."
+
+test "$enable" = "yes" ||
+ fatal "multi_instance_enable!=yes, run 'postmulti -e init' first."
+
+: ${config_directory:?"Invalid empty target instance config_directory"}
+
+case $action in
+create|import)
+
+ # Atomically install stock main.cf/master.cf files. We install the
+ # master.cf file last. Once it is present the instance is complete.
+ #
+ test -f $config_directory/main.cf -a \
+ -f $config_directory/master.cf || {
+
+ test "$action" = "create" || {
+ test -f $config_directory/main.cf ||
+ fatal "'$config_directory' lacks a main.cf file"
+ test -f $config_directory/master.cf ||
+ fatal "'$config_directory' lacks a master.cf file"
+ }
+
+ test -f $meta_directory/main.cf.proto ||
+ fatal "Missing main.cf prototype: $meta_directory/main.cf.proto"
+ test -f $meta_directory/master.cf.proto ||
+ fatal "Missing master.cf prototype: $meta_directory/master.cf.proto"
+
+ # Create instance-specific directories
+ #
+ test -d $config_directory ||
+ { (umask 022; mkdir -p $config_directory) || exit 1; }
+ test -d $queue_directory ||
+ { (umask 022; mkdir -p $queue_directory) || exit 1; }
+ test -d $data_directory ||
+ { (umask 077; mkdir -p $data_directory) || exit 1; }
+
+ tmpdir=$config_directory/.tmp
+ (umask 077; mkdir -p $tmpdir) || exit 1
+ cp -p $meta_directory/main.cf.proto $tmpdir/main.cf || exit 1
+
+ # Shared install parameters are cloned from user-specified values in
+ # the default instance, but only if explicitly set there. Otherwise,
+ # they are commented out in the new main.cf file.
+ #
+ SHARED_PARAMETERS="
+ command_directory
+ daemon_directory
+ meta_directory
+ mail_owner
+ setgid_group
+ sendmail_path
+ mailq_path
+ newaliases_path
+ html_directory
+ manpage_directory
+ sample_directory
+ readme_directory
+ shlib_directory
+ "
+
+ shift $# # Needed on SunOS where bare "set --" is NOP!
+ comment_out=
+ for p in $SHARED_PARAMETERS; do
+ val=`postconf -nh $p` || exit 1
+ test -n "$val" && { set -- "$@" "$p = $val"; continue; }
+ comment_out="$comment_out $p"
+ done
+
+ # First comment-out any parameters that take default values
+ test -n "$comment_out" && {
+ postconf -c $tmpdir -# $comment_out || exit 1
+ }
+
+ # Now add instance-specific and non-default values.
+ # By default, disable inet services and local submission
+ # in new instances
+ #
+ postconf -c $tmpdir -e \
+ "queue_directory = $queue_directory" \
+ "data_directory = $data_directory" \
+ "authorized_submit_users =" \
+ "master_service_disable = inet" \
+ "$@" || exit 1
+
+
+ cp -p $meta_directory/master.cf.proto $tmpdir/master.cf || exit 1
+ mv $tmpdir/main.cf $config_directory/main.cf || exit 1
+ mv $tmpdir/master.cf $config_directory/master.cf || exit 1
+ rmdir $tmpdir 2>/dev/null
+ }
+
+ # Set instance name and group
+ #
+ assign_names || exit 1
+
+ # Update multi_instance_directories
+ # and drop from alternate_config_directories
+ #
+ # XXX: Must happen before set-permissions below, otherwise instance
+ # is treated as a non-slave instance by post-install via postfix(1).
+ #
+ update_cfdirs del $config_directory || exit 1
+
+ # Update permissions of private files. Verifies existence of
+ # queue_directory and data_directory, ...
+ #
+ # XXX: Must happen after instance list updates above, otherwise instance
+ # is treated as a non-slave instance by post-install via postfix(1).
+ #
+ postfix -c $config_directory set-permissions || exit 1
+ ;;
+
+deport)
+ # Deporting an already deleted instance?
+ #
+ [ -f "$config_directory/main.cf" ] || {
+ update_cfdirs del $config_directory
+ exit $?
+ }
+
+ postfix -c "$config_directory" status >/dev/null 2>&1 &&
+ fatal "Instance '$config_directory' is not stopped"
+
+ # Update multi_instance_directories
+ # and add to alternate_config_directories
+ #
+ update_cfdirs add $config_directory || exit 1
+ ;;
+
+destroy)
+
+ # "postmulti -e destroy" will remove an entire instance only when
+ # invoked immediately after "postmulti -e create" (i.e. before
+ # other files are added to the instance). We delete only known
+ # safe names without "/".
+ #
+ QUEUE_SUBDIRS="active bounce corrupt defer deferred flush hold \
+ incoming maildrop pid private public saved trace"
+ #DEBUG=echo
+ WARN="postlog -p warn -t $TAG"
+
+ # Locate the target instance
+ #
+ [ -f "$config_directory/main.cf" ] ||
+ fatal "$config_directory/main.cf file not found"
+
+ postfix -c "$config_directory" status >/dev/null 2>&1 &&
+ fatal "Instance '$config_directory' is not stopped"
+
+ # Update multi_instance directories
+ # and also (just in case) drop from alternate_config_directories
+ #
+ $DEBUG update_cfdirs del "$config_directory" || exit 1
+
+ # XXX: Internal "postfix /some/cmd" interface.
+ #
+ postfix -c "$config_directory" /bin/sh -c "
+ for q in $QUEUE_SUBDIRS
+ do
+ $DEBUG rmdir -- \$q ||
+ $WARN \`pwd\`/\$q: please verify contents and remove by hand
+ done
+ "
+
+ postfix -c "$config_directory" /bin/sh -c "
+ for dir in \$data_directory \$queue_directory
+ do
+ $DEBUG rmdir -- \$dir ||
+ $WARN \$dir: please verify contents and remove by hand
+ done
+ "
+
+ # In the configuration directory remove just the main.cf and master.cf
+ # files.
+ $DEBUG rm -f -- "$config_directory/master.cf" "$config_directory/main.cf" 2>/dev/null
+ $DEBUG rmdir -- "$config_directory" ||
+ $WARN $config_directory: please verify contents and remove by hand
+ ;;
+
+enable)
+ postconf -c "$config_directory" -e \
+ "multi_instance_enable = yes" || exit 1;;
+disable)
+ postconf -c "$config_directory" -e \
+ "multi_instance_enable = no" || exit 1;;
+assign)
+ assign_names || exit 1;;
+esac
+
+exit 0
diff --git a/conf/relocated b/conf/relocated
new file mode 100644
index 0000000..e50edfd
--- /dev/null
+++ b/conf/relocated
@@ -0,0 +1,176 @@
+# RELOCATED(5) RELOCATED(5)
+#
+# NAME
+# relocated - Postfix relocated table format
+#
+# SYNOPSIS
+# postmap /etc/postfix/relocated
+#
+# DESCRIPTION
+# The optional relocated(5) table provides the information
+# that is used in "user has moved to new_location" bounce
+# messages.
+#
+# Normally, the relocated(5) 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/relocated" to rebuild an indexed
+# file after changing the corresponding relocated table.
+#
+# When the table is provided via other means such as NIS,
+# LDAP or SQL, the same lookups are done as for ordinary
+# indexed files.
+#
+# Alternatively, the table can be provided as a regu-
+# lar-expression map where patterns are given as regular
+# expressions, or lookups can be directed to TCP-based
+# server. In those case, the lookups are done in a slightly
+# different way as described below under "REGULAR EXPRESSION
+# TABLES" or "TCP-BASED TABLES".
+#
+# Table lookups are case insensitive.
+#
+# CASE FOLDING
+# The search string is folded to lowercase before database
+# lookup. As of Postfix 2.3, the search string is not case
+# folded with database types such as regexp: or pcre: whose
+# lookup fields can match both upper and lower case.
+#
+# TABLE FORMAT
+# The input format for the postmap(1) command is as follows:
+#
+# o An entry has one of the following form:
+#
+# pattern new_location
+#
+# Where new_location specifies contact information
+# such as an email address, or perhaps a street
+# address or telephone number.
+#
+# o Empty lines and whitespace-only lines are ignored,
+# as are lines whose first non-whitespace character
+# is a `#'.
+#
+# o A logical line starts with non-whitespace text. A
+# line that starts with whitespace continues a logi-
+# cal line.
+#
+# TABLE SEARCH ORDER
+# With lookups from indexed files such as DB or DBM, or from
+# networked tables such as NIS, LDAP or SQL, patterns are
+# tried in the order as listed below:
+#
+# user@domain
+# Matches user@domain. This form has precedence over
+# all other forms.
+#
+# user Matches user@site when site is $myorigin, when site
+# is listed in $mydestination, or when site is listed
+# in $inet_interfaces or $proxy_interfaces.
+#
+# @domain
+# Matches other addresses in domain. This form has
+# the lowest precedence.
+#
+# ADDRESS EXTENSION
+# When a mail address localpart contains the optional recip-
+# ient delimiter (e.g., user+foo@domain), the lookup order
+# becomes: user+foo@domain, user@domain, user+foo, user, and
+# @domain.
+#
+# REGULAR EXPRESSION TABLES
+# This section describes how the table lookups change when
+# the table is given in the form of regular expressions or
+# when lookups are directed to a TCP-based server. For a
+# description of regular expression lookup table syntax, see
+# regexp_table(5) or pcre_table(5). For a description of the
+# TCP client/server table lookup protocol, see tcp_table(5).
+# This feature is not available up to and including Postfix
+# version 2.4.
+#
+# Each pattern is a regular expression that is applied to
+# the entire address being looked up. Thus, user@domain mail
+# addresses are not broken up into their user and @domain
+# constituent parts, nor is user+foo broken up into user and
+# foo.
+#
+# Patterns are applied in the order as specified in the ta-
+# ble, until a pattern is found that matches the search
+# string.
+#
+# Results are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from
+# the pattern can be interpolated as $1, $2 and so on.
+#
+# TCP-BASED TABLES
+# This section describes how the table lookups change when
+# lookups are directed to a TCP-based server. For a descrip-
+# tion of the TCP client/server lookup protocol, see tcp_ta-
+# ble(5). This feature is not available up to and including
+# Postfix version 2.4.
+#
+# Each lookup operation uses the entire address once. Thus,
+# user@domain mail addresses are not broken up into their
+# user and @domain constituent parts, nor is user+foo broken
+# up into user and foo.
+#
+# Results are the same as with indexed file lookups.
+#
+# BUGS
+# The table format does not understand quoting conventions.
+#
+# CONFIGURATION PARAMETERS
+# The following main.cf parameters are especially relevant.
+# The text below provides only a parameter summary. See
+# postconf(5) for more details including examples.
+#
+# relocated_maps
+# List of lookup tables for relocated users or sites.
+#
+# Other parameters of interest:
+#
+# inet_interfaces
+# 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
+# local.
+#
+# myorigin
+# The domain that is appended to locally-posted mail.
+#
+# proxy_interfaces
+# Other interfaces that this machine receives mail on
+# by way of a proxy agent or network address transla-
+# tor.
+#
+# SEE ALSO
+# trivial-rewrite(8), address resolver
+# postmap(1), Postfix lookup table manager
+# postconf(5), configuration parameters
+#
+# README FILES
+# Use "postconf readme_directory" or "postconf html_direc-
+# tory" to locate this information.
+# DATABASE_README, Postfix lookup table overview
+# ADDRESS_REWRITING_README, address rewriting guide
+#
+# LICENSE
+# The Secure Mailer license must be distributed with this
+# software.
+#
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#
+# RELOCATED(5)
diff --git a/conf/transport b/conf/transport
new file mode 100644
index 0000000..0213a6e
--- /dev/null
+++ b/conf/transport
@@ -0,0 +1,299 @@
+# TRANSPORT(5) TRANSPORT(5)
+#
+# NAME
+# transport - Postfix transport table format
+#
+# SYNOPSIS
+# postmap /etc/postfix/transport
+#
+# postmap -q "string" /etc/postfix/transport
+#
+# postmap -q - /etc/postfix/transport <inputfile
+#
+# DESCRIPTION
+# The optional transport(5) table specifies a mapping from
+# email addresses to message delivery transports and
+# next-hop destinations. Message delivery transports such
+# as local or smtp are defined in the master.cf file, and
+# next-hop destinations are typically hosts or domain names.
+# The table is searched by the trivial-rewrite(8) daemon.
+#
+# This mapping overrides the default transport:nexthop
+# selection that is built into Postfix:
+#
+# local_transport (default: local:$myhostname)
+# This is the default for final delivery to domains
+# listed with mydestination, and for [ipaddress] des-
+# tinations that match $inet_interfaces or
+# $proxy_interfaces. The default nexthop destination
+# is the MTA hostname.
+#
+# virtual_transport (default: virtual:)
+# This is the default for final delivery to domains
+# listed with virtual_mailbox_domains. The default
+# nexthop destination is the recipient domain.
+#
+# relay_transport (default: relay:)
+# This is the default for remote delivery to domains
+# listed with relay_domains. In order of decreasing
+# precedence, the nexthop destination is taken from
+# relay_transport, sender_dependent_relayhost_maps,
+# relayhost, or from the recipient domain.
+#
+# default_transport (default: smtp:)
+# This is the default for remote delivery to other
+# destinations. In order of decreasing precedence,
+# the nexthop destination is taken from sender_depen-
+# dent_default_transport_maps, default_transport,
+# sender_dependent_relayhost_maps, relayhost, or from
+# the recipient domain.
+#
+# Normally, the transport(5) 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/transport" to rebuild an indexed
+# file after changing the corresponding transport table.
+#
+# When the table is provided via other means such as NIS,
+# LDAP or SQL, the same lookups are done as for ordinary
+# indexed files.
+#
+# Alternatively, the table can be provided as a regu-
+# lar-expression map where patterns are given as regular
+# expressions, or lookups can be directed to TCP-based
+# server. In those case, the lookups are done in a slightly
+# different way as described below under "REGULAR EXPRESSION
+# TABLES" or "TCP-BASED TABLES".
+#
+# CASE FOLDING
+# The search string is folded to lowercase before database
+# lookup. As of Postfix 2.3, the search string is not case
+# folded with database types such as regexp: or pcre: whose
+# lookup fields can match both upper and lower case.
+#
+# TABLE FORMAT
+# The input format for the postmap(1) command is as follows:
+#
+# pattern result
+# When pattern matches the recipient address or
+# domain, use the corresponding result.
+#
+# blank lines and comments
+# Empty lines and whitespace-only lines are ignored,
+# as are lines whose first non-whitespace character
+# is a `#'.
+#
+# multi-line text
+# A logical line starts with non-whitespace text. A
+# line that starts with whitespace continues a logi-
+# cal line.
+#
+# The pattern specifies an email address, a domain name, or
+# a domain name hierarchy, as described in section "TABLE
+# LOOKUP".
+#
+# The result is of the form transport:nexthop and specifies
+# how or where to deliver mail. This is described in section
+# "RESULT FORMAT".
+#
+# TABLE SEARCH ORDER
+# With lookups from indexed files such as DB or DBM, or from
+# networked tables such as NIS, LDAP or SQL, patterns are
+# tried in the order as listed below:
+#
+# user+extension@domain transport:nexthop
+# Deliver mail for user+extension@domain through
+# transport to nexthop.
+#
+# user@domain transport:nexthop
+# Deliver mail for user@domain through transport to
+# nexthop.
+#
+# domain transport:nexthop
+# Deliver mail for domain through transport to nex-
+# thop.
+#
+# .domain transport:nexthop
+# Deliver mail for any subdomain of domain through
+# transport to nexthop. This applies only when the
+# string transport_maps is not listed in the par-
+# ent_domain_matches_subdomains configuration set-
+# ting. Otherwise, a domain name matches itself and
+# its subdomains.
+#
+# * transport:nexthop
+# The special pattern * represents any address (i.e.
+# it functions as the wild-card pattern, and is
+# unique to Postfix transport tables).
+#
+# Note 1: the null recipient address is looked up as
+# $empty_address_recipient@$myhostname (default: mailer-dae-
+# mon@hostname).
+#
+# Note 2: user@domain or user+extension@domain lookup is
+# available in Postfix 2.0 and later.
+#
+# RESULT FORMAT
+# The lookup result is of the form transport:nexthop. The
+# transport field specifies a mail delivery transport such
+# as smtp or local. The nexthop field specifies where and
+# how to deliver mail.
+#
+# The transport field specifies the name of a mail delivery
+# transport (the first name of a mail delivery service entry
+# in the Postfix master.cf file).
+#
+# The interpretation of the nexthop field is transport
+# dependent. In the case of SMTP, specify a service on a
+# non-default port as host:service, and disable MX (mail
+# exchanger) DNS lookups with [host] or [host]:port. The []
+# form is required when you specify an IP address instead of
+# a hostname.
+#
+# A null transport and null nexthop result means "do not
+# change": use the delivery transport and nexthop informa-
+# tion that would be used when the entire transport table
+# did not exist.
+#
+# A non-null transport field with a null nexthop field
+# resets the nexthop information to the recipient domain.
+#
+# A null transport field with non-null nexthop field does
+# not modify the transport information.
+#
+# EXAMPLES
+# In order to deliver internal mail directly, while using a
+# mail relay for all other mail, specify a null entry for
+# internal destinations (do not change the delivery trans-
+# port or the nexthop information) and specify a wildcard
+# for all other destinations.
+#
+# my.domain :
+# .my.domain :
+# * smtp:outbound-relay.my.domain
+#
+# In order to send mail for example.com and its subdomains
+# via the uucp transport to the UUCP host named example:
+#
+# example.com uucp:example
+# .example.com uucp:example
+#
+# When no nexthop host name is specified, the destination
+# domain name is used instead. For example, the following
+# directs mail for user@example.com via the slow transport
+# to a mail exchanger for example.com. The slow transport
+# could be configured to run at most one delivery process at
+# a time:
+#
+# example.com slow:
+#
+# When no transport is specified, Postfix uses the transport
+# that matches the address domain class (see DESCRIPTION
+# above). The following sends all mail for example.com and
+# its subdomains to host gateway.example.com:
+#
+# example.com :[gateway.example.com]
+# .example.com :[gateway.example.com]
+#
+# In the above example, the [] suppress MX lookups. This
+# prevents mail routing loops when your machine is primary
+# MX host for example.com.
+#
+# In the case of delivery via SMTP, one may specify host-
+# name:service instead of just a host:
+#
+# example.com smtp:bar.example:2025
+#
+# This directs mail for user@example.com to host bar.example
+# port 2025. Instead of a numerical port a symbolic name may
+# be used. Specify [] around the hostname if MX lookups must
+# be disabled.
+#
+# The error mailer can be used to bounce mail:
+#
+# .example.com error:mail for *.example.com is not deliverable
+#
+# This causes all mail for user@anything.example.com to be
+# bounced.
+#
+# REGULAR EXPRESSION TABLES
+# This section describes how the table lookups change when
+# the table is given in the form of regular expressions. For
+# a description of regular expression lookup table syntax,
+# see regexp_table(5) or pcre_table(5).
+#
+# Each pattern is a regular expression that is applied to
+# the entire address being looked up. Thus,
+# some.domain.hierarchy is not looked up via its parent
+# domains, nor is user+foo@domain looked up as user@domain.
+#
+# Patterns are applied in the order as specified in the ta-
+# ble, until a pattern is found that matches the search
+# string.
+#
+# The trivial-rewrite(8) server disallows regular expression
+# substitution of $1 etc. in regular expression lookup
+# tables, because that could open a security hole (Postfix
+# version 2.3 and later).
+#
+# TCP-BASED TABLES
+# This section describes how the table lookups change when
+# lookups are directed to a TCP-based server. For a descrip-
+# tion of the TCP client/server lookup protocol, see tcp_ta-
+# ble(5). This feature is not available up to and including
+# Postfix version 2.4.
+#
+# Each lookup operation uses the entire recipient address
+# once. Thus, some.domain.hierarchy is not looked up via
+# its parent domains, nor is user+foo@domain looked up as
+# user@domain.
+#
+# Results are the same as with indexed file lookups.
+#
+# CONFIGURATION PARAMETERS
+# The following main.cf parameters are especially relevant.
+# The text below provides only a parameter summary. See
+# postconf(5) for more details including examples.
+#
+# empty_address_recipient
+# The address that is looked up instead of the null
+# sender address.
+#
+# parent_domain_matches_subdomains
+# List of Postfix features that use domain.tld pat-
+# terns to match sub.domain.tld (as opposed to
+# requiring .domain.tld patterns).
+#
+# transport_maps
+# List of transport lookup tables.
+#
+# SEE ALSO
+# trivial-rewrite(8), rewrite and resolve addresses
+# master(5), master.cf file format
+# postconf(5), configuration parameters
+# postmap(1), Postfix lookup table manager
+#
+# README FILES
+# Use "postconf readme_directory" or "postconf html_direc-
+# tory" to locate this information.
+# ADDRESS_REWRITING_README, address rewriting guide
+# DATABASE_README, Postfix lookup table overview
+# FILTER_README, external content filter
+#
+# LICENSE
+# The Secure Mailer license must be distributed with this
+# software.
+#
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#
+# TRANSPORT(5)
diff --git a/conf/virtual b/conf/virtual
new file mode 100644
index 0000000..da9cd65
--- /dev/null
+++ b/conf/virtual
@@ -0,0 +1,324 @@
+# VIRTUAL(5) VIRTUAL(5)
+#
+# NAME
+# virtual - Postfix virtual alias table format
+#
+# SYNOPSIS
+# postmap /etc/postfix/virtual
+#
+# postmap -q "string" /etc/postfix/virtual
+#
+# postmap -q - /etc/postfix/virtual <inputfile
+#
+# DESCRIPTION
+# The optional virtual(5) alias table rewrites recipient
+# addresses for all local, all virtual, and all remote mail
+# destinations. This is unlike the aliases(5) table which
+# is used only for local(8) delivery. Virtual aliasing is
+# recursive, and is implemented by the Postfix cleanup(8)
+# daemon before mail is queued.
+#
+# The main applications of virtual aliasing are:
+#
+# o To redirect mail for one address to one or more
+# addresses.
+#
+# o To implement virtual alias domains where all
+# addresses are aliased to addresses in other
+# domains.
+#
+# Virtual alias domains are not to be confused with
+# the virtual mailbox domains that are implemented
+# with the Postfix virtual(8) mail delivery agent.
+# With virtual mailbox domains, each recipient
+# address can have its own mailbox.
+#
+# Virtual aliasing is applied only to recipient envelope
+# addresses, and does not affect message headers. Use
+# canonical(5) mapping to rewrite header and envelope
+# addresses in general.
+#
+# Normally, the virtual(5) 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" to rebuild an indexed file
+# after changing the corresponding text file.
+#
+# When the table is provided via other means such as NIS,
+# LDAP or SQL, the same lookups are done as for ordinary
+# indexed files.
+#
+# Alternatively, the table can be provided as a regu-
+# lar-expression map where patterns are given as regular
+# expressions, or lookups can be directed to TCP-based
+# server. In those case, the lookups are done in a slightly
+# different way as described below under "REGULAR EXPRESSION
+# TABLES" or "TCP-BASED TABLES".
+#
+# CASE FOLDING
+# The search string is folded to lowercase before database
+# lookup. As of Postfix 2.3, the search string is not case
+# folded with database types such as regexp: or pcre: whose
+# lookup fields can match both upper and lower case.
+#
+# TABLE FORMAT
+# The input format for the postmap(1) command is as follows:
+#
+# pattern address, address, ...
+# When pattern matches a mail address, replace it by
+# the corresponding address.
+#
+# blank lines and comments
+# Empty lines and whitespace-only lines are ignored,
+# as are lines whose first non-whitespace character
+# is a `#'.
+#
+# multi-line text
+# A logical line starts with non-whitespace text. A
+# line that starts with whitespace continues a logi-
+# cal line.
+#
+# TABLE SEARCH ORDER
+# With lookups from indexed files such as DB or DBM, or from
+# networked tables such as NIS, LDAP or SQL, each
+# user@domain query produces a sequence of query patterns as
+# described below.
+#
+# Each query pattern is sent to each specified lookup table
+# before trying the next query pattern, until a match is
+# found.
+#
+# user@domain address, address, ...
+# Redirect mail for user@domain to address. This
+# form has the highest precedence.
+#
+# user address, address, ...
+# Redirect mail for user@site to address when site is
+# equal to $myorigin, when site is listed in $mydes-
+# tination, or when it is listed in $inet_interfaces
+# or $proxy_interfaces.
+#
+# This functionality overlaps with functionality of
+# the local aliases(5) database. The difference is
+# that virtual(5) mapping can be applied to non-local
+# addresses.
+#
+# @domain address, address, ...
+# Redirect mail for other users in domain to address.
+# This form has the lowest precedence.
+#
+# Note: @domain is a wild-card. With this form, the
+# Postfix SMTP server accepts mail for any recipient
+# in domain, regardless of whether that recipient
+# exists. This may turn your mail system into a
+# backscatter source: Postfix first accepts mail for
+# non-existent recipients and then tries to return
+# that mail as "undeliverable" to the often forged
+# sender address.
+#
+# To avoid backscatter with mail for a wild-card
+# domain, replace the wild-card mapping with explicit
+# 1:1 mappings, or add a reject_unverified_recipient
+# restriction for that domain:
+#
+# smtpd_recipient_restrictions =
+# ...
+# reject_unauth_destination
+# check_recipient_access
+# inline:{example.com=reject_unverified_recipient}
+# unverified_recipient_reject_code = 550
+#
+# In the above example, Postfix may contact a remote
+# server if the recipient is aliased to a remote
+# address.
+#
+# RESULT ADDRESS REWRITING
+# The lookup result is subject to address rewriting:
+#
+# o When the result has the form @otherdomain, the
+# result becomes the same user in otherdomain. This
+# works only for the first address in a multi-address
+# lookup result.
+#
+# o When "append_at_myorigin=yes", append "@$myorigin"
+# to addresses without "@domain".
+#
+# o When "append_dot_mydomain=yes", append ".$mydomain"
+# to addresses without ".domain".
+#
+# ADDRESS EXTENSION
+# When a mail address localpart contains the optional recip-
+# ient delimiter (e.g., user+foo@domain), the lookup order
+# becomes: user+foo@domain, user@domain, user+foo, user, and
+# @domain.
+#
+# The propagate_unmatched_extensions parameter controls
+# whether an unmatched address extension (+foo) is propa-
+# gated to the result of table lookup.
+#
+# VIRTUAL ALIAS DOMAINS
+# Besides virtual aliases, the virtual alias table can also
+# be used to implement virtual alias domains. With a virtual
+# alias domain, all recipient addresses are aliased to
+# addresses in other domains.
+#
+# Virtual alias domains are not to be confused with the vir-
+# tual mailbox domains that are implemented with the Postfix
+# virtual(8) mail delivery agent. With virtual mailbox
+# domains, each recipient address can have its own mailbox.
+#
+# With a virtual alias domain, the virtual domain has its
+# own user name space. Local (i.e. non-virtual) usernames
+# are not visible in a virtual alias domain. In particular,
+# local aliases(5) and local mailing lists are not visible
+# as localname@virtual-alias.domain.
+#
+# Support for a virtual alias domain looks like:
+#
+# /etc/postfix/main.cf:
+# 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-alias.domain anything (right-hand content does not matter)
+# postmaster@virtual-alias.domain postmaster
+# user1@virtual-alias.domain address1
+# user2@virtual-alias.domain address2, address3
+#
+# The virtual-alias.domain anything entry is required for a
+# virtual alias domain. Without this entry, mail is rejected
+# with "relay access denied", or bounces with "mail loops
+# back to myself".
+#
+# Do not specify virtual alias domain names in the main.cf
+# mydestination or relay_domains configuration parameters.
+#
+# With a virtual alias domain, the Postfix SMTP server
+# accepts mail for known-user@virtual-alias.domain, and
+# rejects mail for unknown-user@virtual-alias.domain as
+# undeliverable.
+#
+# Instead of specifying the virtual alias domain name via
+# the virtual_alias_maps table, you may also specify it via
+# the main.cf virtual_alias_domains configuration parameter.
+# This latter parameter uses the same syntax as the main.cf
+# mydestination configuration parameter.
+#
+# REGULAR EXPRESSION TABLES
+# This section describes how the table lookups change when
+# the table is given in the form of regular expressions. For
+# a description of regular expression lookup table syntax,
+# see regexp_table(5) or pcre_table(5).
+#
+# Each pattern is a regular expression that is applied to
+# the entire address being looked up. Thus, user@domain mail
+# addresses are not broken up into their user and @domain
+# constituent parts, nor is user+foo broken up into user and
+# foo.
+#
+# Patterns are applied in the order as specified in the ta-
+# ble, until a pattern is found that matches the search
+# string.
+#
+# Results are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from
+# the pattern can be interpolated as $1, $2 and so on.
+#
+# TCP-BASED TABLES
+# This section describes how the table lookups change when
+# lookups are directed to a TCP-based server. For a descrip-
+# tion of the TCP client/server lookup protocol, see tcp_ta-
+# ble(5). This feature is not available up to and including
+# Postfix version 2.4.
+#
+# Each lookup operation uses the entire address once. Thus,
+# user@domain mail addresses are not broken up into their
+# user and @domain constituent parts, nor is user+foo broken
+# up into user and foo.
+#
+# Results are the same as with indexed file lookups.
+#
+# BUGS
+# The table format does not understand quoting conventions.
+#
+# CONFIGURATION PARAMETERS
+# The following main.cf parameters are especially relevant
+# to this topic. See the Postfix main.cf file for syntax
+# details and for default values. Use the "postfix reload"
+# command after a configuration change.
+#
+# virtual_alias_maps ($virtual_maps)
+# Optional lookup tables that alias specific mail
+# addresses or domains to other local or remote
+# address.
+#
+# virtual_alias_domains ($virtual_alias_maps)
+# Postfix is final destination for the specified list
+# of virtual alias domains, that is, domains for
+# which all addresses are aliased to addresses in
+# other local or remote domains.
+#
+# propagate_unmatched_extensions (canonical, virtual)
+# What address lookup tables copy an address exten-
+# sion from the lookup key to the lookup result.
+#
+# Other parameters of interest:
+#
+# inet_interfaces (all)
+# The network interface addresses that this mail sys-
+# tem receives mail on.
+#
+# mydestination ($myhostname, localhost.$mydomain, local-
+# host)
+# The list of domains that are delivered via the
+# $local_transport mail delivery transport.
+#
+# myorigin ($myhostname)
+# The domain name that locally-posted mail appears to
+# come from, and that locally posted mail is deliv-
+# ered to.
+#
+# owner_request_special (yes)
+# Enable special treatment for owner-listname entries
+# in the aliases(5) file, and don't split owner-list-
+# name and listname-request address localparts when
+# the recipient_delimiter is set to "-".
+#
+# proxy_interfaces (empty)
+# The network interface addresses that this mail sys-
+# tem receives mail on by way of a proxy or network
+# address translation unit.
+#
+# SEE ALSO
+# cleanup(8), canonicalize and enqueue mail
+# postmap(1), Postfix lookup table manager
+# postconf(5), configuration parameters
+# canonical(5), canonical address mapping
+#
+# README FILES
+# Use "postconf readme_directory" or "postconf html_direc-
+# tory" to locate this information.
+# ADDRESS_REWRITING_README, address rewriting guide
+# DATABASE_README, Postfix lookup table overview
+# VIRTUAL_README, domain hosting guide
+#
+# LICENSE
+# The Secure Mailer license must be distributed with this
+# software.
+#
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#
+# VIRTUAL(5)