Except for main.cf and master.cf, all files are optional
for non-default Postfix configuration directories. File:
conf/postfix-files.
+
+20090115
+
+ Cleanup: rewrote the 20090114 VERP bugfix, to replace code
+ that "works" by code that is "right". Files: *qmgr/qmgr_deliver.c,
+ bounce/bounce_notify_verp.c, global/verp_sender.c.
+
+20090118
+
+ Documentation: some URLs to enable/disable client-side TLS
+ jumped into the middle of an enumeration. File:
+ proto/TLS_README.html.
+
+20090119-21
+
+ Feature: multi-instance manager plug-in API. A sample
+ multi-instance manager with instructions is available as
+ $daemon_directory/postfix-wrapper. The plug-in API itself
+ is described in postfix-wrapper(5). Files: postfix/postfix.c,
+ global/mail_params.[hc], proto/postfix-wrapper,
+ conf/postfix-wrapper, conf/postfix-script, conf/postfix-files.
+
+ Support to check/update shared files only in the context
+ of the default Postfix instance. Files: conf/post-install,
+ conf/postfix-script.
+
+20090122
+
+ Refinements: the multi-instance manager always replaces
+ "start" by "check" when a Postfix instance is multi-instance
+ disabled, so that problems will still be reported; polish
+ documentation; delete unnecessary multi_instance_order
+ parameter. Files: conf/postfix-wrapper, proto/postfix-wrapper,
+ global/mail_params.[hc] and documentation.
+
+ Bugfix: the data_directory was not automatically created!
+ File: conf/postfix-files.
src/postsuper src/qmqpd src/spawn src/flush src/verify \
src/virtual src/proxymap src/anvil src/scache src/discard src/tlsmgr
MANDIRS = proto man html
-LIBEXEC = libexec/post-install libexec/postfix-files libexec/postfix-script
+LIBEXEC = libexec/post-install libexec/postfix-files libexec/postfix-script \
+ libexec/postfix-wrapper libexec/main.cf libexec/master.cf
default: update
libexec/postfix-script: conf/postfix-script
ln -f $? $@
+libexec/postfix-wrapper: conf/postfix-wrapper
+ ln -f $? $@
+
+libexec/main.cf: conf/main.cf
+ ln -f $? $@
+
+libexec/master.cf: conf/master.cf
+ ln -f $? $@
+
manpages:
set -e; for i in $(MANDIRS); do \
(set -e; echo "[$$i]"; cd $$i; $(MAKE) -f Makefile.in $(OPTS) MAKELEVEL=) || exit 1; \
* Client-side TLS activity logging
* Client-side TLS session cache
* Client TLS limitations
- * Client TLS security levels
- * Disabling TLS in the SMTP/LMTP client
- * Enabling TLS in the SMTP/LMTP client
- * Mandating TLS encryption
- * Certificate fingerprint verification
- * Mandating server certificate verification
- * Secure server certificate verification
+ * Configuring TLS in the SMTP/LMTP client
* Per-destination TLS policy
* Obsolete per-site TLS policy support
* Closing a DNS loophole with obsolete per-site TLS policies
similar issues exist for secure connections via aliases for HTTPS and Kerberos.
SMTP merely uses indirect naming (via MX records) more frequently.
-C\bCl\bli\bie\ben\bnt\bt T\bTL\bLS\bS s\bse\bec\bcu\bur\bri\bit\bty\by l\ble\bev\bve\bel\bls\bs
+C\bCo\bon\bnf\bfi\big\bgu\bur\bri\bin\bng\bg T\bTL\bLS\bS i\bin\bn t\bth\bhe\be S\bSM\bMT\bTP\bP/\b/L\bLM\bMT\bTP\bP c\bcl\bli\bie\ben\bnt\bt
-The TLS security levels listed below are described in more detail in the
+Similar to the Postfix SMTP server, the Postfix SMTP/LMTP client implements
+multiple TLS security levels. These levels are described in more detail in the
sections that follow.
n\bno\bon\bne\be
s\bse\bec\bcu\bur\bre\be
Secure-channel TLS.
-D\bDi\bis\bsa\bab\bbl\bli\bin\bng\bg T\bTL\bLS\bS i\bin\bn t\bth\bhe\be S\bSM\bMT\bTP\bP/\b/L\bLM\bMT\bTP\bP c\bcl\bli\bie\ben\bnt\bt
+N\bNo\bo T\bTL\bLS\bS e\ben\bnc\bcr\bry\byp\bpt\bti\bio\bon\bn
At the "none" TLS security level, TLS encryption is disabled. This is the
default security level. With Postfix 2.3 and later, it can be configured
T\bTL\bLS\bS p\bpo\bol\bli\bic\bcy\by t\bta\bab\bbl\ble\be
-Postfix 2.3 introduces a new more flexible TLS policy table. For earlier
+The current TLS policy table was introduced with Postfix 2.3. For earlier
releases, read the description of the obsolete Postfix 2.2 per-site table.
A small fraction of servers offer STARTTLS but the negotiation consistently
The mail_release_date configuration parameter (format: yyyymmdd)
specifies the release date of a stable release or snapshot release.
+Major changes with snapshot 20090121
+====================================
+
+Plug-in support for multi-instance managers. Basically this
+automatically applies your "postfix start" etc. command to multiple
+Postfix instances if available. The postfix-wrapper script (in the
+daemon directory) provides a simple multi-instance manager with
+instructions. The plug-in API itself is described in postfix-wrapper(5).
+
Major changes with snapshot 20090109
====================================
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"
+NON_SHARED="config_directory queue_directory data_directory"
USAGE="Usage: $0 [name=value] command
create-missing Create missing queue directories.
do
IFS="$BACKUP_IFS"
set_permission=
- # Skip comments.
+ # Skip comments. Skip shared files, if updating a non-default instance.
case $path in
- [$]*) ;;
+ [$]*) case "$def_config_directory" in
+ "$config_directory") $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.
# permissions, so that running "make install" fixes any glitches.
#
$config_directory:d:root:-:755:u
-$data_directory:d:$mail_owner:-:700: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
$daemon_directory/flush:f:root:-:755
#$daemon_directory/lmtp:f:root:-:755
$daemon_directory/local:f:root:-:755
+$daemon_directory/main.cf:f:root:-:644
+$daemon_directory/master.cf:f:root:-:644
$daemon_directory/master:f:root:-:755
$daemon_directory/oqmgr:f:root:-:755
$daemon_directory/pickup:f:root:-:755
$daemon_directory/post-install:f:root:-:755
$daemon_directory/postfix-files:f:root:-:644
$daemon_directory/postfix-script:f:root:-:755
+$daemon_directory/postfix-wrapper:f:root:-:755
$daemon_directory/proxymap:f:root:-:755
$daemon_directory/qmgr:f:root:-:755
$daemon_directory/qmqpd:f:root:-:755
$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
$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
$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
+}
+test "$def_config_directory" = "$config_directory" &&
+ check_shared_files=1
#
# Parse JCL
check-warn)
# This command is NOT part of the public interface.
- for dir in $daemon_directory $config_directory $queue_directory \
- $queue_directory/pid
+ todo="$config_directory $queue_directory $queue_directory/pid"
+ test -n "$check_shared_files" && todo="$daemon_directory $todo"
+
+ for dir in $todo
do
ls -lLd $dir | (grep " root " >/dev/null ||
$WARN not owned by root: $dir)
ls -lLd $queue_directory | egrep '^.....(w|...w)' >/dev/null && \
$WARN group or other writable: $queue_directory
- find $daemon_directory/* $config_directory/* ! -user root \
+ todo="$config_directory/*"
+ test -n "$check_shared_files" && todo="$daemon_directory/* $todo"
+
+ find $todo ! -user root \
-exec $WARN not owned by root: {} \;
- find $daemon_directory/. $config_directory/. \
+ todo="$config_directory/."
+ test -n "$check_shared_files" && todo="$daemon_directory/. $todo"
+
+ find $todo \
\( -perm -020 -o -perm -002 \) -type f \
-exec $WARN group or other writable: {} \;
find $data_directory/. ! -user $mail_owner \
- -exec $WARN not owned by $mail_owner: {} \;
+ -exec $WARN not owned by $mail_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: {} \;
- find $queue_directory/public $queue_directory/maildrop \
- $command_directory/postqueue $command_directory/postdrop \
+ 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: {} \;
# XXX also: look for weird stuff, weird permissions, etc.
- test -f /usr/sbin/sendmail -a -f /usr/lib/sendmail && {
+ 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
--- /dev/null
+#!/bin/sh
+
+# To view the formatted manual page of this file, type:
+# POSTFIXSOURCE/mantools/srctoman - postfix-wrapper | nroff -man
+
+#++
+# NAME
+# postfix-wrapper 1
+# SUMMARY
+# trivial multi-instance manager
+# SYNOPSIS
+# postfix command
+#
+# postfix /usr/libexec/postfix/postfix-wrapper init
+# DESCRIPTION
+# This command implements a trivial Postfix multi-instance
+# manager.
+#
+# Each Postfix instance is defined by its own configuration
+# directory with its own main.cf and master.cf files, by its
+# own queue and data directories, and by its own myhostname
+# and inet_interfaces settings. Other Postfix files, including
+# executable files and documentation, are shared between
+# Postfix instances.
+#
+# Only the default Postfix instance is required. The location
+# of its configuration files is specified by the built-in
+# default value for the config_directory parameter. Other
+# Postfix instances are optional.
+# MANAGING INSTANCES
+# .ad
+# .fi
+# To hook the postfix-wrapper multi-instance manager into
+# Postfix, see the 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.
+#
+# To manage an individual Postfix instance, use:
+#
+# .nf
+# # postfix -c /path/to/config_directory command
+# .fi
+#
+# Note: only the default Postfix instance will check or update
+# the shared Postfix files, including the executable files
+# and documentation.
+# WRAPPER INITIALIZATION
+# .ad
+# .fi
+# To hook this program into Postfix, execute the following
+# command, replacing /etc/postfix by the default Postfix
+# configuration directory, and replacing /usr/libexec/postfix
+# by the actual path of the Postfix daemon directory:
+#
+# .nf
+# # postfix -c /etc/postfix
+# /usr/libexec/postfix/postfix-wrapper init
+# .fi
+# CREATING A NEW POSTFIX INSTANCE
+# .ad
+# .fi
+# To create a Postfix instance called "postfix-test", start
+# with working main.cf and master.cf files and customize the
+# locations of the queue and data directories. The last
+# command below also creates any directories that Postfix
+# will need.
+#
+# .nf
+# # mkdir /etc/postfix-test
+# # cp /etc/postfix/main.cf /etc/postfix-test
+# # cp /etc/postfix/master.cf /etc/postfix-test
+# # postconf -c /etc/postfix-test -e
+# "multi_instance_name=postfix-test"
+# # postfix -c /etc/postfix-test post-install
+# "queue_directory=/var/spool/postfix-test"
+# "data_directory=/var/lib/postfix-test"
+# create-missing
+# .fi
+#
+# Register this Postfix instance with the default instance:
+#
+# .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
+# .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
+WRAPPER=$daemon_directory/postfix-wrapper
+
+# 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|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.
+
+for dir in $all_dirs
+do
+ case "$1" in
+ init*)
+ $POSTCONF -e \
+ "multi_instance_enable = yes" \
+ "multi_instance_wrapper = $daemon_directory/postfix-wrapper"
+ exit;;
+ start)
+ test "`$POSTCONF -c $dir -h multi_instance_enable`" = yes ||
+ set check;;
+ stop|abort|drain|flush|reload)
+ test "`$POSTCONF -c $dir -h multi_instance_enable`" = yes ||
+ continue;;
+ esac
+ $POSTFIX -c $dir "$@" || err=$?
+done
+
+exit $err
transport.5.html virtual.5.html pcre_table.5.html regexp_table.5.html \
cidr_table.5.html tcp_table.5.html header_checks.5.html \
ldap_table.5.html mysql_table.5.html pgsql_table.5.html \
- master.5.html nisplus_table.5.html generic.5.html bounce.5.html
+ master.5.html nisplus_table.5.html generic.5.html bounce.5.html \
+ postfix-wrapper.5.html
OTHER = postfix-manuals.html
AWK = awk '{ print; if (NR == 2) print ".pl 9999\n.ll 65" }'
MAN2HTML = man2html -t "Postfix manual - `IFS=.; set \`echo $@\`; echo \"$$1($$2)\"`"
PATH=../mantools:$$PATH; \
srctoman - $? | $(AWK) | nroff -man | uniq | $(MAN2HTML) | postlink >$@
+postfix-wrapper.5.html: ../proto/postfix-wrapper
+ PATH=../mantools:$$PATH; \
+ srctoman - $? | $(AWK) | nroff -man | uniq | $(MAN2HTML) | postlink >$@
+
postfix-manuals.html: ../src/postfix/postfix.c ../mantools/makemanidx
PATH=../mantools:$$PATH; \
makemanidx ../src/postfix/postfix.c | postlink >$@
<li><a href="#client_tls_limits"> Client TLS limitations </a>
-<li><a href="#client_tls_levels"> Client TLS security levels </a>
-
-<li><a href="#client_tls_none"> Disabling TLS in the SMTP/LMTP client</a>
-
-<li><a href="#client_tls_may"> Enabling TLS in the SMTP/LMTP client </a>
-
-<li><a href="#client_tls_encrypt"> Mandating TLS encryption </a>
-
-<li><a href="#client_tls_fprint"> Certificate fingerprint verification </a>
-
-<li><a href="#client_tls_verify"> Mandating server certificate verification </a>
-
-<li><a href="#client_tls_secure"> Secure server certificate verification </a>
+<li><a href="#client_tls_levels"> Configuring TLS in the SMTP/LMTP client </a>
<li><a href="#client_tls_policy"> Per-destination TLS policy </a>
for secure connections via aliases for HTTPS and Kerberos. SMTP merely
uses indirect naming (via MX records) more frequently. </p>
-<h3><a name="client_tls_levels"> Client TLS security levels </a>
+<h3><a name="client_tls_levels"> Configuring TLS in the SMTP/LMTP client </a>
</h3>
-<p> The TLS security levels listed below are described in more detail
-in the sections that follow.</p>
+<p> Similar to the Postfix SMTP server, the Postfix SMTP/LMTP client
+implements multiple TLS security levels. These levels are described
+in more detail in the sections that follow.</p>
<dl>
<dt><b>none</b></dt>
<dd><a href="#client_tls_secure">Secure-channel TLS.</a>
</dl>
-<h3><a name="client_tls_none"> Disabling TLS in the SMTP/LMTP client </a>
+<h3><a name="client_tls_none"> No TLS encryption </a>
</h3>
<p> At the "none" TLS security level, TLS encryption is
<h3> <a name="client_tls_policy"> TLS policy table </a>
</h3>
-<p> Postfix 2.3 introduces a new more flexible TLS policy table. For
+<p> The current TLS policy table was introduced with Postfix 2.3. For
earlier releases, read the description of the obsolete Postfix 2.2 <a
href="#client_tls_obs">per-site</a> table. </p>
</DD>
<DT><b><a name="milter_connect_macros">milter_connect_macros</a>
-(default: see postconf -n output)</b></DT><DD>
+(default: see "postconf -d" output)</b></DT><DD>
<p> The macros that are sent to Milter (mail filter) applications
after completion of an SMTP connection. See <a href="MILTER_README.html">MILTER_README</a>
</DD>
<DT><b><a name="milter_data_macros">milter_data_macros</a>
-(default: see postconf -n output)</b></DT><DD>
+(default: see "postconf -d" output)</b></DT><DD>
<p> The macros that are sent to version 4 or higher Milter (mail
filter) applications after the SMTP DATA command. See <a href="MILTER_README.html">MILTER_README</a>
</DD>
<DT><b><a name="milter_end_of_data_macros">milter_end_of_data_macros</a>
-(default: see postconf -n output)</b></DT><DD>
+(default: see "postconf -d" output)</b></DT><DD>
<p> The macros that are sent to Milter (mail filter) applications
after the message end-of-data. See <a href="MILTER_README.html">MILTER_README</a> for a list of
</DD>
<DT><b><a name="milter_end_of_header_macros">milter_end_of_header_macros</a>
-(default: see postconf -n output)</b></DT><DD>
+(default: see "postconf -d" output)</b></DT><DD>
<p> The macros that are sent to Milter (mail filter) applications
after the end of the message header. See <a href="MILTER_README.html">MILTER_README</a> for a list
</DD>
<DT><b><a name="milter_helo_macros">milter_helo_macros</a>
-(default: see postconf -n output)</b></DT><DD>
+(default: see "postconf -d" output)</b></DT><DD>
<p> The macros that are sent to Milter (mail filter) applications
after the SMTP HELO or EHLO command. See
</DD>
<DT><b><a name="milter_mail_macros">milter_mail_macros</a>
-(default: see postconf -n output)</b></DT><DD>
+(default: see "postconf -d" output)</b></DT><DD>
<p> The macros that are sent to Milter (mail filter) applications
after the SMTP MAIL FROM command. See <a href="MILTER_README.html">MILTER_README</a>
</DD>
<DT><b><a name="milter_rcpt_macros">milter_rcpt_macros</a>
-(default: see postconf -n output)</b></DT><DD>
+(default: see "postconf -d" output)</b></DT><DD>
<p> The macros that are sent to Milter (mail filter) applications
after the SMTP RCPT TO command. See <a href="MILTER_README.html">MILTER_README</a>
</DD>
<DT><b><a name="milter_unknown_command_macros">milter_unknown_command_macros</a>
-(default: see postconf -n output)</b></DT><DD>
+(default: see "postconf -d" output)</b></DT><DD>
<p> The macros that are sent to version 3 or higher Milter (mail
filter) applications after an unknown SMTP command. See <a href="MILTER_README.html">MILTER_README</a>
</p>
+</DD>
+
+<DT><b><a name="multi_instance_directories">multi_instance_directories</a>
+(default: empty)</b></DT><DD>
+
+<p> An optional list of non-default Postfix configuration directories;
+these directories belong to additional Postfix instances that share
+the Postfix executable files and documentation with the default
+Postfix instance, and that are started, stopped, etc., together
+with the default Postfix instance. Specify a list of pathnames
+separated by comma or whitespace. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+<p> When the list of non-default Postfix configuration directories
+is non-empty, the <a href="postfix.1.html">postfix(1)</a> command will invoke the multi-instance
+manager specified with the <a href="postconf.5.html#multi_instance_wrapper">multi_instance_wrapper</a> parameter to
+execute commands on the default instance and on all additional
+Postfix instances. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="multi_instance_enable">multi_instance_enable</a>
+(default: no)</b></DT><DD>
+
+<p> Allow this Postfix instance to be started, stopped, etc., by a
+multi-instance manager. By default, new instances are created in
+a safe state that prevents them from being started inadvertently.
+This parameter is reserved for the multi-instance manager. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="multi_instance_group">multi_instance_group</a>
+(default: empty)</b></DT><DD>
+
+<p> The optional instance group name of this Postfix instance. A
+group identifies closely-related Postfix instances that the
+multi-instance manager can start, stop, etc., as a unit. This
+parameter is reserved for the multi-instance manager. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="multi_instance_name">multi_instance_name</a>
+(default: empty)</b></DT><DD>
+
+<p> The optional instance name of this Postfix instance. This name
+becomes also the default value for the <a href="postconf.5.html#syslog_name">syslog_name</a> parameter. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="multi_instance_wrapper">multi_instance_wrapper</a>
+(default: empty)</b></DT><DD>
+
+<p> The pathname of a multi-instance manager command that the
+<a href="postfix.1.html">postfix(1)</a> command invokes when the <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a>
+parameter value is non-empty. The pathname may be followed by
+initial command arguments separated by whitespace; shell
+metacharacters are not supported in this context. </p>
+
+<p> The <a href="postfix.1.html">postfix(1)</a> command invokes the manager command with the
+<a href="postfix.1.html">postfix(1)</a> non-option command arguments on the manager command line,
+and with all installation configuration parameters exported into
+the manager command process environment. The manager command in
+turn invokes the <a href="postfix.1.html">postfix(1)</a> command for individual Postfix instances
+as "postfix -c <i><a href="postconf.5.html#config_directory">config_directory</a></i> <i>command</i>". </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+
</DD>
<DT><b><a name="multi_recipient_bounce_reject_code">multi_recipient_bounce_reject_code</a>
</DD>
<DT><b><a name="syslog_name">syslog_name</a>
-(default: postfix)</b></DT><DD>
+(default: see "postconf -d" output)</b></DT><DD>
<p>
The mail system name that is prepended to the process name in syslog
<li> <a href="postmap.1.html">postmap(1)</a>, Postfix lookup table manager
+<li> postmulti(1), Postfix multi-instance manager
+
<li> <a href="postqueue.1.html">postqueue(1)</a>, Postfix mail queue control
<li> <a href="postsuper.1.html">postsuper(1)</a>, Postfix housekeeping
<li> <a href="postconf.5.html">postconf(5)</a>, Postfix <a href="postconf.5.html">main.cf</a> file syntax
+<li> <a href="postfix-wrapper.5.html">postfix-wrapper(5)</a>, Postfix multi-instance API
+
</ul>
<h2> Table-driven mechanisms </h2>
--- /dev/null
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html> <head>
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+<title> Postfix manual - postfix-wrapper(5) </title>
+</head> <body> <pre>
+POSTFIX-WRAPPER(5) POSTFIX-WRAPPER(5)
+
+<b>NAME</b>
+ postfix-wrapper - Postfix multi-instance API
+
+<b>DESCRIPTION</b>
+ This document describes an interface that allows a multi-
+ instance manager to plug into Postfix and to control mul-
+ tiple Postfix instances.
+
+ Each Postfix instance is defined by its own configuration
+ directory with its own <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> files, by its
+ own queue and data directories, and by its own <a href="postconf.5.html#myhostname">myhostname</a>
+ and <a href="postconf.5.html#inet_interfaces">inet_interfaces</a> settings. Other Postfix files, includ-
+ ing executable files and documentation, are shared between
+ Postfix instances.
+
+ Only the default Postfix instance is required. The loca-
+ tion of its configuration files is specified by the built-
+ in default value for the <a href="postconf.5.html#config_directory">config_directory</a> parameter.
+ Other Postfix instances are optional.
+
+<b>GENERAL OPERATION</b>
+ First of all, nothing changes when there is only one Post-
+ fix instance.
+
+ Even after multi-instance support has been set up through
+ the mechanisms discussed later, sites can still continue
+ to use the familiar "postfix start / stop / reload /
+ upgrade / etc" commands in boot scripts, build procedures,
+ etc.
+
+ To start, stop, update, etc., multiple Postfix instances,
+ use:
+
+ # postfix <i>command</i>
+
+ For example, to find out what Postfix instances are con-
+ figured:
+
+ # postfix status
+
+ To manage an individual Postfix instance, use:
+
+ # postfix -c <i>/path/to/config</i><b>_</b><i>directory command</i>
+
+<b>MULTI-INSTANCE DETECTION</b>
+ While "postfix start/stop/etc" will remain the primary
+ command interface, the <a href="postfix.1.html">postfix(1)</a> command itself will need
+ to figure out if a command targets multiple Postfix
+ instances or just a specific Postfix instance. This deci-
+ sion can be made with information that is already avail-
+ able:
+
+ When the <a href="postfix.1.html">postfix(1)</a> command is invoked with the -c
+ option, it will operate only on the specified
+ instance. We do the same when MAIL_CONFIG is spec-
+ ified in the process environment.
+
+ Otherwise, the <a href="postfix.1.html">postfix(1)</a> command will operate on
+ all applicable Postfix instances.
+
+<b>MULTI-INSTANCE MANAGER HOOK</b>
+ When the <a href="postfix.1.html">postfix(1)</a> command is invoked without -c option,
+ and non-default Postfix instance directories are defined
+ in <a href="postconf.5.html">main.cf</a> with <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a>, then the post-
+ fix(1) command invokes the command specified in <a href="postconf.5.html">main.cf</a>
+ with <a href="postconf.5.html#multi_instance_wrapper">multi_instance_wrapper</a>, instead of invoking postfix-
+ script. The <a href="postconf.5.html#multi_instance_wrapper">multi_instance_wrapper</a> and other <a href="postconf.5.html">main.cf</a>
+ parameters are listed in the CONFIGURATION PARAMETERS sec-
+ tion below.
+
+ A useful wrapper implementation can be as simple as:
+
+ #!/bin/sh
+
+ : ${<a href="postconf.5.html#command_directory">command_directory</a>?"do not invoke this command directly"}
+
+ POSTCONF=$<a href="postconf.5.html#command_directory">command_directory</a>/postconf
+ POSTFIX=$<a href="postconf.5.html#command_directory">command_directory</a>/postfix
+ instance_dirs=`$POSTCONF -h <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> |
+ sed 's/,/ /'` || exit 1
+
+ for dir in $<a href="postconf.5.html#config_directory">config_directory</a> $instance_dirs
+ do
+ case "$1" in
+ stop|abort|flush|reload|drain)
+ test "`$POSTCONF -c $dir -h <a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a>`"
+ = yes || continue;;
+ start)
+ test "`$POSTCONF -c $dir -h <a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a>`"
+ = yes || set check;;
+ esac
+ $POSTFIX -c $dir "$@" || err=$?
+ done
+
+ exit $err
+
+ This wrapper skips commands such as "stop" that require a
+ running Postfix instance when a Postfix instance is dis-
+ abled, and replaces "start" by "check" so that problems
+ will still be reported.
+
+ The postmulti(1) command implements a more sophisticated
+ approach, based on a combination of C code and scripting.
+
+<b>SHARED VERSUS NON-SHARED FILES</b>
+ Some files are shared between Postfix instances (such as
+ executables and manpages) and some files are per-instance
+ (such as the queue). See the NON-SHARED FILES section
+ below for a list of per-instance files.
+
+ Until now, executables, manpages, etc., have been checked
+ or updated as part of the default Postfix instance. With
+ multi-instance support, we simply continue to do this.
+ Non-default Postfix instances will check or update only
+ their non-shared files.
+
+ The consequence of this approach is that the default Post-
+ fix instance should be updated before any other instances.
+
+<b>IMPLEMENTATION NOTES</b>
+ The <a href="postfix.1.html">postfix(1)</a> command ignores the <a href="postconf.5.html#multi_instance_directories">multi_instance_directo</a>-
+ <a href="postconf.5.html#multi_instance_directories">ries</a> and <a href="postconf.5.html#multi_instance_wrapper">multi_instance_wrapper</a> parameters when the -c
+ option is specified, or when MAIL_CONFIG is present in the
+ process environment.
+
+ Otherwise, the <a href="postfix.1.html">postfix(1)</a> command uses the
+ <a href="postconf.5.html#multi_instance_wrapper">multi_instance_wrapper</a> parameter only when the
+ <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> parameter value is non-empty.
+
+ The multi-instance manager must replace a "start" command
+ by "check" when a Postfix instance does not have
+ "<a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a> = yes". This substitution ensures
+ that problems will still be reported.
+
+ Set-gid commands such as <a href="postdrop.1.html">postdrop(1)</a> and <a href="postqueue.1.html">postqueue(1)</a>
+ effectively append the <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> parame-
+ ter value to the legacy <a href="postconf.5.html#alternate_config_directories">alternate_config_directories</a>
+ parameter value.
+
+ The legacy <a href="postconf.5.html#alternate_config_directories">alternate_config_directories</a> parameter remains
+ necessary for non-default Postfix instances that are run-
+ ning different versions of Postfix, or that are not man-
+ aged together with the default Postfix instance.
+
+ No Postfix command or script will update or check shared
+ files unless it is running in the context of the default
+ Postfix instance.
+
+<b>ENVIRONMENT VARIABLES</b>
+ MAIL_CONFIG
+ When present, this forces the <a href="postfix.1.html">postfix(1)</a> command to
+ operate only on the specified Postfix instance.
+ This environment variable is exported by the post-
+ fix(1) -c option, so that <a href="postfix.1.html">postfix(1)</a> commands in
+ descendant processes will work correctly.
+
+<b>CONFIGURATION PARAMETERS</b>
+ <b><a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> (empty)</b>
+ An optional list of non-default Postfix configura-
+ tion directories; these directories belong to addi-
+ tional Postfix instances that share the Postfix
+ executable files and documentation with the default
+ Postfix instance, and that are started, stopped,
+ etc., together with the default Postfix instance.
+
+ <b><a href="postconf.5.html#multi_instance_wrapper">multi_instance_wrapper</a> (empty)</b>
+ The pathname of a multi-instance manager command
+ that the <a href="postfix.1.html"><b>postfix</b>(1)</a> command invokes when the
+ <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> parameter value is non-
+ empty.
+
+ <b><a href="postconf.5.html#multi_instance_name">multi_instance_name</a> (empty)</b>
+ The optional instance name of this Postfix
+ instance.
+
+ <b><a href="postconf.5.html#multi_instance_group">multi_instance_group</a> (empty)</b>
+ The optional instance group name of this Postfix
+ instance.
+
+ <b><a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a> (no)</b>
+ Allow this Postfix instance to be started, stopped,
+ etc., by a multi-instance manager.
+
+<b>NON-SHARED FILES</b>
+ <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
+ <a href="master.5.html">master.cf</a> configuration files.
+
+ <b><a href="postconf.5.html#data_directory">data_directory</a> (see 'postconf -d' output)</b>
+ The directory with Postfix-writable data files (for
+ example: caches, pseudo-random numbers).
+
+ <b><a href="postconf.5.html#queue_directory">queue_directory</a> (see 'postconf -d' output)</b>
+ The location of the Postfix top-level queue direc-
+ tory.
+
+<b>SEE ALSO</b>
+ <a href="postfix.1.html">postfix(1)</a> Postfix control program
+ postmulti(1) full-blown multi-instance manager
+
+<b>LICENSE</b>
+ The Secure Mailer license must be distributed with this
+ software.
+
+<b>AUTHOR(S)</b>
+ Wietse Venema
+ IBM T.J. Watson Research
+ P.O. Box 704
+ Yorktown Heights, NY 10598, USA
+
+ POSTFIX-WRAPPER(5)
+</pre> </body> </html>
fix mail system: start or stop the <a href="master.8.html"><b>master</b>(8)</a> daemon, do a
health check, and other maintenance.
- The <a href="postfix.1.html"><b>postfix</b>(1)</a> command sets up a standardized environment
- and runs the <b>postfix-script</b> shell script to do the actual
- work.
+ By default, the <a href="postfix.1.html"><b>postfix</b>(1)</a> command sets up a standardized
+ environment and runs the <b>postfix-script</b> shell script to do
+ the actual work.
+
+ However, when support for multiple Postfix instances is
+ configured, <a href="postfix.1.html"><b>postfix</b>(1)</a> executes the command specified with
+ the <b><a href="postconf.5.html#multi_instance_wrapper">multi_instance_wrapper</a></b> configuration parameter. This
+ command will execute the <i>command</i> for each applicable Post-
+ fix instance.
The following commands are implemented:
between multiple Postfix instances on the same
host.
+ With Postfix 2.6 and later, this option forces the
+ <a href="postfix.1.html">postfix(1)</a> command to operate on the specified
+ Postfix instance only. This behavior is inherited
+ by <a href="postfix.1.html">postfix(1)</a> commands that run as a descendant of
+ the current process.
+
<b>-D</b> (with <b>postfix start</b> only)
Run each Postfix daemon under control of a debugger
as specified via the <b><a href="postconf.5.html#debugger_command">debugger_command</a></b> configuration
This is set when the -c command-line option is
present.
+ With Postfix 2.6 and later, this environment vari-
+ able forces the <a href="postfix.1.html">postfix(1)</a> command to operate on
+ the specified Postfix instance only. This behavior
+ is inherited by <a href="postfix.1.html">postfix(1)</a> commands that run as a
+ descendant of the current process.
+
<b>MAIL_VERBOSE</b>
This is set when the -v command-line option is
present.
The directory with Postfix-writable data files (for
example: caches, pseudo-random numbers).
+ Available in Postfix version 2.6 and later:
+
+ <b><a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> (empty)</b>
+ An optional list of non-default Postfix configura-
+ tion directories; these directories belong to addi-
+ tional Postfix instances that share the Postfix
+ executable files and documentation with the default
+ Postfix instance, and that are started, stopped,
+ etc., together with the default Postfix instance.
+
+ <b><a href="postconf.5.html#multi_instance_wrapper">multi_instance_wrapper</a> (empty)</b>
+ The pathname of a multi-instance manager command
+ that the <a href="postfix.1.html"><b>postfix</b>(1)</a> command invokes when the
+ <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> parameter value is non-
+ empty.
+
+ <b><a href="postconf.5.html#multi_instance_group">multi_instance_group</a> (empty)</b>
+ The optional instance group name of this Postfix
+ instance.
+
+ <b><a href="postconf.5.html#multi_instance_name">multi_instance_name</a> (empty)</b>
+ The optional instance name of this Postfix
+ instance.
+
+ <b><a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a> (no)</b>
+ Allow this Postfix instance to be started, stopped,
+ etc., by a multi-instance manager.
+
Other configuration parameters:
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
<a href="master.5.html">master.cf</a> configuration files.
<b><a href="postconf.5.html#import_environment">import_environment</a> (see 'postconf -d' output)</b>
- The list of environment parameters that a Postfix
+ The list of environment parameters that a Postfix
process will import from a non-Postfix parent
process.
The syslog facility of Postfix logging.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (postfix)</b>
- The mail system name that is prepended to the
- process name in syslog records, so that "smtpd"
+ The mail system name that is prepended to the
+ process name in syslog records, so that "smtpd"
becomes, for example, "postfix/smtpd".
<b>FILES</b>
- Prior to Postfix version 2.6, all of the following files
- were in <b>$<a href="postconf.5.html#config_directory">config_directory</a></b>. Some files are now in <b>$<a href="postconf.5.html#daemon_directory">dae</a>-</b>
- <b><a href="postconf.5.html#daemon_directory">mon_directory</a></b> so that they can be shared among multiple
+ Prior to Postfix version 2.6, all of the following files
+ were in <b>$<a href="postconf.5.html#config_directory">config_directory</a></b>. Some files are now in <b>$<a href="postconf.5.html#daemon_directory">dae</a>-</b>
+ <b><a href="postconf.5.html#daemon_directory">mon_directory</a></b> so that they can be shared among multiple
instances that run the same Postfix version.
- Use the command "<b>postconf <a href="postconf.5.html#config_directory">config_directory</a></b>" or "<b>postconf</b>
- <b><a href="postconf.5.html#daemon_directory">daemon_directory</a></b>" to expand the names into their actual
+ Use the command "<b>postconf <a href="postconf.5.html#config_directory">config_directory</a></b>" or "<b>postconf</b>
+ <b><a href="postconf.5.html#daemon_directory">daemon_directory</a></b>" to expand the names into their actual
values.
$<a href="postconf.5.html#config_directory">config_directory</a>/<a href="postconf.5.html">main.cf</a>, Postfix configuration parameters
<a href="postlock.1.html">postlock(1)</a>, Postfix-compatible locking
<a href="postlog.1.html">postlog(1)</a>, Postfix-compatible logging
<a href="postmap.1.html">postmap(1)</a>, Postfix lookup table manager
+ postmulti(1), Postfix multi-instance manager
<a href="postqueue.1.html">postqueue(1)</a>, Postfix mail queue control
<a href="postsuper.1.html">postsuper(1)</a>, Postfix housekeeping
<a href="mailq.1.html">mailq(1)</a>, Sendmail compatibility interface
<a href="bounce.5.html">bounce(5)</a>, Postfix bounce message templates
<a href="master.5.html">master(5)</a>, Postfix <a href="master.5.html">master.cf</a> file syntax
<a href="postconf.5.html">postconf(5)</a>, Postfix <a href="postconf.5.html">main.cf</a> file syntax
+ <a href="postfix-wrapper.5.html">postfix-wrapper(5)</a>, Postfix multi-instance API
Table-driven mechanisms:
<a href="access.5.html">access(5)</a>, Postfix SMTP access control table
<a href="QSHAPE_README.html">QSHAPE_README</a>, Postfix queue analysis
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
man5/cidr_table.5 man5/tcp_table.5 man5/header_checks.5 \
man5/body_checks.5 man5/ldap_table.5 man5/mysql_table.5 \
man5/pgsql_table.5 man5/master.5 man5/nisplus_table.5 \
- man5/generic.5 man5/bounce.5
+ man5/generic.5 man5/bounce.5 man5/postfix-wrapper.5
TOOLS = man1/smtp-sink.1 man1/smtp-source.1 man1/qmqp-sink.1 \
man1/qmqp-source.1 man1/qshape.1
man5/virtual.5: ../proto/virtual
../mantools/srctoman - $? >$@
+man5/postfix-wrapper.5: ../proto/postfix-wrapper
+ ../mantools/fixman ../proto/postconf.proto $? >junk && \
+ (cmp -s junk $? || mv junk $?) && rm -f junk
+ ../mantools/srctoman - $? >$@
+
man1/smtp-sink.1: ../src/smtpstone/smtp-sink.c
../mantools/fixman ../proto/postconf.proto $? >junk && \
(cmp -s junk $? || mv junk $?) && rm -f junk
mail system: start or stop the \fBmaster\fR(8) daemon, do a health
check, and other maintenance.
-The \fBpostfix\fR(1) command sets up a standardized environment and
-runs the \fBpostfix-script\fR shell script to do the actual work.
+By default, the \fBpostfix\fR(1) command sets up a standardized
+environment and runs the \fBpostfix-script\fR shell script
+to do the actual work.
+
+However, when support for multiple Postfix instances is
+configured, \fBpostfix\fR(1) executes the command specified
+with the \fBmulti_instance_wrapper\fR configuration parameter.
+This command will execute the \fIcommand\fR for each
+applicable Postfix instance.
The following commands are implemented:
.IP \fBcheck\fR
the named directory instead of the default configuration directory.
Use this to distinguish between multiple Postfix instances on the
same host.
+
+With Postfix 2.6 and later, this option forces the postfix(1)
+command to operate on the specified Postfix instance only.
+This behavior is inherited by postfix(1) commands that run
+as a descendant of the current process.
.IP "\fB-D\fR (with \fBpostfix start\fR only)"
Run each Postfix daemon under control of a debugger as specified
via the \fBdebugger_command\fR configuration parameter.
variables before executing the \fBpostfix-script\fR file:
.IP \fBMAIL_CONFIG\fR
This is set when the -c command-line option is present.
+
+With Postfix 2.6 and later, this environment variable forces
+the postfix(1) command to operate on the specified Postfix
+instance only. This behavior is inherited by postfix(1)
+commands that run as a descendant of the current process.
.IP \fBMAIL_VERBOSE\fR
This is set when the -v command-line option is present.
.IP \fBMAIL_DEBUG\fR
The directory with Postfix-writable data files (for example:
caches, pseudo-random numbers).
.PP
+Available in Postfix version 2.6 and later:
+.IP "\fBmulti_instance_directories (empty)\fR"
+An optional list of non-default Postfix configuration directories;
+these directories belong to additional Postfix instances that share
+the Postfix executable files and documentation with the default
+Postfix instance, and that are started, stopped, etc., together
+with the default Postfix instance.
+.IP "\fBmulti_instance_wrapper (empty)\fR"
+The pathname of a multi-instance manager command that the
+\fBpostfix\fR(1) command invokes when the multi_instance_directories
+parameter value is non-empty.
+.IP "\fBmulti_instance_group (empty)\fR"
+The optional instance group name of this Postfix instance.
+.IP "\fBmulti_instance_name (empty)\fR"
+The optional instance name of this Postfix instance.
+.IP "\fBmulti_instance_enable (no)\fR"
+Allow this Postfix instance to be started, stopped, etc., by
+a multi-instance manager.
+.PP
Other configuration parameters:
.IP "\fBconfig_directory (see 'postconf -d' output)\fR"
The default location of the Postfix main.cf and master.cf
postlock(1), Postfix-compatible locking
postlog(1), Postfix-compatible logging
postmap(1), Postfix lookup table manager
+postmulti(1), Postfix multi-instance manager
postqueue(1), Postfix mail queue control
postsuper(1), Postfix housekeeping
mailq(1), Sendmail compatibility interface
bounce(5), Postfix bounce message templates
master(5), Postfix master.cf file syntax
postconf(5), Postfix main.cf file syntax
+postfix-wrapper(5), Postfix multi-instance API
Table-driven mechanisms:
access(5), Postfix SMTP access control table
(weeks). The default time unit is s (seconds).
.PP
This feature is available in Postfix 2.3 and later.
-.SH milter_connect_macros (default: see postconf -n output)
+.SH milter_connect_macros (default: see "postconf -d" output)
The macros that are sent to Milter (mail filter) applications
after completion of an SMTP connection. See MILTER_README
for a list of available macro names and their meanings.
(weeks). The default time unit is s (seconds).
.PP
This feature is available in Postfix 2.3 and later.
-.SH milter_data_macros (default: see postconf -n output)
+.SH milter_data_macros (default: see "postconf -d" output)
The macros that are sent to version 4 or higher Milter (mail
filter) applications after the SMTP DATA command. See MILTER_README
for a list of available macro names and their meanings.
the "hold" queue. Available with Postfix 2.6 and later.
.PP
This feature is available in Postfix 2.3 and later.
-.SH milter_end_of_data_macros (default: see postconf -n output)
+.SH milter_end_of_data_macros (default: see "postconf -d" output)
The macros that are sent to Milter (mail filter) applications
after the message end-of-data. See MILTER_README for a list of
available macro names and their meanings.
.PP
This feature is available in Postfix 2.3 and later.
-.SH milter_end_of_header_macros (default: see postconf -n output)
+.SH milter_end_of_header_macros (default: see "postconf -d" output)
The macros that are sent to Milter (mail filter) applications
after the end of the message header. See MILTER_README for a list
of available macro names and their meanings.
.PP
This feature is available in Postfix 2.5 and later.
-.SH milter_helo_macros (default: see postconf -n output)
+.SH milter_helo_macros (default: see "postconf -d" output)
The macros that are sent to Milter (mail filter) applications
after the SMTP HELO or EHLO command. See
MILTER_README for a list of available macro names and their meanings.
meanings.
.PP
This feature is available in Postfix 2.3 and later.
-.SH milter_mail_macros (default: see postconf -n output)
+.SH milter_mail_macros (default: see "postconf -d" output)
The macros that are sent to Milter (mail filter) applications
after the SMTP MAIL FROM command. See MILTER_README
for a list of available macro names and their meanings.
will not reply for each individual message header.
.PP
This feature is available in Postfix 2.3 and later.
-.SH milter_rcpt_macros (default: see postconf -n output)
+.SH milter_rcpt_macros (default: see "postconf -d" output)
The macros that are sent to Milter (mail filter) applications
after the SMTP RCPT TO command. See MILTER_README
for a list of available macro names and their meanings.
.PP
This feature is available in Postfix 2.3 and later.
-.SH milter_unknown_command_macros (default: see postconf -n output)
+.SH milter_unknown_command_macros (default: see "postconf -d" output)
The macros that are sent to version 3 or higher Milter (mail
filter) applications after an unknown SMTP command. See MILTER_README
for a list of available macro names and their meanings.
.PP
Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
The default time unit is s (seconds).
+.SH multi_instance_directories (default: empty)
+An optional list of non-default Postfix configuration directories;
+these directories belong to additional Postfix instances that share
+the Postfix executable files and documentation with the default
+Postfix instance, and that are started, stopped, etc., together
+with the default Postfix instance. Specify a list of pathnames
+separated by comma or whitespace.
+.PP
+This feature is available in Postfix 2.6 and later.
+.PP
+When the list of non-default Postfix configuration directories
+is non-empty, the \fBpostfix\fR(1) command will invoke the multi-instance
+manager specified with the multi_instance_wrapper parameter to
+execute commands on the default instance and on all additional
+Postfix instances.
+.PP
+This feature is available in Postfix 2.6 and later.
+.SH multi_instance_enable (default: no)
+Allow this Postfix instance to be started, stopped, etc., by a
+multi-instance manager. By default, new instances are created in
+a safe state that prevents them from being started inadvertently.
+This parameter is reserved for the multi-instance manager.
+.PP
+This feature is available in Postfix 2.6 and later.
+.SH multi_instance_group (default: empty)
+The optional instance group name of this Postfix instance. A
+group identifies closely-related Postfix instances that the
+multi-instance manager can start, stop, etc., as a unit. This
+parameter is reserved for the multi-instance manager.
+.PP
+This feature is available in Postfix 2.6 and later.
+.SH multi_instance_name (default: empty)
+The optional instance name of this Postfix instance. This name
+becomes also the default value for the syslog_name parameter.
+.PP
+This feature is available in Postfix 2.6 and later.
+.SH multi_instance_wrapper (default: empty)
+The pathname of a multi-instance manager command that the
+\fBpostfix\fR(1) command invokes when the multi_instance_directories
+parameter value is non-empty. The pathname may be followed by
+initial command arguments separated by whitespace; shell
+metacharacters are not supported in this context.
+.PP
+The \fBpostfix\fR(1) command invokes the manager command with the
+\fBpostfix\fR(1) non-option command arguments on the manager command line,
+and with all installation configuration parameters exported into
+the manager command process environment. The manager command in
+turn invokes the \fBpostfix\fR(1) command for individual Postfix instances
+as "postfix -c \fIconfig_directory\fR \fIcommand\fR".
+.PP
+This feature is available in Postfix 2.6 and later.
.SH multi_recipient_bounce_reject_code (default: 550)
The numerical Postfix SMTP server response code when a remote SMTP
client request is blocked by the reject_multi_recipient_bounce
process initialization will be logged with the default facility.
Examples are errors while parsing the command line arguments, and
errors while accessing the Postfix main.cf configuration file.
-.SH syslog_name (default: postfix)
+.SH syslog_name (default: see "postconf -d" output)
The mail system name that is prepended to the process name in syslog
records, so that "smtpd" becomes, for example, "postfix/smtpd".
.PP
--- /dev/null
+.TH POSTFIX-WRAPPER 5
+.ad
+.fi
+.SH NAME
+postfix-wrapper
+\-
+Postfix multi-instance API
+.SH DESCRIPTION
+.ad
+.fi
+This document describes an interface that allows a
+multi-instance manager to plug into Postfix and to control
+multiple Postfix instances.
+
+Each Postfix instance is defined by its own configuration
+directory with its own main.cf and master.cf files, by its
+own queue and data directories, and by its own myhostname
+and inet_interfaces settings. Other Postfix files, including
+executable files and documentation, are shared between
+Postfix instances.
+
+Only the default Postfix instance is required. The location
+of its configuration files is specified by the built-in
+default value for the config_directory parameter. Other
+Postfix instances are optional.
+.SH "GENERAL OPERATION"
+.na
+.nf
+.ad
+.fi
+First of all, nothing changes when there is only one Postfix
+instance.
+
+Even after multi-instance support has been set up through
+the mechanisms discussed later, sites can still continue
+to use the familiar "postfix start / stop / reload / upgrade
+/ etc" commands in boot scripts, build procedures, etc.
+
+To start, stop, update, etc., multiple Postfix instances,
+use:
+
+.nf
+ # postfix \fIcommand\fR
+.fi
+
+For example, to find out what Postfix instances are configured:
+
+.nf
+ # postfix status
+
+To manage an individual Postfix instance, use:
+
+.nf
+ # postfix -c \fI/path/to/config_directory command\fR
+.fi
+.SH "MULTI-INSTANCE DETECTION"
+.na
+.nf
+.ad
+.fi
+While "postfix start/stop/etc" will remain the primary
+command interface, the postfix(1) command itself will need
+to figure out if a command targets multiple Postfix instances
+or just a specific Postfix instance. This decision can be
+made with information that is already available:
+.IP
+When the postfix(1) command is invoked with the -c
+option, it will operate only on the specified instance.
+We do the same when MAIL_CONFIG is specified in the
+process environment.
+
+Otherwise, the postfix(1) command will operate on all
+applicable Postfix instances.
+.SH "MULTI-INSTANCE MANAGER HOOK"
+.na
+.nf
+.ad
+.fi
+When the postfix(1) command is invoked without -c option,
+and non-default Postfix instance directories are defined
+in main.cf with multi_instance_directories, then the
+postfix(1) command invokes the command specified in main.cf
+with multi_instance_wrapper, instead of invoking postfix-script.
+The multi_instance_wrapper and other main.cf parameters are
+listed in the CONFIGURATION PARAMETERS section below.
+
+A useful wrapper implementation can be as simple as:
+
+.nf
+.ft C
+ #!/bin/sh
+
+ : ${command_directory?"do not invoke this command directly"}
+
+ POSTCONF=$command_directory/postconf
+ POSTFIX=$command_directory/postfix
+ instance_dirs=`$POSTCONF -h multi_instance_directories |
+ sed 's/,/ /'` || exit 1
+
+ for dir in $config_directory $instance_dirs
+ do
+ case "$1" in
+ stop|abort|flush|reload|drain)
+ test "`$POSTCONF -c $dir -h multi_instance_enable`"
+ = yes || continue;;
+ start)
+ test "`$POSTCONF -c $dir -h multi_instance_enable`"
+ = yes || set check;;
+ esac
+ $POSTFIX -c $dir "$@" || err=$?
+ done
+
+ exit $err
+.ft
+.fi
+
+This wrapper skips commands such as "stop" that require a
+running Postfix instance when a Postfix instance is disabled,
+and replaces "start" by "check" so that problems will still
+be reported.
+
+The postmulti(1) command implements a more sophisticated
+approach, based on a combination of C code and scripting.
+.SH "SHARED VERSUS NON-SHARED FILES"
+.na
+.nf
+.ad
+.fi
+Some files are shared between Postfix instances (such as
+executables and manpages) and some files are per-instance
+(such as the queue). See the NON-SHARED FILES section below
+for a list of per-instance files.
+
+Until now, executables, manpages, etc., have been checked
+or updated as part of the default Postfix instance. With
+multi-instance support, we simply continue to do this.
+Non-default Postfix instances will check or update only
+their non-shared files.
+
+The consequence of this approach is that the default Postfix
+instance should be updated before any other instances.
+.SH "IMPLEMENTATION NOTES"
+.na
+.nf
+.ad
+.fi
+The postfix(1) command ignores the multi_instance_directories
+and multi_instance_wrapper parameters when the -c option
+is specified, or when MAIL_CONFIG is present in the process
+environment.
+
+Otherwise, the postfix(1) command uses the multi_instance_wrapper
+parameter only when the multi_instance_directories parameter
+value is non-empty.
+
+The multi-instance manager must replace a "start" command by
+"check" when a Postfix instance does not have
+"multi_instance_enable = yes". This substitution ensures
+that problems will still be reported.
+
+Set-gid commands such as postdrop(1) and postqueue(1)
+effectively append the multi_instance_directories parameter
+value to the legacy alternate_config_directories parameter
+value.
+
+The legacy alternate_config_directories parameter remains
+necessary for non-default Postfix instances that are running
+different versions of Postfix, or that are not managed
+together with the default Postfix instance.
+
+No Postfix command or script will update or check shared
+files unless it is running in the context of the default
+Postfix instance.
+.SH "ENVIRONMENT VARIABLES"
+.na
+.nf
+.ad
+.fi
+.IP MAIL_CONFIG
+When present, this forces the postfix(1) command to operate
+only on the specified Postfix instance. This environment
+variable is exported by the postfix(1) -c option, so that
+postfix(1) commands in descendant processes will work
+correctly.
+.SH "CONFIGURATION PARAMETERS"
+.na
+.nf
+.ad
+.fi
+.IP "\fBmulti_instance_directories (empty)\fR"
+An optional list of non-default Postfix configuration directories;
+these directories belong to additional Postfix instances that share
+the Postfix executable files and documentation with the default
+Postfix instance, and that are started, stopped, etc., together
+with the default Postfix instance.
+.IP "\fBmulti_instance_wrapper (empty)\fR"
+The pathname of a multi-instance manager command that the
+\fBpostfix\fR(1) command invokes when the multi_instance_directories
+parameter value is non-empty.
+.IP "\fBmulti_instance_name (empty)\fR"
+The optional instance name of this Postfix instance.
+.IP "\fBmulti_instance_group (empty)\fR"
+The optional instance group name of this Postfix instance.
+.IP "\fBmulti_instance_enable (no)\fR"
+Allow this Postfix instance to be started, stopped, etc., by a
+multi-instance manager.
+.SH "NON-SHARED FILES"
+.na
+.nf
+.ad
+.fi
+.IP "\fBconfig_directory (see 'postconf -d' output)\fR"
+The default location of the Postfix main.cf and master.cf
+configuration files.
+.IP "\fBdata_directory (see 'postconf -d' output)\fR"
+The directory with Postfix-writable data files (for example:
+caches, pseudo-random numbers).
+.IP "\fBqueue_directory (see 'postconf -d' output)\fR"
+The location of the Postfix top-level queue directory.
+.SH "SEE ALSO"
+.na
+.nf
+postfix(1) Postfix control program
+postmulti(1) full-blown multi-instance manager
+.SH "LICENSE"
+.na
+.nf
+.ad
+.fi
+The Secure Mailer license must be distributed with this software.
+.SH "AUTHOR(S)"
+.na
+.nf
+Wietse Venema
+IBM T.J. Watson Research
+P.O. Box 704
+Yorktown Heights, NY 10598, USA
# Emit one parameter name and text
-sub emit_text()
+sub emit_text
{
+ my ($delim) = @_;
if ($block = $param_text{$name}) {
- print "/* .IP \"\\fB$name ($defval_text{$name})\\fR\"\n";
+ print "$delim .IP \"\\fB$name ($defval_text{$name})\\fR\"\n";
$wantpp = 0;
$block =~ s/<a [^>]*>//g;
$block =~ s/<\/a>//g;
$block =~ s/([_a-zA-Z0-9-]+)(\([0-9]\))/\\fB\1\\fR\2/g;
# Encapsulate as C code comment.
- $block =~ s/^([^.])/\/\*\t\1/;
- $block =~ s/^\./\/\* ./;
- $block =~ s/\n([^.])/\n\/\*\t\1/g;
- $block =~ s/\n\./\n\/\* ./g;
+ $block =~ s/^([^.])/$delim\t\1/;
+ $block =~ s/^\./$delim ./;
+ $block =~ s/\n([^.])/\n$delim\t\1/g;
+ $block =~ s/\n\./\n$delim ./g;
print $block;
} else {
- print "/* .IP \"\\fB$name ($defval)\\fR\"\n";
+ print "$delim .IP \"\\fB$name ($defval)\\fR\"\n";
print $text;
}
$name = "";
save_text();
}
-# Process source file with embedded text. For now, hard-coded for C.
+# Process source file with embedded text. For now, hard-coded for C & sh.
while(<>) {
- if (/^\/\*\+\+/) {
+ if (/^(\/\*|#)\+\+/) {
$incomment = 1;
$name = "";
print;
next;
}
- if (/^\/\*--/) {
- emit_text() if ($name ne "");
+ if (/^(\/\*|#)--/) {
+ emit_text($1) if ($name ne "");
$incomment = 0;
print;
next;
next;
}
- if (/\/\* +CONFIGURATION +PARAM/) {
+ if (/(\/\*|#) +CONFIGURATION +PARAM/) {
$incomment = 2;
}
# Delete text after nested itemized list.
- if ($incomment == 2 && /^\/\* +\.IP ""/) {
+ if ($incomment == 2 && /^(\/\*|#) +\.IP ""/) {
$text .= $_;
while (<>) {
- last if /^\/\* +([A-Z][A-Z][A-Z]+|\.[A-Z][A-Z])/;
+ last if /^(\/\*|#) +([A-Z][A-Z][A-Z]+|\.[A-Z][A-Z])/;
$text .= $_;
}
}
# Delete nested itemized list.
- if ($incomment == 2 && /^\/\* +\.RS/) {
+ if ($incomment == 2 && /^(\/\*|#) +\.RS/) {
$text .= $_;
$rsnest++;
while (<>) {
$text .= $_;
- $rsnest++ if /^\/\* +\.RS/;
- $rsnest-- if /\/\* +\.RE/;
+ $rsnest++ if /^(\/\*|#) +\.RS/;
+ $rsnest-- if /(\/\*|#) +\.RE/;
last if $rsnest == 0;
}
next;
}
- if ($incomment == 2 && /^\/\* +\.IP +"?\\fB([a-zA-Z0-9_]+)( +\((.*)\))?/) {
- emit_text() if ($name ne "");
- $name = $1;
- $defval = $3;
+ if ($incomment == 2 && /^(\/\*|#) +\.IP +"?\\fB([a-zA-Z0-9_]+)( +\((.*)\))?/) {
+ emit_text($1) if ($name ne "");
+ $name = $2;
+ $defval = $4;
$text = "";
next;
}
- if ($incomment == 2 && /^\/\* +([A-Z][A-Z][A-Z]+|\.[A-Z][A-Z])/) {
- emit_text() if ($name ne "");
- $incomment = 0 if /^\/\* +(SEE +ALSO|README +FILES|LICENSE|AUTHOR)/;
+ if ($incomment == 2 && /^(\/\*|#) +([A-Z][A-Z][A-Z]+|\.[A-Z][A-Z])/) {
+ emit_text($1) if ($name ne "");
+ $incomment = 0 if /^(\/\*|#) +(SEE +ALSO|README +FILES|LICENSE|AUTHOR)/;
print;
next;
}
s;\ballow_min_user\b;<a href="postconf.5.html#allow_min_user">$&</a>;g;
s;\ballow_percent_hack\b;<a href="postconf.5.html#allow_percent_hack">$&</a>;g;
s;\ballow_untrusted_routing\b;<a href="postconf.5.html#allow_untrusted_routing">$&</a>;g;
- s;\balternate_config_directories\b;<a href="postconf.5.html#alternate_config_directories">$&</a>;g;
+ s;\balternate_config_direc[-</bB>]*\n*[ <bB>]*tories\b;<a href="postconf.5.html#alternate_config_directories">$&</a>;g;
s;\balways_bcc\b;<a href="postconf.5.html#always_bcc">$&</a>;g;
s;\banvil_rate_time_unit\b;<a href="postconf.5.html#anvil_rate_time_unit">$&</a>;g;
s;\bappend_at_myorigin\b;<a href="postconf.5.html#append_at_myorigin">$&</a>;g;
s/[<bB>]*pcre[<\/bBiI>]*_[<\/iIbB>]*ta[-<\/bB>]*\n*[ <bB>]*ble[<\/bB>]*\(5\)/<a href="pcre_table.5.html">$&<\/a>/g;
s/[<bB>]*pgsql[<\/bBiI>]*_[<\/iIbB>]*ta[-<\/bB>]*\n*[ <bB>]*ble[<\/bB>]*\(5\)/<a href="pgsql_table.5.html">$&<\/a>/g;
s/[<bB>]*postconf[<\/bB>]*\(5\)/<a href="postconf.5.html">$&<\/a>/g;
+ s/[<bB>]*postfix-wrapper[<\/bB>]*\(5\)/<a href="postfix-wrapper.5.html">$&<\/a>/g;
s/[<bB>]*prox[-<\/bB>]*\n*[ <bB>]*ymap[<\/bB>]*\(8\)/<a href="proxymap.8.html">$&<\/a>/g;
s/[<bB>]*reg[-<\/bB>]*\n*[ <bB>]*exp[<\/bBiI>]*_[<\/iIbB>]*ta[-<\/bB>]*\n*[ <bB>]*ble[<\/bB>]*\(5\)/<a href="regexp_table.5.html">$&<\/a>/g;
s/[<bB>]*relocated[<\/bB>]*\(5\)/<a href="relocated.5.html">$&<\/a>/g;
s;\bmilter_end_of_data_macros\b;<a href="postconf.5.html#milter_end_of_data_macros">$&</a>;g;
s;\bmilter_end_of_header_macros\b;<a href="postconf.5.html#milter_end_of_header_macros">$&</a>;g;
+ # Multi-instance support
+ s;\bmulti_instance_directo[-</bB>]*\n*[ <bB>]*ries\b;<a href="postconf.5.html#multi_instance_directories">$&</a>;g;
+ s;\bmulti_instance_wrapper\b;<a href="postconf.5.html#multi_instance_wrapper">$&</a>;g;
+ s;\bmulti_instance_group\b;<a href="postconf.5.html#multi_instance_group">$&</a>;g;
+ s;\bmulti_instance_name\b;<a href="postconf.5.html#multi_instance_name">$&</a>;g;
+ s;\bmulti_instance_enable\b;<a href="postconf.5.html#multi_instance_enable">$&</a>;g;
+
+
# Hyperlink URLs and RFC documents
s/(http:\/\/[^ ,"\(\)]*[^ ,"\(\):;!?.])/<a href="$1">$1<\/a>/;
<li><a href="#client_tls_limits"> Client TLS limitations </a>
-<li><a href="#client_tls_levels"> Client TLS security levels </a>
-
-<li><a href="#client_tls_none"> Disabling TLS in the SMTP/LMTP client</a>
-
-<li><a href="#client_tls_may"> Enabling TLS in the SMTP/LMTP client </a>
-
-<li><a href="#client_tls_encrypt"> Mandating TLS encryption </a>
-
-<li><a href="#client_tls_fprint"> Certificate fingerprint verification </a>
-
-<li><a href="#client_tls_verify"> Mandating server certificate verification </a>
-
-<li><a href="#client_tls_secure"> Secure server certificate verification </a>
+<li><a href="#client_tls_levels"> Configuring TLS in the SMTP/LMTP client </a>
<li><a href="#client_tls_policy"> Per-destination TLS policy </a>
for secure connections via aliases for HTTPS and Kerberos. SMTP merely
uses indirect naming (via MX records) more frequently. </p>
-<h3><a name="client_tls_levels"> Client TLS security levels </a>
+<h3><a name="client_tls_levels"> Configuring TLS in the SMTP/LMTP client </a>
</h3>
-<p> The TLS security levels listed below are described in more detail
-in the sections that follow.</p>
+<p> Similar to the Postfix SMTP server, the Postfix SMTP/LMTP client
+implements multiple TLS security levels. These levels are described
+in more detail in the sections that follow.</p>
<dl>
<dt><b>none</b></dt>
<dd><a href="#client_tls_secure">Secure-channel TLS.</a>
</dl>
-<h3><a name="client_tls_none"> Disabling TLS in the SMTP/LMTP client </a>
+<h3><a name="client_tls_none"> No TLS encryption </a>
</h3>
<p> At the "none" TLS security level, TLS encryption is
<h3> <a name="client_tls_policy"> TLS policy table </a>
</h3>
-<p> Postfix 2.3 introduces a new more flexible TLS policy table. For
+<p> The current TLS policy table was introduced with Postfix 2.3. For
earlier releases, read the description of the obsolete Postfix 2.2 <a
href="#client_tls_obs">per-site</a> table. </p>
errors while accessing the Postfix main.cf configuration file.
</p>
-%PARAM syslog_name postfix
+%PARAM syslog_name see "postconf -d" output
<p>
The mail system name that is prepended to the process name in syslog
<p> This feature is available in Postfix 2.3 and later. </p>
-%PARAM milter_connect_macros see postconf -n output
+%PARAM milter_connect_macros see "postconf -d" output
<p> The macros that are sent to Milter (mail filter) applications
after completion of an SMTP connection. See MILTER_README
<p> This feature is available in Postfix 2.3 and later. </p>
-%PARAM milter_helo_macros see postconf -n output
+%PARAM milter_helo_macros see "postconf -d" output
<p> The macros that are sent to Milter (mail filter) applications
after the SMTP HELO or EHLO command. See
<p> This feature is available in Postfix 2.3 and later. </p>
-%PARAM milter_mail_macros see postconf -n output
+%PARAM milter_mail_macros see "postconf -d" output
<p> The macros that are sent to Milter (mail filter) applications
after the SMTP MAIL FROM command. See MILTER_README
<p> This feature is available in Postfix 2.3 and later. </p>
-%PARAM milter_rcpt_macros see postconf -n output
+%PARAM milter_rcpt_macros see "postconf -d" output
<p> The macros that are sent to Milter (mail filter) applications
after the SMTP RCPT TO command. See MILTER_README
<p> This feature is available in Postfix 2.3 and later. </p>
-%PARAM milter_data_macros see postconf -n output
+%PARAM milter_data_macros see "postconf -d" output
<p> The macros that are sent to version 4 or higher Milter (mail
filter) applications after the SMTP DATA command. See MILTER_README
<p> This feature is available in Postfix 2.3 and later. </p>
-%PARAM milter_end_of_header_macros see postconf -n output
+%PARAM milter_end_of_header_macros see "postconf -d" output
<p> The macros that are sent to Milter (mail filter) applications
after the end of the message header. See MILTER_README for a list
<p> This feature is available in Postfix 2.5 and later. </p>
-%PARAM milter_end_of_data_macros see postconf -n output
+%PARAM milter_end_of_data_macros see "postconf -d" output
<p> The macros that are sent to Milter (mail filter) applications
after the message end-of-data. See MILTER_README for a list of
<p> This feature is available in Postfix 2.3 and later. </p>
-%PARAM milter_unknown_command_macros see postconf -n output
+%PARAM milter_unknown_command_macros see "postconf -d" output
<p> The macros that are sent to version 3 or higher Milter (mail
filter) applications after an unknown SMTP command. See MILTER_README
lmtp(8)). </p>
<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM multi_instance_directories
+
+<p> An optional list of non-default Postfix configuration directories;
+these directories belong to additional Postfix instances that share
+the Postfix executable files and documentation with the default
+Postfix instance, and that are started, stopped, etc., together
+with the default Postfix instance. Specify a list of pathnames
+separated by comma or whitespace. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+<p> When the list of non-default Postfix configuration directories
+is non-empty, the postfix(1) command will invoke the multi-instance
+manager specified with the multi_instance_wrapper parameter to
+execute commands on the default instance and on all additional
+Postfix instances. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM multi_instance_wrapper
+
+<p> The pathname of a multi-instance manager command that the
+postfix(1) command invokes when the multi_instance_directories
+parameter value is non-empty. The pathname may be followed by
+initial command arguments separated by whitespace; shell
+metacharacters are not supported in this context. </p>
+
+<p> The postfix(1) command invokes the manager command with the
+postfix(1) non-option command arguments on the manager command line,
+and with all installation configuration parameters exported into
+the manager command process environment. The manager command in
+turn invokes the postfix(1) command for individual Postfix instances
+as "postfix -c <i>config_directory</i> <i>command</i>". </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM multi_instance_group
+
+<p> The optional instance group name of this Postfix instance. A
+group identifies closely-related Postfix instances that the
+multi-instance manager can start, stop, etc., as a unit. This
+parameter is reserved for the multi-instance manager. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM multi_instance_name
+
+<p> The optional instance name of this Postfix instance. This name
+becomes also the default value for the syslog_name parameter. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM multi_instance_enable no
+
+<p> Allow this Postfix instance to be started, stopped, etc., by a
+multi-instance manager. By default, new instances are created in
+a safe state that prevents them from being started inadvertently.
+This parameter is reserved for the multi-instance manager. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
--- /dev/null
+#++
+# NAME
+# postfix-wrapper 5
+# SUMMARY
+# Postfix multi-instance API
+# DESCRIPTION
+# This document describes an interface that allows a
+# multi-instance manager to plug into Postfix and to control
+# multiple Postfix instances.
+#
+# Each Postfix instance is defined by its own configuration
+# directory with its own main.cf and master.cf files, by its
+# own queue and data directories, and by its own myhostname
+# and inet_interfaces settings. Other Postfix files, including
+# executable files and documentation, are shared between
+# Postfix instances.
+#
+# Only the default Postfix instance is required. The location
+# of its configuration files is specified by the built-in
+# default value for the config_directory parameter. Other
+# Postfix instances are optional.
+# GENERAL OPERATION
+# .ad
+# .fi
+# First of all, nothing changes when there is only one Postfix
+# instance.
+#
+# Even after multi-instance support has been set up through
+# the mechanisms discussed later, sites can still continue
+# to use the familiar "postfix start / stop / reload / upgrade
+# / etc" commands in boot scripts, build procedures, etc.
+#
+# To start, stop, update, etc., multiple Postfix instances,
+# use:
+#
+# .nf
+# # postfix \fIcommand\fR
+# .fi
+#
+# For example, to find out what Postfix instances are configured:
+#
+# .nf
+# # postfix status
+#
+# To manage an individual Postfix instance, use:
+#
+# .nf
+# # postfix -c \fI/path/to/config_directory command\fR
+# .fi
+# MULTI-INSTANCE DETECTION
+# .ad
+# .fi
+# While "postfix start/stop/etc" will remain the primary
+# command interface, the postfix(1) command itself will need
+# to figure out if a command targets multiple Postfix instances
+# or just a specific Postfix instance. This decision can be
+# made with information that is already available:
+# .IP
+# When the postfix(1) command is invoked with the -c
+# option, it will operate only on the specified instance.
+# We do the same when MAIL_CONFIG is specified in the
+# process environment.
+#
+# Otherwise, the postfix(1) command will operate on all
+# applicable Postfix instances.
+# MULTI-INSTANCE MANAGER HOOK
+# .ad
+# .fi
+# When the postfix(1) command is invoked without -c option,
+# and non-default Postfix instance directories are defined
+# in main.cf with multi_instance_directories, then the
+# postfix(1) command invokes the command specified in main.cf
+# with multi_instance_wrapper, instead of invoking postfix-script.
+# The multi_instance_wrapper and other main.cf parameters are
+# listed in the CONFIGURATION PARAMETERS section below.
+#
+# A useful wrapper implementation can be as simple as:
+#
+# .nf
+# .ft C
+# #!/bin/sh
+#
+# : ${command_directory?"do not invoke this command directly"}
+#
+# POSTCONF=$command_directory/postconf
+# POSTFIX=$command_directory/postfix
+# instance_dirs=`$POSTCONF -h multi_instance_directories |
+# sed 's/,/ /'` || exit 1
+#
+# for dir in $config_directory $instance_dirs
+# do
+# case "$1" in
+# stop|abort|flush|reload|drain)
+# test "`$POSTCONF -c $dir -h multi_instance_enable`"
+# = yes || continue;;
+# start)
+# test "`$POSTCONF -c $dir -h multi_instance_enable`"
+# = yes || set check;;
+# esac
+# $POSTFIX -c $dir "$@" || err=$?
+# done
+#
+# exit $err
+# .ft
+# .fi
+#
+# This wrapper skips commands such as "stop" that require a
+# running Postfix instance when a Postfix instance is disabled,
+# and replaces "start" by "check" so that problems will still
+# be reported.
+#
+# The postmulti(1) command implements a more sophisticated
+# approach, based on a combination of C code and scripting.
+# SHARED VERSUS NON-SHARED FILES
+# .ad
+# .fi
+# Some files are shared between Postfix instances (such as
+# executables and manpages) and some files are per-instance
+# (such as the queue). See the NON-SHARED FILES section below
+# for a list of per-instance files.
+#
+# Until now, executables, manpages, etc., have been checked
+# or updated as part of the default Postfix instance. With
+# multi-instance support, we simply continue to do this.
+# Non-default Postfix instances will check or update only
+# their non-shared files.
+#
+# The consequence of this approach is that the default Postfix
+# instance should be updated before any other instances.
+# IMPLEMENTATION NOTES
+# .ad
+# .fi
+# The postfix(1) command ignores the multi_instance_directories
+# and multi_instance_wrapper parameters when the -c option
+# is specified, or when MAIL_CONFIG is present in the process
+# environment.
+#
+# Otherwise, the postfix(1) command uses the multi_instance_wrapper
+# parameter only when the multi_instance_directories parameter
+# value is non-empty.
+#
+# The multi-instance manager must replace a "start" command by
+# "check" when a Postfix instance does not have
+# "multi_instance_enable = yes". This substitution ensures
+# that problems will still be reported.
+#
+# Set-gid commands such as postdrop(1) and postqueue(1)
+# effectively append the multi_instance_directories parameter
+# value to the legacy alternate_config_directories parameter
+# value.
+#
+# The legacy alternate_config_directories parameter remains
+# necessary for non-default Postfix instances that are running
+# different versions of Postfix, or that are not managed
+# together with the default Postfix instance.
+#
+# No Postfix command or script will update or check shared
+# files unless it is running in the context of the default
+# Postfix instance.
+# ENVIRONMENT VARIABLES
+# .ad
+# .fi
+# .IP MAIL_CONFIG
+# When present, this forces the postfix(1) command to operate
+# only on the specified Postfix instance. This environment
+# variable is exported by the postfix(1) -c option, so that
+# postfix(1) commands in descendant processes will work
+# correctly.
+# CONFIGURATION PARAMETERS
+# .ad
+# .fi
+# .IP "\fBmulti_instance_directories (empty)\fR"
+# An optional list of non-default Postfix configuration directories;
+# these directories belong to additional Postfix instances that share
+# the Postfix executable files and documentation with the default
+# Postfix instance, and that are started, stopped, etc., together
+# with the default Postfix instance.
+# .IP "\fBmulti_instance_wrapper (empty)\fR"
+# The pathname of a multi-instance manager command that the
+# \fBpostfix\fR(1) command invokes when the multi_instance_directories
+# parameter value is non-empty.
+# .IP "\fBmulti_instance_name (empty)\fR"
+# The optional instance name of this Postfix instance.
+# .IP "\fBmulti_instance_group (empty)\fR"
+# The optional instance group name of this Postfix instance.
+# .IP "\fBmulti_instance_enable (no)\fR"
+# Allow this Postfix instance to be started, stopped, etc., by a
+# multi-instance manager.
+# NON-SHARED FILES
+# .ad
+# .fi
+# .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
+# The default location of the Postfix main.cf and master.cf
+# configuration files.
+# .IP "\fBdata_directory (see 'postconf -d' output)\fR"
+# The directory with Postfix-writable data files (for example:
+# caches, pseudo-random numbers).
+# .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
+# The location of the Postfix top-level queue directory.
+# SEE ALSO
+# postfix(1) Postfix control program
+# 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
+#--
&& (rcpt->dsn_notify & DSN_NOTIFY_FAILURE) == 0) {
bounce_status = 0;
} else {
- verp_sender(verp_buf, verp_delims, recipient, rcpt->orig_addr[0] ?
- rcpt->orig_addr : rcpt->address);
+ verp_sender(verp_buf, verp_delims, recipient, rcpt);
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, STR(verp_buf),
INT_FILT_BOUNCE,
NULL_TRACE_FLAGS,
buf = vstring_alloc(1);
while (found == 0 && readlline(buf, fp, (int *) 0)) {
if (split_nameval(vstring_str(buf), &name, &value) == 0
- && strcmp(name, VAR_CONFIG_DIRS) == 0) {
+ && (strcmp(name, VAR_CONFIG_DIRS) == 0
+ || strcmp(name, VAR_MULTI_CONF_DIRS) == 0)) {
while (found == 0 && (cp = mystrtok(&value, ", \t\r\n")) != 0)
if (strcmp(cp, config_dir) == 0)
found = 1;
/* char *var_int_filt_classes;
/* int var_cyrus_sasl_authzid;
/*
+/* char *var_multi_conf_dirs;
+/* char *var_multi_wrapper;
+/* char *var_multi_group;
+/* char *var_multi_name;
+/* bool var_multi_enable;
+/*
/* void mail_params_init()
/*
/* const char null_format_string[1];
char *var_int_filt_classes;
int var_cyrus_sasl_authzid;
+char *var_multi_conf_dirs;
+char *var_multi_wrapper;
+char *var_multi_group;
+char *var_multi_name;
+bool var_multi_enable;
+
const char null_format_string[1] = "";
/* check_myhostname - lookup hostname and validate */
static const CONFIG_STR_TABLE first_str_defaults[] = {
VAR_SYSLOG_FACILITY, DEF_SYSLOG_FACILITY, &var_syslog_facility, 1, 0,
VAR_INET_PROTOCOLS, DEF_INET_PROTOCOLS, &var_inet_protocols, 1, 0,
+ VAR_MULTI_CONF_DIRS, DEF_MULTI_CONF_DIRS, &var_multi_conf_dirs, 0, 0,
+ VAR_MULTI_WRAPPER, DEF_MULTI_WRAPPER, &var_multi_wrapper, 0, 0,
+ VAR_MULTI_GROUP, DEF_MULTI_GROUP, &var_multi_group, 0, 0,
+ VAR_MULTI_NAME, DEF_MULTI_NAME, &var_multi_name, 0, 0,
0,
};
static const CONFIG_STR_FN_TABLE function_str_defaults[] = {
VAR_OLDLOG_COMPAT, DEF_OLDLOG_COMPAT, &var_oldlog_compat,
VAR_HELPFUL_WARNINGS, DEF_HELPFUL_WARNINGS, &var_helpful_warnings,
VAR_CYRUS_SASL_AUTHZID, DEF_CYRUS_SASL_AUTHZID, &var_cyrus_sasl_authzid,
+ VAR_MULTI_ENABLE, DEF_MULTI_ENABLE, &var_multi_enable,
0,
};
const char *cp;
* Distinct logging tag for multiple Postfix instances.
*/
#define VAR_SYSLOG_NAME "syslog_name"
+#if 1
+#define DEF_SYSLOG_NAME \
+ "${" VAR_MULTI_NAME ":postfix}${" VAR_MULTI_NAME "?$" VAR_MULTI_NAME "}"
+#else
#define DEF_SYSLOG_NAME "postfix"
+#endif
extern char *var_syslog_name;
/*
#define DEF_INET_WINDOW 0
extern int var_inet_windowsize;
+ /*
+ * Plug-in multi-instance support. Only the first two paramaters are used by
+ * Postfix itself; the other ones are reserved for the instance manager.
+ */
+#define VAR_MULTI_CONF_DIRS "multi_instance_directories"
+#define DEF_MULTI_CONF_DIRS ""
+extern char *var_multi_conf_dirs;
+
+#define VAR_MULTI_WRAPPER "multi_instance_wrapper"
+#define DEF_MULTI_WRAPPER ""
+extern char *var_multi_wrapper;
+
+#define VAR_MULTI_NAME "multi_instance_name"
+#define DEF_MULTI_NAME ""
+extern char *var_multi_name;
+
+#define VAR_MULTI_GROUP "multi_instance_group"
+#define DEF_MULTI_GROUP ""
+extern char *var_multi_group;
+
+#define VAR_MULTI_ENABLE "multi_instance_enable"
+#define DEF_MULTI_ENABLE 0
+extern bool var_multi_enable;
+
/* LICENSE
/* .ad
/* .fi
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20090114"
+#define MAIL_RELEASE_DATE "20090122"
#define MAIL_VERSION_NUMBER "2.6"
#ifdef SNAPSHOT
/* VSTRING *dst;
/* const char *delims;
/* const char *sender;
-/* const char *recipient;
+/* const RECIPIENT *recipient;
/*
/* const char *verp_delims_verify(delims)
/* const char *delims;
/* Global library. */
#include <mail_params.h>
+#include <recipient_list.h>
#include <verp_sender.h>
/* verp_sender - encode recipient into envelope sender address */
VSTRING *verp_sender(VSTRING *buf, const char *delimiters,
- const char *sender, const char *recipient)
+ const char *sender, const RECIPIENT *rcpt_info)
{
ssize_t send_local_len;
ssize_t rcpt_local_len;
+ const char *recipient;
const char *cp;
/*
* Change prefix@origin into prefix+user=domain@origin.
+ *
+ * Fix 20090115: Use the Postfix original recipient, because that is what
+ * the VERP consumer expects.
*/
send_local_len = ((cp = strrchr(sender, '@')) != 0 ?
cp - sender : strlen(sender));
+ recipient = (rcpt_info->orig_addr[0] ?
+ rcpt_info->orig_addr : rcpt_info->address);
rcpt_local_len = ((cp = strrchr(recipient, '@')) != 0 ?
cp - recipient : strlen(recipient));
vstring_strncpy(buf, sender, send_local_len);
*/
#include <vstring.h>
+ /*
+ * Global library.
+ */
+#include <recipient_list.h>
+
/*
* External interface.
*/
-extern VSTRING *verp_sender(VSTRING *, const char *, const char *, const char *);
+extern VSTRING *verp_sender(VSTRING *, const char *, const char *, const RECIPIENT *);
extern const char *verp_delims_verify(const char *);
/* LICENSE
* If variable envelope return path is requested, change prefix+@origin
* into prefix+user=domain@origin. Note that with VERP there is only one
* recipient per delivery.
- *
- * Fix 20090114: Use the Postfix original recipient, because that is what
- * the VERP consumer expects.
*/
if (message->verp_delims == 0) {
sender = message->sender;
} else {
sender_buf = vstring_alloc(100);
verp_sender(sender_buf, message->verp_delims,
- message->sender, list.info->orig_addr[0] ?
- list.info->orig_addr : list.info->address);
+ message->sender, list.info);
sender = vstring_str(sender_buf);
}
/* mail system: start or stop the \fBmaster\fR(8) daemon, do a health
/* check, and other maintenance.
/*
-/* The \fBpostfix\fR(1) command sets up a standardized environment and
-/* runs the \fBpostfix-script\fR shell script to do the actual work.
+/* By default, the \fBpostfix\fR(1) command sets up a standardized
+/* environment and runs the \fBpostfix-script\fR shell script
+/* to do the actual work.
+/*
+/* However, when support for multiple Postfix instances is
+/* configured, \fBpostfix\fR(1) executes the command specified
+/* with the \fBmulti_instance_wrapper\fR configuration parameter.
+/* This command will execute the \fIcommand\fR for each
+/* applicable Postfix instance.
/*
/* The following commands are implemented:
/* .IP \fBcheck\fR
/* the named directory instead of the default configuration directory.
/* Use this to distinguish between multiple Postfix instances on the
/* same host.
+/*
+/* With Postfix 2.6 and later, this option forces the postfix(1)
+/* command to operate on the specified Postfix instance only.
+/* This behavior is inherited by postfix(1) commands that run
+/* as a descendant of the current process.
/* .IP "\fB-D\fR (with \fBpostfix start\fR only)"
/* Run each Postfix daemon under control of a debugger as specified
/* via the \fBdebugger_command\fR configuration parameter.
/* variables before executing the \fBpostfix-script\fR file:
/* .IP \fBMAIL_CONFIG\fR
/* This is set when the -c command-line option is present.
+/*
+/* With Postfix 2.6 and later, this environment variable forces
+/* the postfix(1) command to operate on the specified Postfix
+/* instance only. This behavior is inherited by postfix(1)
+/* commands that run as a descendant of the current process.
/* .IP \fBMAIL_VERBOSE\fR
/* This is set when the -v command-line option is present.
/* .IP \fBMAIL_DEBUG\fR
/* The directory with Postfix-writable data files (for example:
/* caches, pseudo-random numbers).
/* .PP
+/* Available in Postfix version 2.6 and later:
+/* .IP "\fBmulti_instance_directories (empty)\fR"
+/* An optional list of non-default Postfix configuration directories;
+/* these directories belong to additional Postfix instances that share
+/* the Postfix executable files and documentation with the default
+/* Postfix instance, and that are started, stopped, etc., together
+/* with the default Postfix instance.
+/* .IP "\fBmulti_instance_wrapper (empty)\fR"
+/* The pathname of a multi-instance manager command that the
+/* \fBpostfix\fR(1) command invokes when the multi_instance_directories
+/* parameter value is non-empty.
+/* .IP "\fBmulti_instance_group (empty)\fR"
+/* The optional instance group name of this Postfix instance.
+/* .IP "\fBmulti_instance_name (empty)\fR"
+/* The optional instance name of this Postfix instance.
+/* .IP "\fBmulti_instance_enable (no)\fR"
+/* Allow this Postfix instance to be started, stopped, etc., by
+/* a multi-instance manager.
+/* .PP
/* Other configuration parameters:
/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
/* The default location of the Postfix main.cf and master.cf
/* postlock(1), Postfix-compatible locking
/* postlog(1), Postfix-compatible logging
/* postmap(1), Postfix lookup table manager
+/* postmulti(1), Postfix multi-instance manager
/* postqueue(1), Postfix mail queue control
/* postsuper(1), Postfix housekeeping
/* mailq(1), Sendmail compatibility interface
/* bounce(5), Postfix bounce message templates
/* master(5), Postfix master.cf file syntax
/* postconf(5), Postfix main.cf file syntax
+/* postfix-wrapper(5), Postfix multi-instance API
/*
/* Table-driven mechanisms:
/* access(5), Postfix SMTP access control table
VAR_HTML_DIR, DEF_HTML_DIR, &var_html_dir, 1, 0,
0,
};
+ int force_single_instance;
+ ARGV *my_argv;
/*
* Fingerprint executables and core dumps.
break;
}
}
+ force_single_instance = (getenv(CONF_ENV_PATH) != 0);
/*
* Copy a bunch of configuration parameters into the environment for easy
/*
* Run the management script.
*/
- script = concatenate(var_daemon_dir, "/postfix-script", (char *) 0);
- if (optind < 1)
- msg_panic("bad optind value");
- argv[optind - 1] = script;
- execvp(script, argv + optind - 1);
- msg_fatal("%s: %m", script);
+ if (force_single_instance || *var_multi_conf_dirs == 0) {
+ script = concatenate(var_daemon_dir, "/postfix-script", (char *) 0);
+ if (optind < 1)
+ msg_panic("bad optind value");
+ argv[optind - 1] = script;
+ execvp(script, argv + optind - 1);
+ msg_fatal("%s: %m", script);
+ }
+
+ /*
+ * Hand off control to a multi-instance manager.
+ */
+ else {
+ if (*var_multi_wrapper == 0)
+ msg_fatal("multi-instance support is requested, but %s is empty",
+ VAR_MULTI_WRAPPER);
+ my_argv = argv_split(var_multi_wrapper, " \t\r\n");
+ do {
+ argv_add(my_argv, argv[optind], (char *) 0);
+ } while (argv[optind++] != 0);
+ execvp(my_argv->argv[0], my_argv->argv);
+ msg_fatal("%s: %m", my_argv->argv[0]);
+ }
}
* If variable envelope return path is requested, change prefix+@origin
* into prefix+user=domain@origin. Note that with VERP there is only one
* recipient per delivery.
- *
- * Fix 20090114: Use the Postfix original recipient, because that is what
- * the VERP consumer expects.
*/
if (message->verp_delims == 0) {
sender = message->sender;
} else {
sender_buf = vstring_alloc(100);
verp_sender(sender_buf, message->verp_delims,
- message->sender, list.info->orig_addr[0] ?
- list.info->orig_addr : list.info->address);
+ message->sender, list.info);
sender = vstring_str(sender_buf);
}