-TCONFIG_INT_TABLE
-TCONFIG_LONG_FN_TABLE
-TCONFIG_LONG_TABLE
+-TCONFIG_NCODE_TABLE
+-TCONFIG_NINT_FN_TABLE
+-TCONFIG_NINT_TABLE
+-TCONFIG_RAW_FN_TABLE
+-TCONFIG_RAW_TABLE
-TCONFIG_STR_FN_TABLE
-TCONFIG_STR_TABLE
-TCONFIG_TIME_FN_TABLE
Documentation: more precise description of multi-instance
manager API, and minor edits of the example program. Files:
conf/postfix-wrapper, proto/postfix-wrapper.
+
+20090208
+
+ Cleanup: enable multi-instance shared-file logic only when
+ the instance is listed in multi_instance_directories. Files:
+ conf/post-install, conf/postfix-script.
+
+20090210
+
+ Feature: specify "reject_tempfail_action = defer" to
+ immediately defer a remote SMTP client request after a
+ reject-type restriction fails with a temporary error. Based
+ on code by Rob Foehl. File: smtpd/smtpd_check.c.
+
+ Feature: finer control of reject_tempfail_action with
+ unknown_address_tempfail_action, unverified_sender_tempfail_action
+ unverified_recipient_tempfail_action, and
+ unknown_helo_hostname_tempfail_action. See documentation
+ for details. File: smtpd/smtpd_check.c.
+
+20090211
+
+ Workaround: pass the SMTP server socket's local and remote
+ peer address information to the Dovecot authentication server.
+ This is incomplete code: it ignores XCLIENT server address
+ overrides. File: xsasl/xsasl_dovecot_server.c.
+
+20090212
+
+ Testing revealed that with mumble_tempfail_action=defer,
+ the "defer" action was ignored. Cause: the DEFER_IF_PERMIT[0-9]
+ macros lost the SMTPD_CHECK_REJECT result value. File:
+ smtpd/smtpd_check.c.
+
+ Feature: stress-dependent smtpd_timeout (normal: 300s,
+ overload: 10s), smtpd_hard_error_limit (normal: 20, overload:
+ 1) and smtpd_junk_command_limit (normal: 100, overload: 1).
update: $(LIBEXEC)
libexec/post-install: conf/post-install
- ln -f $? $@
+ # XXX Work around broken hardlink implementations
+ rm -f $@
+ cp $? $@
libexec/postfix-files: conf/postfix-files
- ln -f $? $@
+ # XXX Work around broken hardlink implementations
+ rm -f $@
+ cp $? $@
libexec/postfix-script: conf/postfix-script
- ln -f $? $@
+ # XXX Work around broken hardlink implementations
+ rm -f $@
+ cp $? $@
libexec/postfix-wrapper: conf/postfix-wrapper
- ln -f $? $@
+ # XXX Work around broken hardlink implementations
+ rm -f $@
+ cp $? $@
libexec/main.cf: conf/main.cf
- ln -f $? $@
+ # XXX Work around broken hardlink implementations
+ rm -f $@
+ cp $? $@
libexec/master.cf: conf/master.cf
- ln -f $? $@
+ # XXX Work around broken hardlink implementations
+ rm -f $@
+ cp $? $@
manpages:
set -e; for i in $(MANDIRS); do \
H\bHo\bow\bw a\bad\bdd\bdr\bre\bes\bss\bs v\bve\ber\bri\bif\bfi\bic\bca\bat\bti\bio\bon\bn w\bwo\bor\brk\bks\bs
-A sender or recipient address is verified by probing the nearest MTA for that
-address, without actually delivering mail. The nearest MTA could be Postfix
-itself, or it could be a remote MTA (SMTP interruptus). Probe messages are like
-normal mail, except that they are never delivered, deferred or bounced; probe
-messages are always discarded.
+A Postfix MTA verifies a sender or recipient address by probing the nearest MTA
+for that address, without actually delivering mail. The nearest MTA could be
+the Postfix MTA itself, or it could be a remote MTA (SMTP interruptus). Probe
+messages are like normal mail, except that they are never delivered, deferred
+or bounced; probe messages are always discarded.
Postfix Postfix Address
Internet -> SMTP <-> verify <-> verification
The unverified_recipient_reject_reason parameter (default: empty) specifies
fixed text that Postfix will send to remote SMTP clients, instead of sending
-actual address verification details.
+actual address verification details. Do not specify the SMTP status code or
+enhanced status code.
+
+The unverified_recipient_tempfail_action parameter (default: defer_if_permit)
+specifies the Postfix SMTP server action when a recipient address verification
+probe fails with some temporary error.
S\bSe\ben\bnd\bde\ber\br a\bad\bdd\bdr\bre\bes\bss\bs v\bve\ber\bri\bif\bfi\bic\bca\bat\bti\bio\bon\bn f\bfo\bor\br m\bma\bai\bil\bl f\bfr\bro\bom\bm f\bfr\bre\beq\bqu\bue\ben\bnt\btl\bly\by f\bfo\bor\brg\bge\bed\bd d\bdo\bom\bma\bai\bin\bns\bs
The unverified_sender_reject_reason parameter (default: empty) specifies fixed
text that Postfix will send to remote SMTP clients, instead of sending actual
-addres verification details.
+addres verification details. Do not specify the SMTP status code or enhanced
+status code.
+
+The unverified_sender_tempfail_action parameter (default: defer_if_permit)
+specifies the Postfix SMTP server action when a sender address verification
+probe fails with some temporary error.
A\bAd\bdd\bdr\bre\bes\bss\bs v\bve\ber\bri\bif\bfi\bic\bca\bat\bti\bio\bon\bn d\bda\bat\bta\bab\bba\bas\bse\be
% cd INSTALL_ROOT
% rm -f SOMEWHERE/outputfile
- % find . \! -type d -print | xargs tar cf SOMEWHERE/outputfile
+ % find . \! -type d -print | xargs tar rf SOMEWHERE/outputfile
% gzip SOMEWHERE/outputfile
This way you will not include any directories that might cause trouble upon
The mail_release_date configuration parameter (format: yyyymmdd)
specifies the release date of a stable release or snapshot release.
+Major changes with snapshot 20090212
+====================================
+
+Stress-depdent behavior by default. Under conditions of overload,
+smtpd_timeout is reduced from 300s to to 10s, smtpd_hard_error_limit
+is reduced from 20 to 1, and smtpd_junk_command_limit is reduced
+from 100 to 1. This will reduce the delays for most legitimate mail.
+
Major changes with snapshot 20090121
====================================
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"
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 $daemon_directory/postfix-files || {
echo $0: Error: $daemon_directory/postfix-files is not a file. 1>&2
exit 1
do
IFS="$BACKUP_IFS"
set_permission=
- # Skip comments. Skip shared files, if updating a non-default instance.
+ # Skip comments. Skip shared files, if updating a secondary instance.
case $path in
- [$]*) case "$def_config_directory" in
- "$config_directory") $debug keep non-shared or shared $path;;
+ [$]*) case "$update_shared_files" in
+ 1) $debug keep non-shared or shared $path;;
*) non_shared=
for name in $NON_SHARED
do
$FATAL cannot execute $command_directory/postconf!
exit 1
}
-test "$def_config_directory" = "$config_directory" &&
- check_shared_files=1
+
+# If this is a secondary instance, don't touch shared files.
+
+instances=`$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
# 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.
-#
-# 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.
+# manager. It simply applies commands such as "postfix start"
+# to all the applicable Postfix instances.
# MANAGING MULTIPLE INSTANCES
# .ad
# .fi
# POSTFIX-WRAPPER INITIALIZATION
# .ad
# .fi
-# To hook this program into Postfix, execute the following
-# command.
-#
-# Replace /etc/postfix with the default Postfix configuration
-# directory, and replace /usr/libexec/postfix with the daemon
-# directory pathname of the default Postfix instance.
+# 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"
# .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 as shown below.
-# The last command updates main.cf and creates any directories
-# that Postfix will need.
+# 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.
#
-# Replace /etc/postfix with the default Postfix configuration
-# directory, and replace /usr/libexec/postfix with the daemon
-# directory pathname of the default Postfix instance.
+# Each command below should be entered as one line.
#
-# Each 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
# # mkdir /etc/postfix-test
do
case "$1" in
start)
- test "`$POSTCONF -c $dir -h multi_instance_enable`" = yes ||
- set check;;
+ 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;;
<h2><a name="how">How address verification works</a></h2>
-<p> A sender or recipient address is verified by probing the nearest
+<p> A Postfix MTA verifies a sender or recipient address by probing
+the nearest
MTA for that address, without actually delivering mail. The nearest
-MTA could be Postfix itself, or it could be a remote MTA (SMTP
+MTA could be the Postfix MTA itself, or it could be a remote MTA
+(SMTP
interruptus). Probe messages are like normal mail, except that
they are never delivered, deferred or bounced; probe messages are
always discarded. </p>
<p> The <a href="postconf.5.html#unverified_recipient_reject_reason">unverified_recipient_reject_reason</a> parameter (default:
empty) specifies fixed text that Postfix will send to remote SMTP
-clients, instead of sending actual address verification details. </p>
+clients, instead of sending actual address verification details.
+Do not specify the SMTP status code or enhanced status code. </p>
+
+<p> The <a href="postconf.5.html#unverified_recipient_tempfail_action">unverified_recipient_tempfail_action</a> parameter (default:
+<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>) specifies the Postfix SMTP server action when a
+recipient address verification probe fails with some temporary
+error. </p>
<h2><a name="forged_sender">Sender address verification for mail from frequently forged domains</a></h2>
<p> The <a href="postconf.5.html#unverified_sender_reject_reason">unverified_sender_reject_reason</a> parameter (default:
empty) specifies fixed text that Postfix will send to remote SMTP
-clients, instead of sending actual addres verification details. </p>
+clients, instead of sending actual addres verification details.
+Do not specify the SMTP status code or enhanced status code. </p>
+
+<p> The <a href="postconf.5.html#unverified_sender_tempfail_action">unverified_sender_tempfail_action</a> parameter (default:
+<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>) specifies the Postfix SMTP server action when a
+sender address verification probe fails with some temporary error.
+</p>
<h2><a name="caching">Address verification database</a></h2>
<blockquote> <pre>
% cd INSTALL_ROOT
% rm -f SOMEWHERE/outputfile
-% find . \! -type d -print | xargs tar cf SOMEWHERE/outputfile
+% find . \! -type d -print | xargs tar rf SOMEWHERE/outputfile
% gzip SOMEWHERE/outputfile </pre> </blockquote>
<p>This way you will not include any directories that might cause
</p>
+</DD>
+
+<DT><b><a name="reject_tempfail_action">reject_tempfail_action</a>
+(default: <a href="postconf.5.html#defer_if_permit">defer_if_permit</a>)</b></DT><DD>
+
+<p> The Postfix SMTP server's action when a reject-type restriction
+fails due to a temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted. </p>
+
+<p> For finer control, see: <a href="postconf.5.html#unverified_recipient_tempfail_action">unverified_recipient_tempfail_action</a>,
+<a href="postconf.5.html#unverified_sender_tempfail_action">unverified_sender_tempfail_action</a>, <a href="postconf.5.html#unknown_address_tempfail_action">unknown_address_tempfail_action</a>,
+and <a href="postconf.5.html#unknown_helo_hostname_tempfail_action">unknown_helo_hostname_tempfail_action</a>. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+
</DD>
<DT><b><a name="relay_clientcerts">relay_clientcerts</a>
<dd>Reject the request. This restriction is useful at the end of
a restriction list, to make the default policy explicit. The
-<a href="postconf.5.html#reject_code">reject_code</a> configuration parameter specifies the response code to
+<a href="postconf.5.html#reject_code">reject_code</a> configuration parameter specifies the response code for
rejected requests (default: 554).</dd>
<dt><b><a name="sleep">sleep <i>seconds</i></a></b></dt>
</DD>
<DT><b><a name="smtpd_hard_error_limit">smtpd_hard_error_limit</a>
-(default: 20)</b></DT><DD>
+(default: normal: 20, stress: 1)</b></DT><DD>
<p>
The maximal number of errors a remote SMTP client is allowed to
make without delivering mail. The Postfix SMTP server disconnects
-when the limit is exceeded.
+when the limit is exceeded. Normally the default limit is 20, but
+it changes under overload to just 1 with Postfix 2.6 and later.
</p>
<dd>Reject the request when the HELO or EHLO hostname syntax is
invalid. <br> The <a href="postconf.5.html#invalid_hostname_reject_code">invalid_hostname_reject_code</a> specifies the response
-code to rejected requests (default: 501).</dd>
+code for rejected requests (default: 501).</dd>
<dt><b><a name="reject_non_fqdn_helo_hostname">reject_non_fqdn_helo_hostname</a></b> (with Postfix < 2.3: reject_non_fqdn_hostname)</dt>
<dd>Reject the request when the HELO or EHLO hostname is not in
fully-qualified domain form, as required by the RFC. <br> The
-<a href="postconf.5.html#non_fqdn_reject_code">non_fqdn_reject_code</a> parameter specifies the response code to
+<a href="postconf.5.html#non_fqdn_reject_code">non_fqdn_reject_code</a> parameter specifies the response code for
rejected requests (default: 504).</dd>
<dt><b><a name="reject_rhsbl_helo">reject_rhsbl_helo <i>rbl_domain=d.d.d.d</i></a></b></dt>
<dt><b><a name="reject_unknown_helo_hostname">reject_unknown_helo_hostname</a></b> (with Postfix < 2.3: reject_unknown_hostname)</dt>
<dd>Reject the request when the HELO or EHLO hostname has no DNS A
-or MX record. <br> The <a href="postconf.5.html#unknown_hostname_reject_code">unknown_hostname_reject_code</a> specifies the
-response code to rejected requests (default: 450). </dd>
+or MX record. <br> The <a href="postconf.5.html#unknown_hostname_reject_code">unknown_hostname_reject_code</a> parameter
+specifies the numerical response code for rejected requests (default:
+450). <br> The <a href="postconf.5.html#unknown_helo_hostname_tempfail_action">unknown_helo_hostname_tempfail_action</a> parameter
+specifies the action after a temporary DNS error (default:
+<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>). </dd>
</dl>
</DD>
<DT><b><a name="smtpd_junk_command_limit">smtpd_junk_command_limit</a>
-(default: 100)</b></DT><DD>
+(default: normal: 100, stress: 1)</b></DT><DD>
<p>
The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote
increment the error counter with each junk command. The junk
command count is reset after mail is delivered. See also the
<a href="postconf.5.html#smtpd_error_sleep_time">smtpd_error_sleep_time</a> and <a href="postconf.5.html#smtpd_soft_error_limit">smtpd_soft_error_limit</a> configuration
-parameters.
+parameters. Normally the default limit is 100, but it changes under
+overload to just 1 with Postfix 2.6 and later.
</p>
<dd>Reject the request when the RCPT TO address is not in
fully-qualified domain form, as required by the RFC. <br> The
-<a href="postconf.5.html#non_fqdn_reject_code">non_fqdn_reject_code</a> parameter specifies the response code to
+<a href="postconf.5.html#non_fqdn_reject_code">non_fqdn_reject_code</a> parameter specifies the response code for
rejected requests (default: 504). </dd>
<dt><b><a name="reject_rhsbl_recipient">reject_rhsbl_recipient <i>rbl_domain=d.d.d.d</i></a></b></dt>
the recipient domain, and the RCPT TO domain has no DNS A or MX
record, or when it has a malformed MX record such as a record with
a zero-length MX hostname (Postfix version 2.3 and later). <br> The
-<a href="postconf.5.html#unknown_address_reject_code">unknown_address_reject_code</a> parameter specifies the response code
-for rejected requests (default: 450). The response is always 450
-in case of a temporary DNS error.</dd>
+<a href="postconf.5.html#unknown_address_reject_code">unknown_address_reject_code</a> parameter specifies the numerical
+response code for rejected requests (default: 450). The response
+is always 450 in case of a temporary DNS error. <br> The
+<a href="postconf.5.html#unknown_address_tempfail_action">unknown_address_tempfail_action</a> parameter specifies the action
+after a temporary DNS error (default: <a href="postconf.5.html#defer_if_permit">defer_if_permit</a>). </dd>
<dt><b><a name="reject_unlisted_recipient">reject_unlisted_recipient</a></b> (with Postfix version 2.0: check_recipient_maps)</dt>
to bounce, or when the recipient address destination is not reachable.
Address verification information is managed by the <a href="verify.8.html">verify(8)</a> server;
see the <a href="ADDRESS_VERIFICATION_README.html">ADDRESS_VERIFICATION_README</a> file for details. <br> The
-<a href="postconf.5.html#unverified_recipient_reject_code">unverified_recipient_reject_code</a> parameter specifies the response
-when an address is known to bounce (default: 450, change into 550
-when you are confident that it is safe to do so). The
-<a href="postconf.5.html#unverified_recipient_defer_code">unverified_recipient_defer_code</a> parameter specifies the response
-when an address probe failed due to a temporary problem (default:
-450). This feature is available in Postfix 2.1 and later. </dd>
+<a href="postconf.5.html#unverified_recipient_reject_code">unverified_recipient_reject_code</a> parameter specifies the numerical
+response code when an address is known to bounce (default: 450,
+change into 550 when you are confident that it is safe to do so).
+<br>The <a href="postconf.5.html#unverified_recipient_defer_code">unverified_recipient_defer_code</a> parameter specifies the
+numerical response code when an address probe failed due to a
+temporary problem (default: 450). <br> The
+<a href="postconf.5.html#unverified_recipient_tempfail_action">unverified_recipient_tempfail_action</a> parameter specifies the action
+after addres probe failure due to a temporary problem (default:
+<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>). <br> This feature is available in Postfix 2.1
+and later. </dd>
</dl>
<dd>Reject the request when the MAIL FROM address is not in
fully-qualified domain form, as required by the RFC. <br> The
-<a href="postconf.5.html#non_fqdn_reject_code">non_fqdn_reject_code</a> parameter specifies the response code to
+<a href="postconf.5.html#non_fqdn_reject_code">non_fqdn_reject_code</a> parameter specifies the response code for
rejected requests (default: 504). </dd>
<dt><b><a name="reject_rhsbl_sender">reject_rhsbl_sender <i>rbl_domain=d.d.d.d</i></a></b></dt>
the sender address, and the MAIL FROM address has no DNS A or MX
record, or when it has a malformed MX record such as a record with
a zero-length MX hostname (Postfix version 2.3 and later). <br> The
-<a href="postconf.5.html#unknown_address_reject_code">unknown_address_reject_code</a> parameter specifies the response code
-for rejected requests (default: 450). The response is always 450
-in case of a temporary DNS error. </dd>
+<a href="postconf.5.html#unknown_address_reject_code">unknown_address_reject_code</a> parameter specifies the numerical
+response code for rejected requests (default: 450). The response
+is always 450 in case of a temporary DNS error. <br> The
+<a href="postconf.5.html#unknown_address_tempfail_action">unknown_address_tempfail_action</a> parameter specifies the action
+after a temporary DNS error (default: <a href="postconf.5.html#defer_if_permit">defer_if_permit</a>). </dd>
<dt><b><a name="reject_unlisted_sender">reject_unlisted_sender</a></b></dt>
bounce, or when the sender address destination is not reachable.
Address verification information is managed by the <a href="verify.8.html">verify(8)</a> server;
see the <a href="ADDRESS_VERIFICATION_README.html">ADDRESS_VERIFICATION_README</a> file for details. <br> The
-<a href="postconf.5.html#unverified_sender_reject_code">unverified_sender_reject_code</a> parameter specifies the response when
-an address is known to bounce (default: 450, change into 550 when
-you are confident that it is safe to do so). The
-<a href="postconf.5.html#unverified_sender_defer_code">unverified_sender_defer_code</a> specifies the response when an address
-address probe failed due to a temporary problem (default: 450).
-This feature is available in Postfix 2.1 and later. </dd>
+<a href="postconf.5.html#unverified_sender_reject_code">unverified_sender_reject_code</a> parameter specifies the numerical
+response code when an address is known to bounce (default: 450,
+change into 550 when you are confident that it is safe to do so).
+<br>The <a href="postconf.5.html#unverified_sender_defer_code">unverified_sender_defer_code</a> specifies the numerical response
+code when an address address probe failed due to a temporary problem
+(default: 450). <br> The <a href="postconf.5.html#unverified_sender_tempfail_action">unverified_sender_tempfail_action</a> parameter
+specifies the action after address probe failure due to a temporary
+problem (default: <a href="postconf.5.html#defer_if_permit">defer_if_permit</a>). <br> This feature is available
+in Postfix 2.1 and later. </dd>
</dl>
</DD>
<DT><b><a name="smtpd_timeout">smtpd_timeout</a>
-(default: 300s)</b></DT><DD>
+(default: normal: 300s, stress: 10s)</b></DT><DD>
<p>
The time limit for sending a Postfix SMTP server response and for
-receiving a remote SMTP client request.
+receiving a remote SMTP client request. Normally the default limit
+is 300s, but it changes under overload to just 10s with Postfix 2.6
+and later.
</p>
<p>
</p>
+</DD>
+
+<DT><b><a name="unknown_address_tempfail_action">unknown_address_tempfail_action</a>
+(default: $<a href="postconf.5.html#reject_tempfail_action">reject_tempfail_action</a>)</b></DT><DD>
+
+<p> The Postfix SMTP server's action when <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a>
+or <a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a> fail due to a temporary error
+condition. Specify "defer" to defer the remote SMTP client request
+immediately. With the default "<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>" action, the Postfix
+SMTP server continues to look for opportunities to reject mail, and
+defers the client request only if it would otherwise be accepted.
+</p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+
</DD>
<DT><b><a name="unknown_client_reject_code">unknown_client_reject_code</a>
</p>
+</DD>
+
+<DT><b><a name="unknown_helo_hostname_tempfail_action">unknown_helo_hostname_tempfail_action</a>
+(default: $<a href="postconf.5.html#reject_tempfail_action">reject_tempfail_action</a>)</b></DT><DD>
+
+<p> The Postfix SMTP server's action when <a href="postconf.5.html#reject_unknown_helo_hostname">reject_unknown_helo_hostname</a>
+fails due to an temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+
</DD>
<DT><b><a name="unknown_hostname_reject_code">unknown_hostname_reject_code</a>
<DT><b><a name="unverified_recipient_reject_reason">unverified_recipient_reject_reason</a>
(default: empty)</b></DT><DD>
-<p> When rejecting mail with <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a>, reply
-with this text as the reason, instead of actual address verification
-details.
+<p> The Postfix SMTP server's reply when rejecting mail with
+<a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a>. Do not include the numeric SMTP reply
+code or the enhanced status code. By default, the response includes
+actual address verification details.
+
+<p> Example: </p>
+
+<pre>
+<a href="postconf.5.html#unverified_recipient_reject_reason">unverified_recipient_reject_reason</a> = Recipient address lookup failed
+</pre>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="unverified_recipient_tempfail_action">unverified_recipient_tempfail_action</a>
+(default: $<a href="postconf.5.html#reject_tempfail_action">reject_tempfail_action</a>)</b></DT><DD>
+
+<p> The Postfix SMTP server's action when <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a>
+fails due to a temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted. </p>
<p> This feature is available in Postfix 2.6 and later. </p>
<DT><b><a name="unverified_sender_reject_reason">unverified_sender_reject_reason</a>
(default: empty)</b></DT><DD>
-<p> When rejecting mail with <a href="postconf.5.html#reject_unverified_sender">reject_unverified_sender</a>, reply with
-this text as the reason, instead of actual address verification
-details.
+<p> The Postfix SMTP server's reply when rejecting mail with
+<a href="postconf.5.html#reject_unverified_sender">reject_unverified_sender</a>. Do not include the numeric SMTP reply
+code or the enhanced status code. By default, the response includes
+actual address verification details.
+
+<p> Example: </p>
+
+<pre>
+<a href="postconf.5.html#unverified_sender_reject_reason">unverified_sender_reject_reason</a> = Sender address lookup failed
+</pre>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="unverified_sender_tempfail_action">unverified_sender_tempfail_action</a>
+(default: $<a href="postconf.5.html#reject_tempfail_action">reject_tempfail_action</a>)</b></DT><DD>
+
+<p> The Postfix SMTP server's action when <a href="postconf.5.html#reject_unverified_sender">reject_unverified_sender</a>
+fails due to a temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted. </p>
<p> This feature is available in Postfix 2.6 and later. </p>
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. A trivial but useful implementa-
- tion, with instructions, can be found in $<a href="postconf.5.html#daemon_directory">daemon_direc</a>-
- <a href="postconf.5.html#daemon_directory">tory</a>/postfix-wrapper.
-
- 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.
+ Postfix versions 2.6 and later provide support for multi-
+ ple Postfix instances. Instances share executable files
+ and documentation, but have their own directories for con-
+ figuration, queue and data files.
+
+ This document describes how the familiar "postfix start"
+ etc. user interface can be used to manage one or multiple
+ Postfix instances, and gives details of an API that allows
+ the <a href="postfix.1.html">postfix(1)</a> command to coordinate activities with a
+ multi-instance manager program.
+
+ A trivial but useful multi-instance manager implementation
+ is described below, and can be found in the file $<a href="postconf.5.html#daemon_directory">dae</a>-
+ <a href="postconf.5.html#daemon_directory">mon_directory</a>/postfix-wrapper. The latter file also con-
+ tains instructions for setting up multiple instances.
+
+ With multi-instance support, the default Postfix instance
+ is required. The location of its configuration files is
+ specified by the built-in default value for the con-
+ fig_directory parameter.
<b>GENERAL OPERATION</b>
- First of all, nothing changes when there is only one Post-
- fix instance.
+ Multi-instance support is backwards compatible: when there
+ is only one Postfix instance, commands such as "postfix
+ start" keep doing what they have always done.
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.
+ the mechanisms discussed later, sites can continue to use
+ the familiar postfix commands in boot scripts, upgrade
+ procedures, and other places.
- To start, stop, update, etc., multiple Postfix instances,
- use:
+ To start all applicable Postfix instances, use:
- # postfix <i>command</i>
+ # postfix start
- For example, to find out what Postfix instances are con-
- figured:
+ Other <a href="postfix.1.html">postfix(1)</a> commands also work as expected. For exam-
+ ple, to find out what Postfix instances exist in a multi-
+ instance configuration, use:
# postfix status
+ This enumerates the status of all Postfix instances within
+ a multi-instance configuration.
+
<b>MANAGING AN INDIVIDUAL POSTFIX INSTANCE</b>
- To manage an individual Postfix instance, use:
+ To operate on a specific Postfix instance, specify its
+ configuration directory on the <a href="postfix.1.html">postfix(1)</a> command line:
# postfix -c <i>/path/to/config</i><b>_</b><i>directory command</i>
- 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. The same
- happens when MAIL_CONFIG is specified in the process envi-
- ronment.
-
- Otherwise, the <a href="postfix.1.html">postfix(1)</a> command will operate on all
- applicable Postfix instances.
-
-<b>MULTI-INSTANCE MANAGER EXAMPLE</b>
- When the <a href="postfix.1.html">postfix(1)</a> command is invoked without -c option
- or MAIL_CONFIG environment setting, and non-default Post-
- fix instance directories are defined in <a href="postconf.5.html">main.cf</a> with the
- <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> parameter, <a href="postfix.1.html">postfix(1)</a> invokes
- the command specified in <a href="postconf.5.html">main.cf</a> with the
- <a href="postconf.5.html#multi_instance_wrapper">multi_instance_wrapper</a> parameter, instead of invoking
- postfix-script.
+ Alternatively, the <a href="postfix.1.html">postfix(1)</a> command accepts the
+ instance's configuration directory via the MAIL_CONFIG
+ environment variable (the -c command-line option has
+ higher precedence).
+
+ When no Postfix instance information is specified, the
+ <a href="postfix.1.html">postfix(1)</a> command will operate on all applicable Postfix
+ instances.
+
+<b>MULTI-INSTANCE MANAGER IMPLEMENTATION</b>
+ Historically, the <a href="postfix.1.html">postfix(1)</a> command invokes the postfix-
+ script file (currently installed in the daemon directory).
+ This file contains the commands that start or stop Post-
+ fix, upgrade the configuration and so on.
+
+ When multi-instance support is turned on, the <a href="postfix.1.html">postfix(1)</a>
+ command needs to execute these commands for each applica-
+ ble Postfix instance. This multiplication of commands is
+ handled by a multi-instance manager program.
+
+ Turning on multi-instance support goes as follows: update
+ the default Postfix instance's <a href="postconf.5.html">main.cf</a> file, and populate
+ the <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> parameter with the configu-
+ ration directory pathnames of additional Postfix
+ instances.
+
+ With multi-instance support turned on, the <a href="postfix.1.html">postfix(1)</a> com-
+ mand invokes a multi-instance manager command instead of
+ the postfix-script file. The multi-instance manager exe-
+ cutes the <a href="postfix.1.html">postfix(1)</a> command for each applicable Postfix
+ instance. The pathname of the multi-instance manager is
+ specified in the default <a href="postconf.5.html">main.cf</a> file with the
+ <a href="postconf.5.html#multi_instance_wrapper">multi_instance_wrapper</a> parameter.
The <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> and other <a href="postconf.5.html">main.cf</a> parame-
ters are listed below in the CONFIGURATION PARAMETERS sec-
tion.
- A useful wrapper implementation can be as simple as:
+ A useful multi-instance manager implementation can be as
+ simple as:
#!/bin/sh
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;;
+ = yes || continue;;
start)
test "`$POSTCONF -c $dir -h <a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a>`" \
- = yes || set check;;
+ = yes || {
+ $POSTFIX -c $dir check || err=$?
+ continue
+ };;
esac
$POSTFIX -c $dir "$@" || err=$?
done
exit $err
+ A sample implementation, with instructions, can be found
+ in $<a href="postconf.5.html#daemon_directory">daemon_directory</a>/postfix-wrapper.
+
The postmulti(1) command implements a more sophisticated
approach, based on a combination of C code and scripting.
-<b>ENABLING AN INSTANCE FOR MULTI-INSTANCE OPERATION</b>
- To enable start/stop/etc. by a multi-instance manager, set
- the Postfix instance's <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a>
- parameter to "yes". This parameter has no effect on sin-
- gle-instance operation with "postfix -c" or with a
- MAIL_CONFIG environment setting.
-
- The multi-instance manager program will skip commands such
- as "stop" and "flush" when a Postfix instance is disabled,
- and will replace "start" by "check" so that problems will
- still be reported even when the default instance is dis-
- abled.
+<b>ENABLING A SPECIFIC INSTANCE FOR MULTI-INSTANCE OPERATION</b>
+ Each Postfix instance has its own <a href="postconf.5.html">main.cf</a> file with param-
+ eters that control multi-instance operation. The most
+ important settings are discussed here.
+
+ The setting "<a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a> = yes" allows the
+ multi-instance manager to start (and stop) the correspond-
+ ing Postfix instance. For safety reasons, this setting is
+ not the default.
+
+ The setting "<a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a> = no" is useful for
+ manual testing. With this, the multi-instance manager
+ will not start the Postfix instance, and it will skip com-
+ mands such as "stop" or "flush" that require a running
+ Postfix instance. The multi-instance manager will execute
+ commands such as "check", "set-permissions" or "upgrade-
+ configuration", and it will replace "start" by "check" so
+ that problems will be reported even when the instance is
+ disabled.
<b>SHARED VERSUS NON-SHARED FILES</b>
- Some files are shared between Postfix instances, such as
+ 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.
+ such as the queue directory. See the NON-SHARED FILES
+ section below for a list of per-instance files.
Before Postfix multi-instance support was implemented, the
- executables, manpages, etc., have always 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.
+ executables, manpages, etc., have always been checked or
+ updated as part of the default Postfix instance. With
+ multi-instance support, we simply continue to do this.
+
+ Specifically, Postfix instances will not check or update
+ shared files when their <a href="postconf.5.html#config_directory">config_directory</a> value is listed
+ with the default <a href="postconf.5.html">main.cf</a>'s <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a>
+ parameter.
The consequence of this approach is that the default Post-
- fix instance should be updated before any other instances.
+ fix instance should be checked and updated before any
+ other instances.
<b>MULTI-INSTANCE API SUMMARY</b>
Only the multi-instance manager implements support for the
<a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a> configuration parameter. The multi-
- instance manager will not start Postfix instances without
- "<a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a> = yes". This allows a Postfix
- instance to be tested by hand before it is placed under
- control of a multi-instance manager.
-
- 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, when the <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> parameter
- value is non-empty, the <a href="postfix.1.html">postfix(1)</a> command executes the
- command specified with the <a href="postconf.5.html#multi_instance_wrapper">multi_instance_wrapper</a> parame-
- ter, instead of executing the commands in postfix-script.
-
- The multi-instance manager skips commands such as "stop"
- or "reload" that require a running Postfix instance, when
- an instance does not have "<a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a> = yes".
+ instance manager will start only Postfix instances whose
+ <a href="postconf.5.html">main.cf</a> file has "<a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a> = yes". A setting
+ of "no" allows a Postfix instance to be tested by hand.
+
+ The <a href="postfix.1.html">postfix(1)</a> command operates on only one Postfix
+ instance when the -c option is specified, or when
+ MAIL_CONFIG is present in the process environment. This is
+ necessary to terminate recursion.
+
+ Otherwise, when the <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> parameter
+ value is non-empty, the <a href="postfix.1.html">postfix(1)</a> command executes the
+ command specified with the <a href="postconf.5.html#multi_instance_wrapper">multi_instance_wrapper</a> parame-
+ ter, instead of executing the commands in postfix-script.
+
+ The multi-instance manager skips commands such as "stop"
+ or "reload" that require a running Postfix instance, when
+ an instance does not have "<a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a> = yes".
This avoids false error messages.
- The multi-instance manager replaces 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 even when the default
+ The multi-instance manager replaces a "start" command by
+ "check" when a Postfix instance's <a href="postconf.5.html">main.cf</a> file does not
+ have "<a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a> = yes". This substitution
+ ensures that problems will be reported even when the
instance is disabled.
- No Postfix command or script will update or check shared
- files unless it is running in the context of the default
- Postfix instance. Therefore, the default instance should
- be updated before any other Postfix instances.
-
- 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 commands use this information to
- determine whether a -c option or MAIL_CONFIG environment
+ No Postfix command or script will update or check shared
+ files when its <a href="postconf.5.html#config_directory">config_directory</a> value is listed in the
+ default <a href="postconf.5.html">main.cf</a>'s <a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> parameter
+ value. Therefore, the default instance should be checked
+ and updated before any Postfix instances that depend on
+ it.
+
+ 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 commands use this information to
+ determine whether a -c option or MAIL_CONFIG environment
setting specifies a legitimate 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-
+ 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.
<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 <a href="postfix.1.html">post-</a>
- <a href="postfix.1.html">fix(1)</a> -c option, so that <a href="postfix.1.html">postfix(1)</a> commands in
+ operate only on the specified Postfix instance.
+ This environment variable is exported by the <a href="postfix.1.html">post-</a>
+ <a href="postfix.1.html">fix(1)</a> -c option, so that <a href="postfix.1.html">postfix(1)</a> commands in
descendant processes will work correctly.
<b>CONFIGURATION PARAMETERS</b>
- The text below provides only a parameter summary. See
+ The text below provides only a parameter summary. See
<a href="postconf.5.html">postconf(5)</a> for more details.
<b><a href="postconf.5.html#multi_instance_directories">multi_instance_directories</a> (empty)</b>
- An optional list of non-default Postfix configura-
+ An optional list of non-default Postfix configura-
tion directories; these directories belong to addi-
- tional Postfix instances that share the Postfix
+ tional Postfix instances that share the Postfix
executable files and documentation with the default
- Postfix instance, and that are started, stopped,
+ 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-
+ 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
+ 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
+ The optional instance group name of this Postfix
instance.
<b><a href="postconf.5.html#multi_instance_enable">multi_instance_enable</a> (no)</b>
<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
+ 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>
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-
+ 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
- $<a href="postconf.5.html#daemon_directory">daemon_directory</a>/postfix-wrapper simple multi-instance manager
postmulti(1) full-blown multi-instance manager
+ $<a href="postconf.5.html#daemon_directory">daemon_directory</a>/postfix-wrapper simple multi-instance manager
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
Milter (mail filter) application, and for receiving
the response.
- <b><a href="postconf.5.html#milter_connect_macros">milter_connect_macros</a> (see postconf -n output)</b>
+ <b><a href="postconf.5.html#milter_connect_macros">milter_connect_macros</a> (see 'postconf -d' output)</b>
The macros that are sent to Milter (mail filter)
applications after completion of an SMTP connec-
tion.
- <b><a href="postconf.5.html#milter_helo_macros">milter_helo_macros</a> (see postconf -n output)</b>
+ <b><a href="postconf.5.html#milter_helo_macros">milter_helo_macros</a> (see 'postconf -d' output)</b>
The macros that are sent to Milter (mail filter)
applications after the SMTP HELO or EHLO command.
- <b><a href="postconf.5.html#milter_mail_macros">milter_mail_macros</a> (see postconf -n output)</b>
+ <b><a href="postconf.5.html#milter_mail_macros">milter_mail_macros</a> (see 'postconf -d' output)</b>
The macros that are sent to Milter (mail filter)
applications after the SMTP MAIL FROM command.
- <b><a href="postconf.5.html#milter_rcpt_macros">milter_rcpt_macros</a> (see postconf -n output)</b>
+ <b><a href="postconf.5.html#milter_rcpt_macros">milter_rcpt_macros</a> (see 'postconf -d' output)</b>
The macros that are sent to Milter (mail filter)
applications after the SMTP RCPT TO command.
- <b><a href="postconf.5.html#milter_data_macros">milter_data_macros</a> (see postconf -n output)</b>
+ <b><a href="postconf.5.html#milter_data_macros">milter_data_macros</a> (see 'postconf -d' output)</b>
The macros that are sent to version 4 or higher
Milter (mail filter) applications after the SMTP
DATA command.
- <b><a href="postconf.5.html#milter_unknown_command_macros">milter_unknown_command_macros</a> (see postconf -n output)</b>
+ <b><a href="postconf.5.html#milter_unknown_command_macros">milter_unknown_command_macros</a> (see 'postconf -d' output)</b>
The macros that are sent to version 3 or higher
Milter (mail filter) applications after an unknown
SMTP command.
- <b><a href="postconf.5.html#milter_end_of_header_macros">milter_end_of_header_macros</a> (see postconf -n output)</b>
+ <b><a href="postconf.5.html#milter_end_of_header_macros">milter_end_of_header_macros</a> (see 'postconf -d' output)</b>
The macros that are sent to Milter (mail filter)
applications after the end of the message header.
- <b><a href="postconf.5.html#milter_end_of_data_macros">milter_end_of_data_macros</a> (see postconf -n output)</b>
+ <b><a href="postconf.5.html#milter_end_of_data_macros">milter_end_of_data_macros</a> (see 'postconf -d' output)</b>
The macros that are sent to Milter (mail filter)
applications after the message end-of-data.
The maximal number of recipients that the Postfix
SMTP server accepts per message delivery request.
- <b><a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a> (300s)</b>
+ <b><a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a> (normal: 300s, stress: 10s)</b>
The time limit for sending a Postfix SMTP server
response and for receiving a remote SMTP client
request.
allowed to make without delivering mail before the
Postfix SMTP server slows down all its responses.
- <b><a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a> (20)</b>
+ <b><a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a> (normal: 20, stress: 1)</b>
The maximal number of errors a remote SMTP client
is allowed to make without delivering mail.
- <b><a href="postconf.5.html#smtpd_junk_command_limit">smtpd_junk_command_limit</a> (100)</b>
+ <b><a href="postconf.5.html#smtpd_junk_command_limit">smtpd_junk_command_limit</a> (normal: 100, stress: 1)</b>
The number of junk commands (NOOP, VRFY, ETRN or
RSET) that a remote SMTP client can send before the
Postfix SMTP server starts to increment the error
Postfix version 2.1 introduces sender and recipient
address verification. This feature is implemented by
sending probe email messages that are not actually deliv-
- ered. This feature is requested via the <a href="postconf.5.html#reject_unverified_sender">reject_unveri</a>-
- <a href="postconf.5.html#reject_unverified_sender">fied_sender</a> and <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a> access
+ ered. This feature is requested via the reject_unveri-
+ fied_sender and <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a> access
restrictions. The status of verification probes is main-
tained by the <a href="verify.8.html"><b>verify</b>(8)</a> server. See the file <a href="ADDRESS_VERIFICATION_README.html">ADDRESS_VER</a>-
<a href="ADDRESS_VERIFICATION_README.html">IFICATION_README</a> for information about how to configure
<b><a href="postconf.5.html#unverified_recipient_reject_code">unverified_recipient_reject_code</a> (450)</b>
The numerical Postfix SMTP server response when a
- recipient address is rejected by the <a href="postconf.5.html#reject_unverified_recipient">reject_unveri</a>-
- <a href="postconf.5.html#reject_unverified_recipient">fied_recipient</a> restriction.
+ recipient address is rejected by the reject_unveri-
+ fied_recipient restriction.
Available in Postfix version 2.6 and later:
error condition.
<b><a href="postconf.5.html#unverified_sender_reject_reason">unverified_sender_reject_reason</a> (empty)</b>
- When rejecting mail with <a href="postconf.5.html#reject_unverified_sender">reject_unverified_sender</a>,
- reply with this text as the reason, instead of
- actual address verification details.
+ The Postfix SMTP server's reply when rejecting mail
+ with <a href="postconf.5.html#reject_unverified_sender">reject_unverified_sender</a>.
<b><a href="postconf.5.html#unverified_recipient_reject_reason">unverified_recipient_reject_reason</a> (empty)</b>
- When rejecting mail with reject_unverified_recipi-
- ent, reply with this text as the reason, instead of
- actual address verification details.
+ The Postfix SMTP server's reply when rejecting mail
+ with <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a>.
+
+ <b><a href="postconf.5.html#unverified_sender_tempfail_action">unverified_sender_tempfail_action</a> ($<a href="postconf.5.html#reject_tempfail_action">reject_temp</a>-</b>
+ <b><a href="postconf.5.html#reject_tempfail_action">fail_action</a>)</b>
+ The Postfix SMTP server's action when <a href="postconf.5.html#reject_unverified_sender">reject_unver</a>-
+ <a href="postconf.5.html#reject_unverified_sender">ified_sender</a> fails due to a temporary error condi-
+ tion.
+
+ <b><a href="postconf.5.html#unverified_recipient_tempfail_action">unverified_recipient_tempfail_action</a> ($<a href="postconf.5.html#reject_tempfail_action">reject_temp</a>-</b>
+ <b><a href="postconf.5.html#reject_tempfail_action">fail_action</a>)</b>
+ The Postfix SMTP server's action when <a href="postconf.5.html#reject_unverified_recipient">reject_unver</a>-
+ <a href="postconf.5.html#reject_unverified_recipient">ified_recipient</a> fails due to a temporary error con-
+ dition.
<b>ACCESS CONTROL RESPONSES</b>
The following parameters control numerical SMTP reply
an <a href="access.5.html"><b>access</b>(5)</a> map "defer" action, including
"<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>" or "<a href="postconf.5.html#defer_if_reject">defer_if_reject</a>".
+ <b><a href="postconf.5.html#reject_tempfail_action">reject_tempfail_action</a> (<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>)</b>
+ The Postfix SMTP server's action when a reject-type
+ restriction fails due to a temporary error condi-
+ tion.
+
+ <b><a href="postconf.5.html#unknown_helo_hostname_tempfail_action">unknown_helo_hostname_tempfail_action</a> ($<a href="postconf.5.html#reject_tempfail_action">reject_temp</a>-</b>
+ <b><a href="postconf.5.html#reject_tempfail_action">fail_action</a>)</b>
+ The Postfix SMTP server's action when
+ <a href="postconf.5.html#reject_unknown_helo_hostname">reject_unknown_helo_hostname</a> fails due to an tempo-
+ rary error condition.
+
+ <b><a href="postconf.5.html#unknown_address_tempfail_action">unknown_address_tempfail_action</a> ($<a href="postconf.5.html#reject_tempfail_action">reject_tempfail_action</a>)</b>
+ The Postfix SMTP server's action when
+ <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a> or
+ <a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a> fail due to a tem-
+ porary error condition.
+
<b>MISCELLANEOUS CONTROLS</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
+ 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#daemon_timeout">daemon_timeout</a> (18000s)</b>
- How much time a Postfix daemon process may take to
- handle a request before it is terminated by a
+ How much time a Postfix daemon process may take to
+ handle a request before it is terminated by a
built-in watchdog timer.
<b><a href="postconf.5.html#command_directory">command_directory</a> (see 'postconf -d' output)</b>
- The location of all postfix administrative com-
+ The location of all postfix administrative com-
mands.
<b><a href="postconf.5.html#double_bounce_sender">double_bounce_sender</a> (double-bounce)</b>
and most Postfix daemon processes.
<b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
- The maximum amount of time that an idle Postfix
- daemon process waits for an incoming connection
+ The maximum amount of time that an idle Postfix
+ daemon process waits for an incoming connection
before terminating voluntarily.
<b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
- The maximal number of incoming connections that a
- Postfix daemon process will service before termi-
+ The maximal number of incoming connections that a
+ Postfix daemon process will service before termi-
nating voluntarily.
<b><a href="postconf.5.html#myhostname">myhostname</a> (see 'postconf -d' output)</b>
The internet hostname of this mail system.
<b><a href="postconf.5.html#mynetworks">mynetworks</a> (see 'postconf -d' output)</b>
- The list of "trusted" SMTP clients that have more
+ The list of "trusted" SMTP clients that have more
privileges than "strangers".
<b><a href="postconf.5.html#myorigin">myorigin</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
The domain name that locally-posted mail appears to
- come from, and that locally posted mail is deliv-
+ come from, and that locally posted mail is deliv-
ered to.
<b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
- The process ID of a Postfix command or daemon
+ The process ID of a Postfix command or daemon
process.
<b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
- The process name of a Postfix command or daemon
+ The process name of a Postfix command or daemon
process.
<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-
+ The location of the Postfix top-level queue direc-
tory.
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
sions (user+foo).
<b><a href="postconf.5.html#smtpd_banner">smtpd_banner</a> ($<a href="postconf.5.html#myhostname">myhostname</a> ESMTP $<a href="postconf.5.html#mail_name">mail_name</a>)</b>
- The text that follows the 220 status code in the
+ The text that follows the 220 status code in the
SMTP greeting banner.
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
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"
+ <b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
+ The mail system name that is prepended to the
+ process name in syslog records, so that "smtpd"
becomes, for example, "postfix/smtpd".
Available in Postfix version 2.2 and later:
<b><a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a> (CONNECT, GET, POST)</b>
- List of commands that causes the Postfix SMTP
- server to immediately terminate the session with a
+ List of commands that causes the Postfix SMTP
+ server to immediately terminate the session with a
221 code.
Available in Postfix version 2.5 and later:
<b><a href="postconf.5.html#smtpd_client_port_logging">smtpd_client_port_logging</a> (no)</b>
- Enable logging of the remote SMTP client port in
+ Enable logging of the remote SMTP client port in
addition to the hostname and IP address.
<b>SEE ALSO</b>
<a href="XFORWARD_README.html">XFORWARD_README</a>, Postfix XFORWARD extension
<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>
client request is rejected by the "reject" restriction.
.PP
Do not change this unless you have a complete understanding of RFC 2821.
+.SH reject_tempfail_action (default: defer_if_permit)
+The Postfix SMTP server's action when a reject-type restriction
+fails due to a temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"defer_if_permit" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted.
+.PP
+For finer control, see: unverified_recipient_tempfail_action,
+unverified_sender_tempfail_action, unknown_address_tempfail_action,
+and unknown_helo_hostname_tempfail_action.
+.PP
+This feature is available in Postfix 2.6 and later.
.SH relay_clientcerts (default: empty)
List of tables with remote SMTP client-certificate fingerprints
for which the Postfix SMTP server will allow access with the
multi-recipient mail that was posted with the DSN option NOTIFY=NEVER
may be forwarded with the null sender address.
.br
- Note: this restriction can only work reliably
+Note: this restriction can only work reliably
when used in smtpd_data_restrictions or
smtpd_end_of_data_restrictions, because the total number of
recipients is not known at an earlier stage of the SMTP conversation.
.IP "\fBreject\fR"
Reject the request. This restriction is useful at the end of
a restriction list, to make the default policy explicit. The
-reject_code configuration parameter specifies the response code to
+reject_code configuration parameter specifies the response code for
rejected requests (default: 554).
.IP "\fBsleep \fIseconds\fR\fR"
Pause for the specified number of seconds and proceed with
format of message headers will also cause a disconnect.
.PP
This feature is available in Postfix 2.2 and later.
-.SH smtpd_hard_error_limit (default: 20)
+.SH smtpd_hard_error_limit (default: normal: 20, stress: 1)
The maximal number of errors a remote SMTP client is allowed to
make without delivering mail. The Postfix SMTP server disconnects
-when the limit is exceeded.
+when the limit is exceeded. Normally the default limit is 20, but
+it changes under overload to just 1 with Postfix 2.6 and later.
.SH smtpd_helo_required (default: no)
Require that a remote SMTP client introduces itself at the beginning
of an SMTP session with the HELO or EHLO command.
invalid.
.br
The invalid_hostname_reject_code specifies the response
-code to rejected requests (default: 501).
+code for rejected requests (default: 501).
.IP "\fBreject_non_fqdn_helo_hostname\fR (with Postfix < 2.3: reject_non_fqdn_hostname)"
Reject the request when the HELO or EHLO hostname is not in
fully-qualified domain form, as required by the RFC.
.br
The
-non_fqdn_reject_code parameter specifies the response code to
+non_fqdn_reject_code parameter specifies the response code for
rejected requests (default: 504).
.IP "\fBreject_rhsbl_helo \fIrbl_domain=d.d.d.d\fR\fR"
Reject the request when the HELO or EHLO hostname hostname is
Reject the request when the HELO or EHLO hostname has no DNS A
or MX record.
.br
-The unknown_hostname_reject_code specifies the
-response code to rejected requests (default: 450).
+The unknown_hostname_reject_code parameter
+specifies the numerical response code for rejected requests (default:
+450).
+.br
+The unknown_helo_hostname_tempfail_action parameter
+specifies the action after a temporary DNS error (default:
+defer_if_permit).
.PP
Other restrictions that are valid in this context:
.IP \(bu
.SH smtpd_history_flush_threshold (default: 100)
The maximal number of lines in the Postfix SMTP server command history
before it is flushed upon receipt of EHLO, RSET, or end of DATA.
-.SH smtpd_junk_command_limit (default: 100)
+.SH smtpd_junk_command_limit (default: normal: 100, stress: 1)
The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote
SMTP client can send before the Postfix SMTP server starts to
increment the error counter with each junk command. The junk
command count is reset after mail is delivered. See also the
smtpd_error_sleep_time and smtpd_soft_error_limit configuration
-parameters.
+parameters. Normally the default limit is 100, but it changes under
+overload to just 1 with Postfix 2.6 and later.
.SH smtpd_milters (default: empty)
A list of Milter (mail filter) applications for new mail that
arrives via the Postfix \fBsmtpd\fR(8) server. See the MILTER_README
fully-qualified domain form, as required by the RFC.
.br
The
-non_fqdn_reject_code parameter specifies the response code to
+non_fqdn_reject_code parameter specifies the response code for
rejected requests (default: 504).
.IP "\fBreject_rhsbl_recipient \fIrbl_domain=d.d.d.d\fR\fR"
Reject the request when the RCPT TO domain is listed with the
a zero-length MX hostname (Postfix version 2.3 and later).
.br
The
-unknown_address_reject_code parameter specifies the response code
-for rejected requests (default: 450). The response is always 450
-in case of a temporary DNS error.
+unknown_address_reject_code parameter specifies the numerical
+response code for rejected requests (default: 450). The response
+is always 450 in case of a temporary DNS error.
+.br
+The
+unknown_address_tempfail_action parameter specifies the action
+after a temporary DNS error (default: defer_if_permit).
.IP "\fBreject_unlisted_recipient\fR (with Postfix version 2.0: check_recipient_maps)"
Reject the request when the RCPT TO address is not listed in
the list of valid recipients for its domain class. See the
see the ADDRESS_VERIFICATION_README file for details.
.br
The
-unverified_recipient_reject_code parameter specifies the response
-when an address is known to bounce (default: 450, change into 550
-when you are confident that it is safe to do so). The
-unverified_recipient_defer_code parameter specifies the response
-when an address probe failed due to a temporary problem (default:
-450). This feature is available in Postfix 2.1 and later.
+unverified_recipient_reject_code parameter specifies the numerical
+response code when an address is known to bounce (default: 450,
+change into 550 when you are confident that it is safe to do so).
+.br
+The unverified_recipient_defer_code parameter specifies the
+numerical response code when an address probe failed due to a
+temporary problem (default: 450).
+.br
+The
+unverified_recipient_tempfail_action parameter specifies the action
+after addres probe failure due to a temporary problem (default:
+defer_if_permit).
+.br
+This feature is available in Postfix 2.1
+and later.
.PP
Other restrictions that are valid in this context:
.IP \(bu
fully-qualified domain form, as required by the RFC.
.br
The
-non_fqdn_reject_code parameter specifies the response code to
+non_fqdn_reject_code parameter specifies the response code for
rejected requests (default: 504).
.IP "\fBreject_rhsbl_sender \fIrbl_domain=d.d.d.d\fR\fR"
Reject the request when the MAIL FROM domain is listed with
a zero-length MX hostname (Postfix version 2.3 and later).
.br
The
-unknown_address_reject_code parameter specifies the response code
-for rejected requests (default: 450). The response is always 450
-in case of a temporary DNS error.
+unknown_address_reject_code parameter specifies the numerical
+response code for rejected requests (default: 450). The response
+is always 450 in case of a temporary DNS error.
+.br
+The
+unknown_address_tempfail_action parameter specifies the action
+after a temporary DNS error (default: defer_if_permit).
.IP "\fBreject_unlisted_sender\fR"
Reject the request when the MAIL FROM address is not listed in
the list of valid recipients for its domain class. See the
see the ADDRESS_VERIFICATION_README file for details.
.br
The
-unverified_sender_reject_code parameter specifies the response when
-an address is known to bounce (default: 450, change into 550 when
-you are confident that it is safe to do so). The
-unverified_sender_defer_code specifies the response when an address
-address probe failed due to a temporary problem (default: 450).
-This feature is available in Postfix 2.1 and later.
+unverified_sender_reject_code parameter specifies the numerical
+response code when an address is known to bounce (default: 450,
+change into 550 when you are confident that it is safe to do so).
+.br
+The unverified_sender_defer_code specifies the numerical response
+code when an address address probe failed due to a temporary problem
+(default: 450).
+.br
+The unverified_sender_tempfail_action parameter
+specifies the action after address probe failure due to a temporary
+problem (default: defer_if_permit).
+.br
+This feature is available
+in Postfix 2.1 and later.
.PP
Other restrictions that are valid in this context:
.IP \(bu
during TLS startup and shutdown handshake procedures.
.PP
This feature is available in Postfix 2.2 and later.
-.SH smtpd_timeout (default: 300s)
+.SH smtpd_timeout (default: normal: 300s, stress: 10s)
The time limit for sending a Postfix SMTP server response and for
-receiving a remote SMTP client request.
+receiving a remote SMTP client request. Normally the default limit
+is 300s, but it changes under overload to just 10s with Postfix 2.6
+and later.
.PP
Note: if you set SMTP time limits to very large values you may have
to update the global ipc_timeout parameter.
always 450 in case of a temporary DNS error.
.PP
Do not change this unless you have a complete understanding of RFC 2821.
+.SH unknown_address_tempfail_action (default: $reject_tempfail_action)
+The Postfix SMTP server's action when reject_unknown_sender_domain
+or reject_unknown_recipient_domain fail due to a temporary error
+condition. Specify "defer" to defer the remote SMTP client request
+immediately. With the default "defer_if_permit" action, the Postfix
+SMTP server continues to look for opportunities to reject mail, and
+defers the client request only if it would otherwise be accepted.
+.PP
+This feature is available in Postfix 2.6 and later.
.SH unknown_client_reject_code (default: 450)
The numerical Postfix SMTP server response code when a client
without valid address <=> name mapping is rejected by the
with 450 when the mapping failed due to a temporary error condition.
.PP
Do not change this unless you have a complete understanding of RFC 2821.
+.SH unknown_helo_hostname_tempfail_action (default: $reject_tempfail_action)
+The Postfix SMTP server's action when reject_unknown_helo_hostname
+fails due to an temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"defer_if_permit" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted.
+.PP
+This feature is available in Postfix 2.6 and later.
.SH unknown_hostname_reject_code (default: 450)
The numerical Postfix SMTP server response code when the hostname
specified with the HELO or EHLO command is rejected by the
.PP
This feature is available in Postfix 2.1 and later.
.SH unverified_recipient_reject_reason (default: empty)
-When rejecting mail with reject_unverified_recipient, reply
-with this text as the reason, instead of actual address verification
-details.
+The Postfix SMTP server's reply when rejecting mail with
+reject_unverified_recipient. Do not include the numeric SMTP reply
+code or the enhanced status code. By default, the response includes
+actual address verification details.
+.PP
+Example:
+.PP
+.nf
+.na
+.ft C
+unverified_recipient_reject_reason = Recipient address lookup failed
+.fi
+.ad
+.ft R
+.PP
+This feature is available in Postfix 2.6 and later.
+.SH unverified_recipient_tempfail_action (default: $reject_tempfail_action)
+The Postfix SMTP server's action when reject_unverified_recipient
+fails due to a temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"defer_if_permit" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted.
.PP
This feature is available in Postfix 2.6 and later.
.SH unverified_sender_defer_code (default: 450)
.PP
This feature is available in Postfix 2.1 and later.
.SH unverified_sender_reject_reason (default: empty)
-When rejecting mail with reject_unverified_sender, reply with
-this text as the reason, instead of actual address verification
-details.
+The Postfix SMTP server's reply when rejecting mail with
+reject_unverified_sender. Do not include the numeric SMTP reply
+code or the enhanced status code. By default, the response includes
+actual address verification details.
+.PP
+Example:
+.PP
+.nf
+.na
+.ft C
+unverified_sender_reject_reason = Sender address lookup failed
+.fi
+.ad
+.ft R
+.PP
+This feature is available in Postfix 2.6 and later.
+.SH unverified_sender_tempfail_action (default: $reject_tempfail_action)
+The Postfix SMTP server's action when reject_unverified_sender
+fails due to a temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"defer_if_permit" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted.
.PP
This feature is available in Postfix 2.6 and later.
.SH verp_delimiter_filter (default: -=+)
.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. A trivial but useful implementation,
-with instructions, can be found in
-$daemon_directory/postfix-wrapper.
+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.
-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.
+This document describes how the familiar "postfix start"
+etc. user interface can be used to manage one or multiple
+Postfix instances, and gives details of an API that allows
+the postfix(1) command to coordinate activities with a
+multi-instance manager program.
-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.
+A trivial but useful multi-instance manager implementation
+is described below, and can be found in the file
+$daemon_directory/postfix-wrapper. The latter file also
+contains instructions for setting up multiple instances.
+
+With multi-instance support, 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.
.SH "GENERAL OPERATION"
.na
.nf
.ad
.fi
-First of all, nothing changes when there is only one Postfix
-instance.
+Multi-instance support is backwards compatible: when there
+is only one Postfix instance, commands such as "postfix
+start" keep doing what they have always done.
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.
+the mechanisms discussed later, sites can continue to use
+the familiar postfix commands in boot scripts, upgrade
+procedures, and other places.
-To start, stop, update, etc., multiple Postfix instances,
-use:
+To start all applicable Postfix instances, use:
.IP
-# postfix \fIcommand\fR
+# postfix start
.PP
-For example, to find out what Postfix instances are configured:
+Other postfix(1) commands also work as expected. For example,
+to find out what Postfix instances exist in a multi-instance
+configuration, use:
.IP
# postfix status
+.PP
+This enumerates the status of all Postfix instances within
+a multi-instance configuration.
.SH "MANAGING AN INDIVIDUAL POSTFIX INSTANCE"
.na
.nf
.ad
.fi
-To manage an individual Postfix instance, use:
+To operate on a specific Postfix instance, specify its
+configuration directory on the postfix(1) command line:
.IP
# postfix -c \fI/path/to/config_directory command\fR
.PP
-When the postfix(1) command is invoked with the -c option,
-it will operate only on the specified instance. The same
-happens when MAIL_CONFIG is specified in the process
-environment.
+Alternatively, the postfix(1) command accepts the instance's
+configuration directory via the MAIL_CONFIG environment
+variable (the -c command-line option has higher precedence).
-Otherwise, the postfix(1) command will operate on all
-applicable Postfix instances.
-.SH "MULTI-INSTANCE MANAGER EXAMPLE"
+When no Postfix instance information is specified, the
+postfix(1) command will operate on all applicable Postfix
+instances.
+.SH "MULTI-INSTANCE MANAGER IMPLEMENTATION"
.na
.nf
.ad
.fi
-When the postfix(1) command is invoked without -c option
-or MAIL_CONFIG environment setting, and non-default Postfix
-instance directories are defined in main.cf with the
-multi_instance_directories parameter, postfix(1) invokes
-the command specified in main.cf with the multi_instance_wrapper
-parameter, instead of invoking postfix-script.
+Historically, the postfix(1) command invokes the postfix-script
+file (currently installed in the daemon directory). This
+file contains the commands that start or stop Postfix,
+upgrade the configuration and so on.
+
+When multi-instance support is turned on, the postfix(1)
+command needs to execute these commands for each applicable
+Postfix instance. This multiplication of commands is handled
+by a multi-instance manager program.
+
+Turning on multi-instance support goes as follows: update
+the default Postfix instance's main.cf file, and populate
+the multi_instance_directories parameter with the configuration
+directory pathnames of additional Postfix instances.
+
+With multi-instance support turned on, the postfix(1) command
+invokes a multi-instance manager command instead of the
+postfix-script file. The multi-instance manager executes
+the postfix(1) command for each applicable Postfix instance.
+The pathname of the multi-instance manager is specified in
+the default main.cf file with the multi_instance_wrapper
+parameter.
The multi_instance_directories and other main.cf parameters
are listed below in the CONFIGURATION PARAMETERS section.
-A useful wrapper implementation can be as simple as:
+A useful multi-instance manager implementation can be as
+simple as:
.IP
.nf
#!/bin/sh
case "$1" in
stop|abort|flush|reload|drain)
test "\`$POSTCONF -c $dir -h multi_instance_enable\`" \e
- = yes || continue;;
+ = yes || continue;;
start)
test "\`$POSTCONF -c $dir -h multi_instance_enable\`" \e
- = yes || set check;;
+ = yes || {
+ $POSTFIX -c $dir check || err=$?
+ continue
+ };;
esac
$POSTFIX -c $dir "$@" || err=$?
done
exit $err
.fi
.PP
+A sample implementation, with instructions, can be found
+in $daemon_directory/postfix-wrapper.
+
The postmulti(1) command implements a more sophisticated
approach, based on a combination of C code and scripting.
-.SH "ENABLING AN INSTANCE FOR MULTI-INSTANCE OPERATION"
+.SH "ENABLING A SPECIFIC INSTANCE FOR MULTI-INSTANCE OPERATION"
.na
.nf
.ad
.fi
-To enable start/stop/etc. by a multi-instance manager, set
-the Postfix instance's main.cf multi_instance_enable parameter
-to "yes". This parameter has no effect on single-instance
-operation with "postfix -c" or with a MAIL_CONFIG environment
-setting.
+Each Postfix instance has its own main.cf file with parameters
+that control multi-instance operation. The most important
+settings are discussed here.
+
+The setting "multi_instance_enable = yes" allows the
+multi-instance manager to start (and stop) the corresponding
+Postfix instance. For safety reasons, this setting is not
+the default.
-The multi-instance manager program will skip commands such
-as "stop" and "flush" when a Postfix instance is disabled,
-and will replace "start" by "check" so that problems will
-still be reported even when the default instance is disabled.
+The setting "multi_instance_enable = no" is useful for
+manual testing. With this, the multi-instance manager will
+not start the Postfix instance, and it will skip commands
+such as "stop" or "flush" that require a running Postfix
+instance. The multi-instance manager will execute commands
+such as "check", "set-permissions" or "upgrade-configuration",
+and it will replace "start" by "check" so that problems
+will be reported even when the instance is disabled.
.SH "SHARED VERSUS NON-SHARED FILES"
.na
.nf
.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.
+such as the queue directory. See the NON-SHARED FILES
+section below for a list of per-instance files.
Before Postfix multi-instance support was implemented, the
executables, manpages, etc., have always 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.
+
+Specifically, Postfix instances will not check or update
+shared files when their config_directory value is listed
+with the default main.cf's multi_instance_directories
+parameter.
The consequence of this approach is that the default Postfix
-instance should be updated before any other instances.
+instance should be checked and updated before any other
+instances.
.SH "MULTI-INSTANCE API SUMMARY"
.na
.nf
.fi
Only the multi-instance manager implements support for the
multi_instance_enable configuration parameter. The
-multi-instance manager will not start Postfix instances
-without "multi_instance_enable = yes". This allows a Postfix
-instance to be tested by hand before it is placed under
-control of a multi-instance manager.
+multi-instance manager will start only Postfix instances
+whose main.cf file has "multi_instance_enable = yes". A
+setting of "no" allows a Postfix instance to be tested by
+hand.
-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.
+The postfix(1) command operates on only one Postfix instance
+when the -c option is specified, or when MAIL_CONFIG is
+present in the process environment. This is necessary to
+terminate recursion.
Otherwise, when the multi_instance_directories parameter
value is non-empty, the postfix(1) command executes the
This avoids false error messages.
The multi-instance manager replaces 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 even when the default
-instance is disabled.
+"check" when a Postfix instance's main.cf file does not
+have "multi_instance_enable = yes". This substitution ensures
+that problems will be reported even when the instance is
+disabled.
No Postfix command or script will update or check shared
-files unless it is running in the context of the default
-Postfix instance. Therefore, the default instance should
-be updated before any other Postfix instances.
+files when its config_directory value is listed in the
+default main.cf's multi_instance_directories parameter
+value. Therefore, the default instance should be checked
+and updated before any Postfix instances that depend on it.
Set-gid commands such as postdrop(1) and postqueue(1)
effectively append the multi_instance_directories parameter
.na
.nf
postfix(1) Postfix control program
-$daemon_directory/postfix-wrapper simple multi-instance manager
postmulti(1) full-blown multi-instance manager
+$daemon_directory/postfix-wrapper simple multi-instance manager
.SH "LICENSE"
.na
.nf
.ad
.fi
-The Secure Mailer license must be distributed with this software.
+The Secure Mailer license must be distributed with this
+software.
.SH "AUTHOR(S)"
.na
.nf
.IP "\fBmilter_content_timeout (300s)\fR"
The time limit for sending message content to a Milter (mail
filter) application, and for receiving the response.
-.IP "\fBmilter_connect_macros (see postconf -n output)\fR"
+.IP "\fBmilter_connect_macros (see 'postconf -d' output)\fR"
The macros that are sent to Milter (mail filter) applications
after completion of an SMTP connection.
-.IP "\fBmilter_helo_macros (see postconf -n output)\fR"
+.IP "\fBmilter_helo_macros (see 'postconf -d' output)\fR"
The macros that are sent to Milter (mail filter) applications
after the SMTP HELO or EHLO command.
-.IP "\fBmilter_mail_macros (see postconf -n output)\fR"
+.IP "\fBmilter_mail_macros (see 'postconf -d' output)\fR"
The macros that are sent to Milter (mail filter) applications
after the SMTP MAIL FROM command.
-.IP "\fBmilter_rcpt_macros (see postconf -n output)\fR"
+.IP "\fBmilter_rcpt_macros (see 'postconf -d' output)\fR"
The macros that are sent to Milter (mail filter) applications
after the SMTP RCPT TO command.
-.IP "\fBmilter_data_macros (see postconf -n output)\fR"
+.IP "\fBmilter_data_macros (see 'postconf -d' output)\fR"
The macros that are sent to version 4 or higher Milter (mail
filter) applications after the SMTP DATA command.
-.IP "\fBmilter_unknown_command_macros (see postconf -n output)\fR"
+.IP "\fBmilter_unknown_command_macros (see 'postconf -d' output)\fR"
The macros that are sent to version 3 or higher Milter (mail
filter) applications after an unknown SMTP command.
-.IP "\fBmilter_end_of_header_macros (see postconf -n output)\fR"
+.IP "\fBmilter_end_of_header_macros (see 'postconf -d' output)\fR"
The macros that are sent to Milter (mail filter) applications
after the end of the message header.
-.IP "\fBmilter_end_of_data_macros (see postconf -n output)\fR"
+.IP "\fBmilter_end_of_data_macros (see 'postconf -d' output)\fR"
The macros that are sent to Milter (mail filter) applications
after the message end-of-data.
.SH "GENERAL CONTENT INSPECTION CONTROLS"
.IP "\fBsmtpd_recipient_limit (1000)\fR"
The maximal number of recipients that the Postfix SMTP server
accepts per message delivery request.
-.IP "\fBsmtpd_timeout (300s)\fR"
+.IP "\fBsmtpd_timeout (normal: 300s, stress: 10s)\fR"
The time limit for sending a Postfix SMTP server response and for
receiving a remote SMTP client request.
.IP "\fBsmtpd_history_flush_threshold (100)\fR"
The number of errors a remote SMTP client is allowed to make without
delivering mail before the Postfix SMTP server slows down all its
responses.
-.IP "\fBsmtpd_hard_error_limit (20)\fR"
+.IP "\fBsmtpd_hard_error_limit (normal: 20, stress: 1)\fR"
The maximal number of errors a remote SMTP client is allowed to
make without delivering mail.
-.IP "\fBsmtpd_junk_command_limit (100)\fR"
+.IP "\fBsmtpd_junk_command_limit (normal: 100, stress: 1)\fR"
The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote
SMTP client can send before the Postfix SMTP server starts to
increment the error counter with each junk command.
The numerical Postfix SMTP server response when a recipient address
probe fails due to a temporary error condition.
.IP "\fBunverified_sender_reject_reason (empty)\fR"
-When rejecting mail with reject_unverified_sender, reply with
-this text as the reason, instead of actual address verification
-details.
+The Postfix SMTP server's reply when rejecting mail with
+reject_unverified_sender.
.IP "\fBunverified_recipient_reject_reason (empty)\fR"
-When rejecting mail with reject_unverified_recipient, reply
-with this text as the reason, instead of actual address verification
-details.
+The Postfix SMTP server's reply when rejecting mail with
+reject_unverified_recipient.
+.IP "\fBunverified_sender_tempfail_action ($reject_tempfail_action)\fR"
+The Postfix SMTP server's action when reject_unverified_sender
+fails due to a temporary error condition.
+.IP "\fBunverified_recipient_tempfail_action ($reject_tempfail_action)\fR"
+The Postfix SMTP server's action when reject_unverified_recipient
+fails due to a temporary error condition.
.SH "ACCESS CONTROL RESPONSES"
.na
.nf
The numerical Postfix SMTP server response code for
an \fBaccess\fR(5) map "defer" action, including "defer_if_permit"
or "defer_if_reject".
+.IP "\fBreject_tempfail_action (defer_if_permit)\fR"
+The Postfix SMTP server's action when a reject-type restriction
+fails due to a temporary error condition.
+.IP "\fBunknown_helo_hostname_tempfail_action ($reject_tempfail_action)\fR"
+The Postfix SMTP server's action when reject_unknown_helo_hostname
+fails due to an temporary error condition.
+.IP "\fBunknown_address_tempfail_action ($reject_tempfail_action)\fR"
+The Postfix SMTP server's action when reject_unknown_sender_domain
+or reject_unknown_recipient_domain fail due to a temporary error
+condition.
.SH "MISCELLANEOUS CONTROLS"
.na
.nf
banner.
.IP "\fBsyslog_facility (mail)\fR"
The syslog facility of Postfix logging.
-.IP "\fBsyslog_name (postfix)\fR"
+.IP "\fBsyslog_name (see 'postconf -d' output)\fR"
The mail system name that is prepended to the process name in syslog
records, so that "smtpd" becomes, for example, "postfix/smtpd".
.PP
$block =~ s/\s*<\/tt>//g;
$block =~ s/<blockquote>/\n.sp\n.in +4\n/g;
$block =~ s/<\/blockquote>/\n.in -4\n/g;
- $block =~ s/\n<br>/\n.br\n/g;
+ $block =~ s/\n<br>\s*/\n.br\n/g;
$block =~ s/<br>\s*/\n.br\n/g;
$block =~ s/≤/<=/g;
$block =~ s/</</g;
s;\brecip[-</bB>]*\n* *[<bB>]*ient_canoni[-</bB>]*\n* *[<bB>]*cal_maps\b;<a href="postconf.5.html#recipient_canonical_maps">$&</a>;g;
s;\brecip[-</bB>]*\n* *[<bB>]*ient_delim[-</bB>]*\n* *[<bB>]*iter\b;<a href="postconf.5.html#recipient_delimiter">$&<\/a>;g;
s;\breject_code\b;<a href="postconf.5.html#reject_code">$&</a>;g;
+ s;\breject_temp[-</bB>]*\n* *[<bB>]*fail_action\b;<a href="postconf.5.html#reject_tempfail_action">$&</a>;g;
s;\brelay_clientcerts\b;<a href="postconf.5.html#relay_clientcerts">$&</a>;g;
s;\brelay_domains\b;<a href="postconf.5.html#relay_domains">$&</a>;g;
s;\brelay_domains_reject_code\b;<a href="postconf.5.html#relay_domains_reject_code">$&</a>;g;
s;\btcp_windowsize\b;<a href="postconf.5.html#tcp_windowsize">$&</a>;g;
s;\bundisclosed_recip[-</bB>]*\n* *[<bB>]*ients_header\b;<a href="postconf.5.html#undisclosed_recipients_header">$&</a>;g;
s;\bunknown_address_reject_code\b;<a href="postconf.5.html#unknown_address_reject_code">$&</a>;g;
+ s;\bunknown_address_tempfail_action\b;<a href="postconf.5.html#unknown_address_tempfail_action">$&</a>;g;
s;\bunknown_client_reject_code\b;<a href="postconf.5.html#unknown_client_reject_code">$&</a>;g;
s;\bunknown_hostname_reject_code\b;<a href="postconf.5.html#unknown_hostname_reject_code">$&</a>;g;
+ s;\bunknown_helo_hostname_tempfail_action\b;<a href="postconf.5.html#unknown_helo_hostname_tempfail_action">$&</a>;g;
s;\bunknown_local_recip[-</bB>]*\n* *[<bB>]*ient_reject_code\b;<a href="postconf.5.html#unknown_local_recipient_reject_code">$&</a>;g;
s;\bunknown_relay_recipi[-</bB>]*\n*[ <bB>]*ent_reject_code\b;<a href="postconf.5.html#unknown_relay_recipient_reject_code">$&</a>;g;
s;\bunknown_virtual_alias_reject_code\b;<a href="postconf.5.html#unknown_virtual_alias_reject_code">$&</a>;g;
s;\bunknown_virtual_mail[-</bB>]*\n* *[<bB>]*box_reject_code\b;<a href="postconf.5.html#unknown_virtual_mailbox_reject_code">$&</a>;g;
s;\bunverified_recip[-</bB>]*\n* *[<bB>]*ient_reject_code\b;<a href="postconf.5.html#unverified_recipient_reject_code">$&</a>;g;
s;\bunverified_recip[-</bB>]*\n* *[<bB>]*ient_defer_code\b;<a href="postconf.5.html#unverified_recipient_defer_code">$&</a>;g;
+ s;\bunverified_recip[-</bB>]*\n* *[<bB>]*ient_tempfail_action\b;<a href="postconf.5.html#unverified_recipient_tempfail_action">$&</a>;g;
s;\bunverified_sender_reject_code\b;<a href="postconf.5.html#unverified_sender_reject_code">$&</a>;g;
s;\bunverified_sender_defer_code\b;<a href="postconf.5.html#unverified_sender_defer_code">$&</a>;g;
+ s;\bunverified_sender_tempfail_action\b;<a href="postconf.5.html#unverified_sender_tempfail_action">$&</a>;g;
s;\bunverified_recipient_reject_reason\b;<a href="postconf.5.html#unverified_recipient_reject_reason">$&</a>;g;
s;\bunverified_sender_reject_reason\b;<a href="postconf.5.html#unverified_sender_reject_reason">$&</a>;g;
s;\bverp_delimiter_filter\b;<a href="postconf.5.html#verp_delimiter_filter">$&</a>;g;
s;\breject_unauthenticated_sender_login_mismatch\b;<a href="postconf.5.html#reject_unauthenticated_sender_login_mismatch">$&</a>;g;
s;\breject_unknown_sender_domain\b;<a href="postconf.5.html#reject_unknown_sender_domain">$&</a>;g;
s;\breject_unlisted_sender\b;<a href="postconf.5.html#reject_unlisted_sender">$&</a>;g;
- s;\breject_unveri[-</bB>]*\n*[ <bB>]*fied_sender\b;<a href="postconf.5.html#reject_unverified_sender">$&</a>;g;
+ s;\breject_unver[-</bB>]*\n*[ <bB>]*ified_sender\b;<a href="postconf.5.html#reject_unverified_sender">$&</a>;g;
# Access restrictions - recipient
s;\breject_unauth_destination\b;<a href="postconf.5.html#reject_unauth_destination">$&</a>;g;
s;\breject_unknown_recipi[-</bB>]*\n*[ <bB>]*ent_domain\b;<a href="postconf.5.html#reject_unknown_recipient_domain">$&</a>;g;
s;\breject_unlisted_recip[-</bB>]*\n* *[<bB>]*ient\b;<a href="postconf.5.html#reject_unlisted_recipient">$&</a>;g;
- s;\breject_unveri[-</bB>]*\n*[ <bB>]*fied_recip[-</bB>]*\n* *[<bB>]*ient\b;<a href="postconf.5.html#reject_unverified_recipient">$&</a>;g;
+ s;\breject_unver[-</bB>]*\n*[ <bB>]*ified_recip[-</bB>]*\n* *[<bB>]*ient\b;<a href="postconf.5.html#reject_unverified_recipient">$&</a>;g;
# Access restrictions - etrn
<h2><a name="how">How address verification works</a></h2>
-<p> A sender or recipient address is verified by probing the nearest
+<p> A Postfix MTA verifies a sender or recipient address by probing
+the nearest
MTA for that address, without actually delivering mail. The nearest
-MTA could be Postfix itself, or it could be a remote MTA (SMTP
+MTA could be the Postfix MTA itself, or it could be a remote MTA
+(SMTP
interruptus). Probe messages are like normal mail, except that
they are never delivered, deferred or bounced; probe messages are
always discarded. </p>
<p> The unverified_recipient_reject_reason parameter (default:
empty) specifies fixed text that Postfix will send to remote SMTP
-clients, instead of sending actual address verification details. </p>
+clients, instead of sending actual address verification details.
+Do not specify the SMTP status code or enhanced status code. </p>
+
+<p> The unverified_recipient_tempfail_action parameter (default:
+defer_if_permit) specifies the Postfix SMTP server action when a
+recipient address verification probe fails with some temporary
+error. </p>
<h2><a name="forged_sender">Sender address verification for mail from frequently forged domains</a></h2>
<p> The unverified_sender_reject_reason parameter (default:
empty) specifies fixed text that Postfix will send to remote SMTP
-clients, instead of sending actual addres verification details. </p>
+clients, instead of sending actual addres verification details.
+Do not specify the SMTP status code or enhanced status code. </p>
+
+<p> The unverified_sender_tempfail_action parameter (default:
+defer_if_permit) specifies the Postfix SMTP server action when a
+sender address verification probe fails with some temporary error.
+</p>
<h2><a name="caching">Address verification database</a></h2>
<blockquote> <pre>
% cd INSTALL_ROOT
% rm -f SOMEWHERE/outputfile
-% find . \! -type d -print | xargs tar cf SOMEWHERE/outputfile
+% find . \! -type d -print | xargs tar rf SOMEWHERE/outputfile
% gzip SOMEWHERE/outputfile </pre> </blockquote>
<p>This way you will not include any directories that might cause
<dd>Reject the request. This restriction is useful at the end of
a restriction list, to make the default policy explicit. The
-reject_code configuration parameter specifies the response code to
+reject_code configuration parameter specifies the response code for
rejected requests (default: 554).</dd>
<dt><b><a name="sleep">sleep <i>seconds</i></a></b></dt>
</ul>
-%PARAM smtpd_hard_error_limit 20
+%PARAM smtpd_hard_error_limit normal: 20, stress: 1
<p>
The maximal number of errors a remote SMTP client is allowed to
make without delivering mail. The Postfix SMTP server disconnects
-when the limit is exceeded.
+when the limit is exceeded. Normally the default limit is 20, but
+it changes under overload to just 1 with Postfix 2.6 and later.
</p>
-%PARAM smtpd_junk_command_limit 100
+%PARAM smtpd_junk_command_limit normal: 100, stress: 1
<p>
The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote
increment the error counter with each junk command. The junk
command count is reset after mail is delivered. See also the
smtpd_error_sleep_time and smtpd_soft_error_limit configuration
-parameters.
+parameters. Normally the default limit is 100, but it changes under
+overload to just 1 with Postfix 2.6 and later.
</p>
%PARAM smtpd_recipient_overshoot_limit 1000
<dd>Reject the request when the HELO or EHLO hostname syntax is
invalid. <br> The invalid_hostname_reject_code specifies the response
-code to rejected requests (default: 501).</dd>
+code for rejected requests (default: 501).</dd>
<dt><b><a name="reject_non_fqdn_helo_hostname">reject_non_fqdn_helo_hostname</a></b> (with Postfix < 2.3: reject_non_fqdn_hostname)</dt>
<dd>Reject the request when the HELO or EHLO hostname is not in
fully-qualified domain form, as required by the RFC. <br> The
-non_fqdn_reject_code parameter specifies the response code to
+non_fqdn_reject_code parameter specifies the response code for
rejected requests (default: 504).</dd>
<dt><b><a name="reject_rhsbl_helo">reject_rhsbl_helo <i>rbl_domain=d.d.d.d</i></a></b></dt>
<dt><b><a name="reject_unknown_helo_hostname">reject_unknown_helo_hostname</a></b> (with Postfix < 2.3: reject_unknown_hostname)</dt>
<dd>Reject the request when the HELO or EHLO hostname has no DNS A
-or MX record. <br> The unknown_hostname_reject_code specifies the
-response code to rejected requests (default: 450). </dd>
+or MX record. <br> The unknown_hostname_reject_code parameter
+specifies the numerical response code for rejected requests (default:
+450). <br> The unknown_helo_hostname_tempfail_action parameter
+specifies the action after a temporary DNS error (default:
+defer_if_permit). </dd>
</dl>
<dd>Reject the request when the RCPT TO address is not in
fully-qualified domain form, as required by the RFC. <br> The
-non_fqdn_reject_code parameter specifies the response code to
+non_fqdn_reject_code parameter specifies the response code for
rejected requests (default: 504). </dd>
<dt><b><a name="reject_rhsbl_recipient">reject_rhsbl_recipient <i>rbl_domain=d.d.d.d</i></a></b></dt>
the recipient domain, and the RCPT TO domain has no DNS A or MX
record, or when it has a malformed MX record such as a record with
a zero-length MX hostname (Postfix version 2.3 and later). <br> The
-unknown_address_reject_code parameter specifies the response code
-for rejected requests (default: 450). The response is always 450
-in case of a temporary DNS error.</dd>
+unknown_address_reject_code parameter specifies the numerical
+response code for rejected requests (default: 450). The response
+is always 450 in case of a temporary DNS error. <br> The
+unknown_address_tempfail_action parameter specifies the action
+after a temporary DNS error (default: defer_if_permit). </dd>
<dt><b><a name="reject_unlisted_recipient">reject_unlisted_recipient</a></b> (with Postfix version 2.0: check_recipient_maps)</dt>
to bounce, or when the recipient address destination is not reachable.
Address verification information is managed by the verify(8) server;
see the ADDRESS_VERIFICATION_README file for details. <br> The
-unverified_recipient_reject_code parameter specifies the response
-when an address is known to bounce (default: 450, change into 550
-when you are confident that it is safe to do so). The
-unverified_recipient_defer_code parameter specifies the response
-when an address probe failed due to a temporary problem (default:
-450). This feature is available in Postfix 2.1 and later. </dd>
+unverified_recipient_reject_code parameter specifies the numerical
+response code when an address is known to bounce (default: 450,
+change into 550 when you are confident that it is safe to do so).
+<br>The unverified_recipient_defer_code parameter specifies the
+numerical response code when an address probe failed due to a
+temporary problem (default: 450). <br> The
+unverified_recipient_tempfail_action parameter specifies the action
+after addres probe failure due to a temporary problem (default:
+defer_if_permit). <br> This feature is available in Postfix 2.1
+and later. </dd>
</dl>
<dd>Reject the request when the MAIL FROM address is not in
fully-qualified domain form, as required by the RFC. <br> The
-non_fqdn_reject_code parameter specifies the response code to
+non_fqdn_reject_code parameter specifies the response code for
rejected requests (default: 504). </dd>
<dt><b><a name="reject_rhsbl_sender">reject_rhsbl_sender <i>rbl_domain=d.d.d.d</i></a></b></dt>
the sender address, and the MAIL FROM address has no DNS A or MX
record, or when it has a malformed MX record such as a record with
a zero-length MX hostname (Postfix version 2.3 and later). <br> The
-unknown_address_reject_code parameter specifies the response code
-for rejected requests (default: 450). The response is always 450
-in case of a temporary DNS error. </dd>
+unknown_address_reject_code parameter specifies the numerical
+response code for rejected requests (default: 450). The response
+is always 450 in case of a temporary DNS error. <br> The
+unknown_address_tempfail_action parameter specifies the action
+after a temporary DNS error (default: defer_if_permit). </dd>
<dt><b><a name="reject_unlisted_sender">reject_unlisted_sender</a></b></dt>
bounce, or when the sender address destination is not reachable.
Address verification information is managed by the verify(8) server;
see the ADDRESS_VERIFICATION_README file for details. <br> The
-unverified_sender_reject_code parameter specifies the response when
-an address is known to bounce (default: 450, change into 550 when
-you are confident that it is safe to do so). The
-unverified_sender_defer_code specifies the response when an address
-address probe failed due to a temporary problem (default: 450).
-This feature is available in Postfix 2.1 and later. </dd>
+unverified_sender_reject_code parameter specifies the numerical
+response code when an address is known to bounce (default: 450,
+change into 550 when you are confident that it is safe to do so).
+<br>The unverified_sender_defer_code specifies the numerical response
+code when an address address probe failed due to a temporary problem
+(default: 450). <br> The unverified_sender_tempfail_action parameter
+specifies the action after address probe failure due to a temporary
+problem (default: defer_if_permit). <br> This feature is available
+in Postfix 2.1 and later. </dd>
</dl>
check_sender_access hash:/etc/postfix/access
</pre>
-%PARAM smtpd_timeout 300s
+%PARAM smtpd_timeout normal: 300s, stress: 10s
<p>
The time limit for sending a Postfix SMTP server response and for
-receiving a remote SMTP client request.
+receiving a remote SMTP client request. Normally the default limit
+is 300s, but it changes under overload to just 10s with Postfix 2.6
+and later.
</p>
<p>
%PARAM unverified_sender_reject_reason
-<p> When rejecting mail with reject_unverified_sender, reply with
-this text as the reason, instead of actual address verification
-details.
+<p> The Postfix SMTP server's reply when rejecting mail with
+reject_unverified_sender. Do not include the numeric SMTP reply
+code or the enhanced status code. By default, the response includes
+actual address verification details.
+
+<p> Example: </p>
+
+<pre>
+unverified_sender_reject_reason = Sender address lookup failed
+</pre>
<p> This feature is available in Postfix 2.6 and later. </p>
%PARAM unverified_recipient_reject_reason
-<p> When rejecting mail with reject_unverified_recipient, reply
-with this text as the reason, instead of actual address verification
-details.
+<p> The Postfix SMTP server's reply when rejecting mail with
+reject_unverified_recipient. Do not include the numeric SMTP reply
+code or the enhanced status code. By default, the response includes
+actual address verification details.
+
+<p> Example: </p>
+
+<pre>
+unverified_recipient_reject_reason = Recipient address lookup failed
+</pre>
<p> This feature is available in Postfix 2.6 and later. </p>
This parameter is reserved for the multi-instance manager. </p>
<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM reject_tempfail_action defer_if_permit
+
+<p> The Postfix SMTP server's action when a reject-type restriction
+fails due to a temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"defer_if_permit" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted. </p>
+
+<p> For finer control, see: unverified_recipient_tempfail_action,
+unverified_sender_tempfail_action, unknown_address_tempfail_action,
+and unknown_helo_hostname_tempfail_action. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM unverified_recipient_tempfail_action $reject_tempfail_action
+
+<p> The Postfix SMTP server's action when reject_unverified_recipient
+fails due to a temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"defer_if_permit" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM unverified_sender_tempfail_action $reject_tempfail_action
+
+<p> The Postfix SMTP server's action when reject_unverified_sender
+fails due to a temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"defer_if_permit" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM unknown_address_tempfail_action $reject_tempfail_action
+
+<p> The Postfix SMTP server's action when reject_unknown_sender_domain
+or reject_unknown_recipient_domain fail due to a temporary error
+condition. Specify "defer" to defer the remote SMTP client request
+immediately. With the default "defer_if_permit" action, the Postfix
+SMTP server continues to look for opportunities to reject mail, and
+defers the client request only if it would otherwise be accepted.
+</p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM unknown_helo_hostname_tempfail_action $reject_tempfail_action
+
+<p> The Postfix SMTP server's action when reject_unknown_helo_hostname
+fails due to an temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"defer_if_permit" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
# 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. A trivial but useful implementation,
-# with instructions, can be found in
-# $daemon_directory/postfix-wrapper.
-#
-# 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.
+# 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.
+#
+# This document describes how the familiar "postfix start"
+# etc. user interface can be used to manage one or multiple
+# Postfix instances, and gives details of an API that allows
+# the postfix(1) command to coordinate activities with a
+# multi-instance manager program.
+#
+# A trivial but useful multi-instance manager implementation
+# is described below, and can be found in the file
+# $daemon_directory/postfix-wrapper. The latter file also
+# contains instructions for setting up multiple instances.
+#
+# With multi-instance support, 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.
# GENERAL OPERATION
# .ad
# .fi
-# First of all, nothing changes when there is only one Postfix
-# instance.
+# Multi-instance support is backwards compatible: when there
+# is only one Postfix instance, commands such as "postfix
+# start" keep doing what they have always done.
#
# 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.
+# the mechanisms discussed later, sites can continue to use
+# the familiar postfix commands in boot scripts, upgrade
+# procedures, and other places.
#
-# To start, stop, update, etc., multiple Postfix instances,
-# use:
+# To start all applicable Postfix instances, use:
# .IP
-# # postfix \fIcommand\fR
+# # postfix start
# .PP
-# For example, to find out what Postfix instances are configured:
+# Other postfix(1) commands also work as expected. For example,
+# to find out what Postfix instances exist in a multi-instance
+# configuration, use:
# .IP
# # postfix status
+# .PP
+# This enumerates the status of all Postfix instances within
+# a multi-instance configuration.
# MANAGING AN INDIVIDUAL POSTFIX INSTANCE
# .ad
# .fi
-# To manage an individual Postfix instance, use:
+# To operate on a specific Postfix instance, specify its
+# configuration directory on the postfix(1) command line:
# .IP
# # postfix -c \fI/path/to/config_directory command\fR
# .PP
-# When the postfix(1) command is invoked with the -c option,
-# it will operate only on the specified instance. The same
-# happens when MAIL_CONFIG is specified in the process
-# environment.
-#
-# Otherwise, the postfix(1) command will operate on all
-# applicable Postfix instances.
-# MULTI-INSTANCE MANAGER EXAMPLE
+# Alternatively, the postfix(1) command accepts the instance's
+# configuration directory via the MAIL_CONFIG environment
+# variable (the -c command-line option has higher precedence).
+#
+# When no Postfix instance information is specified, the
+# postfix(1) command will operate on all applicable Postfix
+# instances.
+# MULTI-INSTANCE MANAGER IMPLEMENTATION
# .ad
# .fi
-# When the postfix(1) command is invoked without -c option
-# or MAIL_CONFIG environment setting, and non-default Postfix
-# instance directories are defined in main.cf with the
-# multi_instance_directories parameter, postfix(1) invokes
-# the command specified in main.cf with the multi_instance_wrapper
-# parameter, instead of invoking postfix-script.
+# Historically, the postfix(1) command invokes the postfix-script
+# file (currently installed in the daemon directory). This
+# file contains the commands that start or stop Postfix,
+# upgrade the configuration and so on.
+#
+# When multi-instance support is turned on, the postfix(1)
+# command needs to execute these commands for each applicable
+# Postfix instance. This multiplication of commands is handled
+# by a multi-instance manager program.
+#
+# Turning on multi-instance support goes as follows: update
+# the default Postfix instance's main.cf file, and populate
+# the multi_instance_directories parameter with the configuration
+# directory pathnames of additional Postfix instances.
+#
+# With multi-instance support turned on, the postfix(1) command
+# invokes a multi-instance manager command instead of the
+# postfix-script file. The multi-instance manager executes
+# the postfix(1) command for each applicable Postfix instance.
+# The pathname of the multi-instance manager is specified in
+# the default main.cf file with the multi_instance_wrapper
+# parameter.
#
# The multi_instance_directories and other main.cf parameters
# are listed below in the CONFIGURATION PARAMETERS section.
#
-# A useful wrapper implementation can be as simple as:
+# A useful multi-instance manager implementation can be as
+# simple as:
# .IP
# .nf
# #!/bin/sh
#
# POSTCONF=$command_directory/postconf
# POSTFIX=$command_directory/postfix
-# instance_dirs=\`$POSTCONF -h multi_instance_directories |
+# instance_dirs=\`$POSTCONF -h multi_instance_directories |
# sed 's/,/ /'\` || exit 1
#
# err=0
# case "$1" in
# stop|abort|flush|reload|drain)
# test "\`$POSTCONF -c $dir -h multi_instance_enable\`" \e
-# = yes || continue;;
+# = yes || continue;;
# start)
# test "\`$POSTCONF -c $dir -h multi_instance_enable\`" \e
-# = yes || set check;;
+# = yes || {
+# $POSTFIX -c $dir check || err=$?
+# continue
+# };;
# esac
# $POSTFIX -c $dir "$@" || err=$?
# done
# exit $err
# .fi
# .PP
+# A sample implementation, with instructions, can be found
+# in $daemon_directory/postfix-wrapper.
+#
# The postmulti(1) command implements a more sophisticated
# approach, based on a combination of C code and scripting.
-# ENABLING AN INSTANCE FOR MULTI-INSTANCE OPERATION
+# ENABLING A SPECIFIC INSTANCE FOR MULTI-INSTANCE OPERATION
# .ad
# .fi
-# To enable start/stop/etc. by a multi-instance manager, set
-# the Postfix instance's main.cf multi_instance_enable parameter
-# to "yes". This parameter has no effect on single-instance
-# operation with "postfix -c" or with a MAIL_CONFIG environment
-# setting.
-#
-# The multi-instance manager program will skip commands such
-# as "stop" and "flush" when a Postfix instance is disabled,
-# and will replace "start" by "check" so that problems will
-# still be reported even when the default instance is disabled.
+# Each Postfix instance has its own main.cf file with parameters
+# that control multi-instance operation. The most important
+# settings are discussed here.
+#
+# The setting "multi_instance_enable = yes" allows the
+# multi-instance manager to start (and stop) the corresponding
+# Postfix instance. For safety reasons, this setting is not
+# the default.
+#
+# The setting "multi_instance_enable = no" is useful for
+# manual testing. With this, the multi-instance manager will
+# not start the Postfix instance, and it will skip commands
+# such as "stop" or "flush" that require a running Postfix
+# instance. The multi-instance manager will execute commands
+# such as "check", "set-permissions" or "upgrade-configuration",
+# and it will replace "start" by "check" so that problems
+# will be reported even when the instance is disabled.
# 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.
+# such as the queue directory. See the NON-SHARED FILES
+# section below for a list of per-instance files.
#
# Before Postfix multi-instance support was implemented, the
# executables, manpages, etc., have always 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.
+#
+# Specifically, Postfix instances will not check or update
+# shared files when their config_directory value is listed
+# with the default main.cf's multi_instance_directories
+# parameter.
#
# The consequence of this approach is that the default Postfix
-# instance should be updated before any other instances.
+# instance should be checked and updated before any other
+# instances.
# MULTI-INSTANCE API SUMMARY
# .ad
# .fi
# Only the multi-instance manager implements support for the
# multi_instance_enable configuration parameter. The
-# multi-instance manager will not start Postfix instances
-# without "multi_instance_enable = yes". This allows a Postfix
-# instance to be tested by hand before it is placed under
-# control of a multi-instance manager.
+# multi-instance manager will start only Postfix instances
+# whose main.cf file has "multi_instance_enable = yes". A
+# setting of "no" allows a Postfix instance to be tested by
+# hand.
#
-# 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.
+# The postfix(1) command operates on only one Postfix instance
+# when the -c option is specified, or when MAIL_CONFIG is
+# present in the process environment. This is necessary to
+# terminate recursion.
#
# Otherwise, when the multi_instance_directories parameter
# value is non-empty, the postfix(1) command executes the
# This avoids false error messages.
#
# The multi-instance manager replaces 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 even when the default
-# instance is disabled.
+# "check" when a Postfix instance's main.cf file does not
+# have "multi_instance_enable = yes". This substitution ensures
+# that problems will be reported even when the instance is
+# disabled.
#
# No Postfix command or script will update or check shared
-# files unless it is running in the context of the default
-# Postfix instance. Therefore, the default instance should
-# be updated before any other Postfix instances.
+# files when its config_directory value is listed in the
+# default main.cf's multi_instance_directories parameter
+# value. Therefore, the default instance should be checked
+# and updated before any Postfix instances that depend on it.
#
# Set-gid commands such as postdrop(1) and postqueue(1)
# effectively append the multi_instance_directories parameter
# The location of the Postfix top-level queue directory.
# SEE ALSO
# postfix(1) Postfix control program
-# $daemon_directory/postfix-wrapper simple multi-instance manager
# postmulti(1) full-blown multi-instance manager
+# $daemon_directory/postfix-wrapper simple multi-instance manager
# LICENSE
# .ad
# .fi
-# The Secure Mailer license must be distributed with this software.
+# The Secure Mailer license must be distributed with this
+# software.
# AUTHOR(S)
# Wietse Venema
# IBM T.J. Watson Research
user_acl.c valid_mailhost_addr.c verify.c verify_clnt.c \
verp_sender.c wildcard_inet_addr.c xtext.c delivered_hdr.c \
fold_addr.c header_body_checks.c mkmap_proxy.c data_redirect.c \
- match_service.c
+ match_service.c mail_conf_nint.c
OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \
user_acl.o valid_mailhost_addr.o verify.o verify_clnt.o \
verp_sender.o wildcard_inet_addr.o xtext.o delivered_hdr.o \
fold_addr.o header_body_checks.o mkmap_proxy.o data_redirect.o \
- match_service.o
+ match_service.o mail_conf_nint.o
HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \
conv_time.h db_common.h debug_peer.h debug_process.h defer.h \
mail_conf_long.o: ../../include/vstring.h
mail_conf_long.o: mail_conf.h
mail_conf_long.o: mail_conf_long.c
+mail_conf_nint.o: ../../include/argv.h
+mail_conf_nint.o: ../../include/dict.h
+mail_conf_nint.o: ../../include/msg.h
+mail_conf_nint.o: ../../include/mymalloc.h
+mail_conf_nint.o: ../../include/stringops.h
+mail_conf_nint.o: ../../include/sys_defs.h
+mail_conf_nint.o: ../../include/vbuf.h
+mail_conf_nint.o: ../../include/vstream.h
+mail_conf_nint.o: ../../include/vstring.h
+mail_conf_nint.o: mail_conf.h
+mail_conf_nint.o: mail_conf_nint.c
mail_conf_raw.o: ../../include/msg.h
mail_conf_raw.o: ../../include/mymalloc.h
mail_conf_raw.o: ../../include/sys_defs.h
mail_params.o: mail_version.h
mail_params.o: mynetworks.h
mail_params.o: own_inet_addr.h
+mail_params.o: recipient_list.h
mail_params.o: verp_sender.h
mail_pathname.o: ../../include/attr.h
mail_pathname.o: ../../include/iostuff.h
verp_sender.o: ../../include/vbuf.h
verp_sender.o: ../../include/vstring.h
verp_sender.o: mail_params.h
+verp_sender.o: recipient_list.h
verp_sender.o: verp_sender.c
verp_sender.o: verp_sender.h
wildcard_inet_addr.o: ../../include/inet_addr_host.h
extern long get_mail_conf_long(const char *, long, long, long);
extern int get_mail_conf_bool(const char *, int);
extern int get_mail_conf_time(const char *, const char *, int, int);
+extern int get_mail_conf_nint(const char *, const char *, int, int);
extern char *get_mail_conf_raw(const char *, const char *, int, int);
extern char *get_mail_conf_str2(const char *, const char *, const char *, int, int);
extern int get_mail_conf_int2(const char *, const char *, int, int, int);
extern long get_mail_conf_long2(const char *, const char *, long, long, long);
extern int get_mail_conf_time2(const char *, const char *, int, int, int, int);
+extern int get_mail_conf_nint2(const char *, const char *, int, int, int);
/*
* Lookup with function-call defaults.
extern long get_mail_conf_long_fn(const char *, long (*) (void), long, long);
extern int get_mail_conf_bool_fn(const char *, int (*) (void));
extern int get_mail_conf_time_fn(const char *, const char *(*) (void), int, int, int);
+extern int get_mail_conf_nint_fn(const char *, const char *(*) (void), int, int);
extern char *get_mail_conf_raw_fn(const char *, const char *(*) (void), int, int);
/*
extern void set_mail_conf_bool(const char *, int);
extern void set_mail_conf_time(const char *, const char *);
extern void set_mail_conf_time_int(const char *, int);
+extern void set_mail_conf_nint(const char *, const char *);
+extern void set_mail_conf_nint_int(const char *, int);
/*
* Tables that allow us to selectively copy values from the global
char **target; /* pointer to global variable */
int min; /* min length or zero */
int max; /* max length or zero */
-} CONFIG_RAW_TABLE;
+} CONFIG_RAW_TABLE;
typedef struct {
const char *name; /* config variable name */
int max; /* upper bound or zero */
} CONFIG_TIME_TABLE;
+typedef struct {
+ const char *name; /* config variable name */
+ const char *defval; /* default value + default unit */
+ int *target; /* pointer to global variable */
+ int min; /* lower bound or zero */
+ int max; /* upper bound or zero */
+} CONFIG_NINT_TABLE;
+
extern void get_mail_conf_str_table(const CONFIG_STR_TABLE *);
extern void get_mail_conf_int_table(const CONFIG_INT_TABLE *);
extern void get_mail_conf_long_table(const CONFIG_LONG_TABLE *);
extern void get_mail_conf_bool_table(const CONFIG_BOOL_TABLE *);
extern void get_mail_conf_time_table(const CONFIG_TIME_TABLE *);
+extern void get_mail_conf_nint_table(const CONFIG_NINT_TABLE *);
extern void get_mail_conf_raw_table(const CONFIG_RAW_TABLE *);
/*
char **target; /* pointer to global variable */
int min; /* lower bound or zero */
int max; /* upper bound or zero */
-} CONFIG_RAW_FN_TABLE;
+} CONFIG_RAW_FN_TABLE;
typedef struct {
const char *name; /* config variable name */
int *target; /* pointer to global variable */
} CONFIG_BOOL_FN_TABLE;
+typedef struct {
+ const char *name; /* config variable name */
+ const char *(*defval) (void); /* default value provider */
+ int *target; /* pointer to global variable */
+ int min; /* lower bound or zero */
+ int max; /* upper bound or zero */
+} CONFIG_NINT_FN_TABLE;
+
extern void get_mail_conf_str_fn_table(const CONFIG_STR_FN_TABLE *);
extern void get_mail_conf_int_fn_table(const CONFIG_INT_FN_TABLE *);
extern void get_mail_conf_long_fn_table(const CONFIG_LONG_FN_TABLE *);
extern void get_mail_conf_bool_fn_table(const CONFIG_BOOL_FN_TABLE *);
extern void get_mail_conf_raw_fn_table(const CONFIG_RAW_FN_TABLE *);
+extern void get_mail_conf_nint_fn_table(const CONFIG_NINT_FN_TABLE *);
/* LICENSE
/* .ad
--- /dev/null
+/*++
+/* NAME
+/* mail_conf_nint 3
+/* SUMMARY
+/* integer-valued configuration parameter support
+/* SYNOPSIS
+/* #include <mail_conf.h>
+/*
+/* int get_mail_conf_nint(name, defval, min, max);
+/* const char *name;
+/* const char *defval;
+/* int min;
+/* int max;
+/*
+/* int get_mail_conf_nint_fn(name, defval, min, max);
+/* const char *name;
+/* char *(*defval)();
+/* int min;
+/* int max;
+/*
+/* void set_mail_conf_nint(name, value)
+/* const char *name;
+/* const char *value;
+/*
+/* void set_mail_conf_nint_int(name, value)
+/* const char *name;
+/* int value;
+/*
+/* void get_mail_conf_nint_table(table)
+/* const CONFIG_NINT_TABLE *table;
+/*
+/* void get_mail_conf_nint_fn_table(table)
+/* const CONFIG_NINT_TABLE *table;
+/* AUXILIARY FUNCTIONS
+/* int get_mail_conf_nint2(name1, name2, defval, min, max);
+/* const char *name1;
+/* const char *name2;
+/* int defval;
+/* int min;
+/* int max;
+/* DESCRIPTION
+/* This module implements configuration parameter support
+/* for integer values. The default value can be a macro
+/* expression ($name, ${name?value} and ${name:value}).
+/*
+/* get_mail_conf_int() looks up the named entry in the global
+/* configuration dictionary. The default value is returned
+/* when no value was found.
+/* \fImin\fR is zero or specifies a lower limit on the integer
+/* value or string length; \fImax\fR is zero or specifies an
+/* upper limit on the integer value or string length.
+/*
+/* get_mail_conf_int_fn() is similar but specifies a function that
+/* provides the default value. The function is called only
+/* when the default value is needed.
+/*
+/* set_mail_conf_int() updates the named entry in the global
+/* configuration dictionary. This has no effect on values that
+/* have been looked up earlier via the get_mail_conf_XXX() routines.
+/*
+/* get_mail_conf_int_table() and get_mail_conf_int_fn_table() initialize
+/* lists of variables, as directed by their table arguments. A table
+/* must be terminated by a null entry.
+/*
+/* get_mail_conf_int2() concatenates the two names and is otherwise
+/* identical to get_mail_conf_int().
+/* DIAGNOSTICS
+/* Fatal errors: malformed numerical value.
+/* SEE ALSO
+/* config(3) general configuration
+/* mail_conf_str(3) string-valued configuration parameters
+/* 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
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <stdio.h> /* sscanf() */
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <dict.h>
+#include <stringops.h>
+
+/* Global library. */
+
+#include "mail_conf.h"
+
+/* convert_mail_conf_nint - look up and convert integer parameter value */
+
+static int convert_mail_conf_nint(const char *name, int *intval)
+{
+ const char *strval;
+ char junk;
+
+ if ((strval = mail_conf_lookup_eval(name)) != 0) {
+ if (sscanf(strval, "%d%c", intval, &junk) != 1)
+ msg_fatal("bad numerical configuration: %s = %s", name, strval);
+ return (1);
+ }
+ return (0);
+}
+
+/* check_mail_conf_nint - validate integer value */
+
+static void check_mail_conf_nint(const char *name, int intval, int min, int max)
+{
+ if (min && intval < min)
+ msg_fatal("invalid %s parameter value %d < %d", name, intval, min);
+ if (max && intval > max)
+ msg_fatal("invalid %s parameter value %d > %d", name, intval, max);
+}
+
+/* get_mail_conf_nint - evaluate integer-valued configuration variable */
+
+int get_mail_conf_nint(const char *name, const char *defval, int min, int max)
+{
+ int intval;
+
+ if (convert_mail_conf_nint(name, &intval) == 0)
+ set_mail_conf_nint(name, defval);
+ if (convert_mail_conf_nint(name, &intval) == 0)
+ msg_panic("get_mail_conf_nint: parameter not found: %s", name);
+ check_mail_conf_nint(name, intval, min, max);
+ return (intval);
+}
+
+/* get_mail_conf_nint2 - evaluate integer-valued configuration variable */
+
+int get_mail_conf_nint2(const char *name1, const char *name2, int defval,
+ int min, int max)
+{
+ int intval;
+ char *name;
+
+ name = concatenate(name1, name2, (char *) 0);
+ if (convert_mail_conf_nint(name, &intval) == 0)
+ set_mail_conf_nint_int(name, defval);
+ if (convert_mail_conf_nint(name, &intval) == 0)
+ msg_panic("get_mail_conf_nint2: parameter not found: %s", name);
+ check_mail_conf_nint(name, intval, min, max);
+ myfree(name);
+ return (intval);
+}
+
+/* get_mail_conf_nint_fn - evaluate integer-valued configuration variable */
+
+typedef const char *(*stupid_indent_int) (void);
+
+int get_mail_conf_nint_fn(const char *name, stupid_indent_int defval,
+ int min, int max)
+{
+ int intval;
+
+ if (convert_mail_conf_nint(name, &intval) == 0)
+ set_mail_conf_nint(name, defval());
+ if (convert_mail_conf_nint(name, &intval) == 0)
+ msg_panic("get_mail_conf_nint_fn: parameter not found: %s", name);
+ check_mail_conf_nint(name, intval, min, max);
+ return (intval);
+}
+
+/* set_mail_conf_nint - update integer-valued configuration dictionary entry */
+
+void set_mail_conf_nint(const char *name, const char *value)
+{
+ mail_conf_update(name, value);
+}
+
+/* set_mail_conf_nint_int - update integer-valued configuration dictionary entry */
+
+void set_mail_conf_nint_int(const char *name, int value)
+{
+ char buf[BUFSIZ]; /* yeah! crappy code! */
+
+ sprintf(buf, "%d", value); /* yeah! more crappy code! */
+ mail_conf_update(name, buf);
+}
+
+/* get_mail_conf_nint_table - look up table of integers */
+
+void get_mail_conf_nint_table(const CONFIG_NINT_TABLE *table)
+{
+ while (table->name) {
+ table->target[0] = get_mail_conf_nint(table->name, table->defval,
+ table->min, table->max);
+ table++;
+ }
+}
+
+/* get_mail_conf_nint_fn_table - look up integers, defaults are functions */
+
+void get_mail_conf_nint_fn_table(const CONFIG_NINT_FN_TABLE *table)
+{
+ while (table->name) {
+ table->target[0] = get_mail_conf_nint_fn(table->name, table->defval,
+ table->min, table->max);
+ table++;
+ }
+}
extern char *var_smtpd_banner;
#define VAR_SMTPD_TMOUT "smtpd_timeout"
-#define DEF_SMTPD_TMOUT "300s"
+#define DEF_SMTPD_TMOUT "${stress?10}${stress:300}s"
extern int var_smtpd_tmout;
#define VAR_SMTPD_STARTTLS_TMOUT "smtpd_starttls_timeout"
extern int var_smtpd_starttls_tmout;
#define VAR_SMTPD_RCPT_LIMIT "smtpd_recipient_limit"
-#define DEF_SMTPD_RCPT_LIMIT 1000
+#define DEF_SMTPD_RCPT_LIMIT "1000"
extern int var_smtpd_rcpt_limit;
#define VAR_SMTPD_SOFT_ERLIM "smtpd_soft_error_limit"
-#define DEF_SMTPD_SOFT_ERLIM 10
+#define DEF_SMTPD_SOFT_ERLIM "10"
extern int var_smtpd_soft_erlim;
#define VAR_SMTPD_HARD_ERLIM "smtpd_hard_error_limit"
-#define DEF_SMTPD_HARD_ERLIM 20
+#define DEF_SMTPD_HARD_ERLIM "${stress?1}${stress:20}"
extern int var_smtpd_hard_erlim;
#define VAR_SMTPD_ERR_SLEEP "smtpd_error_sleep_time"
extern int var_smtpd_err_sleep;
#define VAR_SMTPD_JUNK_CMD "smtpd_junk_command_limit"
-#define DEF_SMTPD_JUNK_CMD 100
+#define DEF_SMTPD_JUNK_CMD "${stress?1}${stress:100}"
extern int var_smtpd_junk_cmd_limit;
#define VAR_SMTPD_RCPT_OVERLIM "smtpd_recipient_overshoot_limit"
#define DEFER_IF_PERMIT "defer_if_permit"
#define DEFER_IF_REJECT "defer_if_reject"
+#define VAR_REJECT_TMPF_ACT "reject_tempfail_action"
+#define DEF_REJECT_TMPF_ACT DEFER_IF_PERMIT
+extern char *var_reject_tmpf_act;
+
#define SLEEP "sleep"
#define REJECT_PLAINTEXT_SESSION "reject_plaintext_session"
#define DEF_UNK_NAME_CODE 450
extern int var_unk_name_code;
+#define VAR_UNK_NAME_TF_ACT "unknown_helo_hostname_tempfail_action"
+#define DEF_UNK_NAME_TF_ACT "$" VAR_REJECT_TMPF_ACT
+extern char *var_unk_name_tf_act;
+
#define REJECT_NON_FQDN_HELO_HOSTNAME "reject_non_fqdn_helo_hostname"
#define REJECT_NON_FQDN_HOSTNAME "reject_non_fqdn_hostname"
#define REJECT_NON_FQDN_SENDER "reject_non_fqdn_sender"
#define DEF_UNK_ADDR_CODE 450
extern int var_unk_addr_code;
+#define VAR_UNK_ADDR_TF_ACT "unknown_address_tempfail_action"
+#define DEF_UNK_ADDR_TF_ACT "$" VAR_REJECT_TMPF_ACT
+extern char *var_unk_addr_tf_act;
+
#define VAR_SMTPD_REJ_UNL_FROM "smtpd_reject_unlisted_sender"
#define DEF_SMTPD_REJ_UNL_FROM 0
extern bool var_smtpd_rej_unl_from;
#define DEF_UNV_FROM_DCODE 450
extern int var_unv_from_dcode;
+#define VAR_UNV_RCPT_TF_ACT "unverified_recipient_tempfail_action"
+#define DEF_UNV_RCPT_TF_ACT "$" VAR_REJECT_TMPF_ACT
+extern char *var_unv_rcpt_tf_act;
+
+#define VAR_UNV_FROM_TF_ACT "unverified_sender_tempfail_action"
+#define DEF_UNV_FROM_TF_ACT "$" VAR_REJECT_TMPF_ACT
+extern char *var_unv_from_tf_act;
+
#define VAR_UNV_RCPT_WHY "unverified_recipient_reject_reason"
#define DEF_UNV_RCPT_WHY ""
extern char *var_unv_rcpt_why;
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20090125"
+#define MAIL_RELEASE_DATE "20090212"
#define MAIL_VERSION_NUMBER "2.6"
#ifdef SNAPSHOT
#define MAIL_SERVER_BOOL_TABLE 3
#define MAIL_SERVER_TIME_TABLE 4
#define MAIL_SERVER_RAW_TABLE 5
+#define MAIL_SERVER_NINT_TABLE 6
#define MAIL_SERVER_PRE_INIT 10
#define MAIL_SERVER_POST_INIT 11
/* order as specified, and multiple instances of the same type
/* are allowed. Raw parameters are not subjected to $name
/* evaluation.
+/* .IP "MAIL_SERVER_NINT_TABLE (CONFIG_NINT_TABLE *)"
+/* A table with configurable parameters, to be loaded from the
+/* global Postfix configuration file. Tables are loaded in the
+/* order as specified, and multiple instances of the same type
+/* are allowed.
/* .IP "MAIL_SERVER_PRE_INIT (void *(char *service_name, char **argv))"
/* A pointer to a function that is called once
/* by the skeleton after it has read the global configuration file
case MAIL_SERVER_RAW_TABLE:
get_mail_conf_raw_table(va_arg(ap, CONFIG_RAW_TABLE *));
break;
+ case MAIL_SERVER_NINT_TABLE:
+ get_mail_conf_nint_table(va_arg(ap, CONFIG_NINT_TABLE *));
+ break;
case MAIL_SERVER_PRE_INIT:
pre_init = va_arg(ap, MAIL_SERVER_INIT_FN);
break;
/* order as specified, and multiple instances of the same type
/* are allowed. Raw parameters are not subjected to $name
/* evaluation.
+/* .IP "MAIL_SERVER_NINT_TABLE (CONFIG_NINT_TABLE *)"
+/* A table with configurable parameters, to be loaded from the
+/* global Postfix configuration file. Tables are loaded in the
+/* order as specified, and multiple instances of the same type
+/* are allowed.
/* .IP "MAIL_SERVER_PRE_INIT (void *(char *service_name, char **argv))"
/* A pointer to a function that is called once
/* by the skeleton after it has read the global configuration file
case MAIL_SERVER_RAW_TABLE:
get_mail_conf_raw_table(va_arg(ap, CONFIG_RAW_TABLE *));
break;
+ case MAIL_SERVER_NINT_TABLE:
+ get_mail_conf_nint_table(va_arg(ap, CONFIG_NINT_TABLE *));
+ break;
case MAIL_SERVER_PRE_INIT:
pre_init = va_arg(ap, MAIL_SERVER_INIT_FN);
break;
/* order as specified, and multiple instances of the same type
/* are allowed. Raw parameters are not subjected to $name
/* evaluation.
+/* .IP "MAIL_SERVER_NINT_TABLE (CONFIG_NINT_TABLE *)"
+/* A table with configurable parameters, to be loaded from the
+/* global Postfix configuration file. Tables are loaded in the
+/* order as specified, and multiple instances of the same type
+/* are allowed.
/* .IP "MAIL_SERVER_PRE_INIT (void *(char *service_name, char **argv))"
/* A pointer to a function that is called once
/* by the skeleton after it has read the global configuration file
case MAIL_SERVER_RAW_TABLE:
get_mail_conf_raw_table(va_arg(ap, CONFIG_RAW_TABLE *));
break;
+ case MAIL_SERVER_NINT_TABLE:
+ get_mail_conf_nint_table(va_arg(ap, CONFIG_NINT_TABLE *));
+ break;
case MAIL_SERVER_PRE_INIT:
pre_init = va_arg(ap, MAIL_SERVER_INIT_FN);
break;
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
TESTPROG=
MAKES = bool_table.h bool_vars.h int_table.h int_vars.h str_table.h \
- str_vars.h time_table.h time_vars.h raw_table.h raw_vars.h
+ str_vars.h time_table.h time_vars.h raw_table.h raw_vars.h \
+ nint_table.h nint_vars.h
AUTOS = auto_table.h auto_vars.h
PROG = postconf
SAMPLES = ../../conf/main.cf.default
}
}
}
+/^(static| )*(const +)?CONFIG_NINT_TABLE .*\{/,/\};/ {
+ if ($1 ~ /VAR/) {
+ print "int " substr($3,2,length($3)-2) ";" > "nint_vars.h"
+ if (++itab[$1 $2 $4 $5 $6 $7 $8 $9] == 1) {
+ print |"sed 's/[ ][ ]*/ /g' > nint_table.h"
+ }
+ }
+}
# Workaround for broken gawk versions.
#include "int_vars.h"
#include "str_vars.h"
#include "raw_vars.h"
+#include "nint_vars.h"
/*
* Manually extracted.
0,
};
+static const CONFIG_NINT_TABLE nint_table[] = {
+#include "nint_table.h"
+ 0,
+};
+
/*
* Parameters with default values obtained via function calls.
*/
const CONFIG_STR_TABLE *cst;
const CONFIG_STR_FN_TABLE *csft;
const CONFIG_RAW_TABLE *rst;
+ const CONFIG_NINT_TABLE *nst;
param_table = htable_create(100);
htable_enter(param_table, csft->name, (char *) csft);
for (rst = raw_table; rst->name; rst++)
htable_enter(param_table, rst->name, (char *) rst);
+ for (nst = nint_table; nst->name; nst++)
+ htable_enter(param_table, nst->name, (char *) nst);
}
/* show_strval - show string-valued parameter */
}
}
+/* print_nint - print new integer parameter */
+
+static void print_nint(int mode, CONFIG_NINT_TABLE * rst)
+{
+ const char *value;
+
+ if (mode & SHOW_EVAL)
+ msg_warn("parameter %s expands at run-time", rst->name);
+ mode &= ~SHOW_EVAL;
+
+ if (mode & SHOW_DEFS) {
+ show_strval(mode, rst->name, rst->defval);
+ } else {
+ value = dict_lookup(CONFIG_DICT, rst->name);
+ if ((mode & SHOW_NONDEF) == 0) {
+ if (value == 0) {
+ show_strval(mode, rst->name, rst->defval);
+ } else {
+ show_strval(mode, rst->name, value);
+ }
+ } else {
+ if (value != 0)
+ show_strval(mode, rst->name, value);
+ }
+ }
+}
+
/* print_parameter - show specific parameter */
static void print_parameter(int mode, char *ptr)
print_str_fn_2(mode, (CONFIG_STR_FN_TABLE *) ptr);
if (INSIDE(ptr, raw_table))
print_raw(mode, (CONFIG_RAW_TABLE *) ptr);
+ if (INSIDE(ptr, nint_table))
+ print_nint(mode, (CONFIG_NINT_TABLE *) ptr);
if (msg_verbose)
vstream_fflush(VSTREAM_OUT);
}
/* .IP "\fBmilter_content_timeout (300s)\fR"
/* The time limit for sending message content to a Milter (mail
/* filter) application, and for receiving the response.
-/* .IP "\fBmilter_connect_macros (see postconf -n output)\fR"
+/* .IP "\fBmilter_connect_macros (see 'postconf -d' output)\fR"
/* The macros that are sent to Milter (mail filter) applications
/* after completion of an SMTP connection.
-/* .IP "\fBmilter_helo_macros (see postconf -n output)\fR"
+/* .IP "\fBmilter_helo_macros (see 'postconf -d' output)\fR"
/* The macros that are sent to Milter (mail filter) applications
/* after the SMTP HELO or EHLO command.
-/* .IP "\fBmilter_mail_macros (see postconf -n output)\fR"
+/* .IP "\fBmilter_mail_macros (see 'postconf -d' output)\fR"
/* The macros that are sent to Milter (mail filter) applications
/* after the SMTP MAIL FROM command.
-/* .IP "\fBmilter_rcpt_macros (see postconf -n output)\fR"
+/* .IP "\fBmilter_rcpt_macros (see 'postconf -d' output)\fR"
/* The macros that are sent to Milter (mail filter) applications
/* after the SMTP RCPT TO command.
-/* .IP "\fBmilter_data_macros (see postconf -n output)\fR"
+/* .IP "\fBmilter_data_macros (see 'postconf -d' output)\fR"
/* The macros that are sent to version 4 or higher Milter (mail
/* filter) applications after the SMTP DATA command.
-/* .IP "\fBmilter_unknown_command_macros (see postconf -n output)\fR"
+/* .IP "\fBmilter_unknown_command_macros (see 'postconf -d' output)\fR"
/* The macros that are sent to version 3 or higher Milter (mail
/* filter) applications after an unknown SMTP command.
-/* .IP "\fBmilter_end_of_header_macros (see postconf -n output)\fR"
+/* .IP "\fBmilter_end_of_header_macros (see 'postconf -d' output)\fR"
/* The macros that are sent to Milter (mail filter) applications
/* after the end of the message header.
-/* .IP "\fBmilter_end_of_data_macros (see postconf -n output)\fR"
+/* .IP "\fBmilter_end_of_data_macros (see 'postconf -d' output)\fR"
/* The macros that are sent to Milter (mail filter) applications
/* after the message end-of-data.
/* GENERAL CONTENT INSPECTION CONTROLS
/* .IP "\fBsmtpd_recipient_limit (1000)\fR"
/* The maximal number of recipients that the Postfix SMTP server
/* accepts per message delivery request.
-/* .IP "\fBsmtpd_timeout (300s)\fR"
+/* .IP "\fBsmtpd_timeout (normal: 300s, stress: 10s)\fR"
/* The time limit for sending a Postfix SMTP server response and for
/* receiving a remote SMTP client request.
/* .IP "\fBsmtpd_history_flush_threshold (100)\fR"
/* The number of errors a remote SMTP client is allowed to make without
/* delivering mail before the Postfix SMTP server slows down all its
/* responses.
-/* .IP "\fBsmtpd_hard_error_limit (20)\fR"
+/* .IP "\fBsmtpd_hard_error_limit (normal: 20, stress: 1)\fR"
/* The maximal number of errors a remote SMTP client is allowed to
/* make without delivering mail.
-/* .IP "\fBsmtpd_junk_command_limit (100)\fR"
+/* .IP "\fBsmtpd_junk_command_limit (normal: 100, stress: 1)\fR"
/* The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote
/* SMTP client can send before the Postfix SMTP server starts to
/* increment the error counter with each junk command.
/* The numerical Postfix SMTP server response when a recipient address
/* probe fails due to a temporary error condition.
/* .IP "\fBunverified_sender_reject_reason (empty)\fR"
-/* When rejecting mail with reject_unverified_sender, reply with
-/* this text as the reason, instead of actual address verification
-/* details.
+/* The Postfix SMTP server's reply when rejecting mail with
+/* reject_unverified_sender.
/* .IP "\fBunverified_recipient_reject_reason (empty)\fR"
-/* When rejecting mail with reject_unverified_recipient, reply
-/* with this text as the reason, instead of actual address verification
-/* details.
+/* The Postfix SMTP server's reply when rejecting mail with
+/* reject_unverified_recipient.
+/* .IP "\fBunverified_sender_tempfail_action ($reject_tempfail_action)\fR"
+/* The Postfix SMTP server's action when reject_unverified_sender
+/* fails due to a temporary error condition.
+/* .IP "\fBunverified_recipient_tempfail_action ($reject_tempfail_action)\fR"
+/* The Postfix SMTP server's action when reject_unverified_recipient
+/* fails due to a temporary error condition.
/* ACCESS CONTROL RESPONSES
/* .ad
/* .fi
/* The numerical Postfix SMTP server response code for
/* an \fBaccess\fR(5) map "defer" action, including "defer_if_permit"
/* or "defer_if_reject".
+/* .IP "\fBreject_tempfail_action (defer_if_permit)\fR"
+/* The Postfix SMTP server's action when a reject-type restriction
+/* fails due to a temporary error condition.
+/* .IP "\fBunknown_helo_hostname_tempfail_action ($reject_tempfail_action)\fR"
+/* The Postfix SMTP server's action when reject_unknown_helo_hostname
+/* fails due to an temporary error condition.
+/* .IP "\fBunknown_address_tempfail_action ($reject_tempfail_action)\fR"
+/* The Postfix SMTP server's action when reject_unknown_sender_domain
+/* or reject_unknown_recipient_domain fail due to a temporary error
+/* condition.
/* MISCELLANEOUS CONTROLS
/* .ad
/* .fi
/* banner.
/* .IP "\fBsyslog_facility (mail)\fR"
/* The syslog facility of Postfix logging.
-/* .IP "\fBsyslog_name (postfix)\fR"
+/* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
/* The mail system name that is prepended to the process name in syslog
/* records, so that "smtpd" becomes, for example, "postfix/smtpd".
/* .PP
bool var_smtpd_client_port_log;
char *var_stress;
+char *var_reject_tmpf_act;
+char *var_unk_name_tf_act;
+char *var_unk_addr_tf_act;
+char *var_unv_rcpt_tf_act;
+char *var_unv_from_tf_act;
+
/*
* Silly little macros.
*/
int main(int argc, char **argv)
{
- static const CONFIG_INT_TABLE int_table[] = {
+ static const CONFIG_NINT_TABLE nint_table[] = {
VAR_SMTPD_RCPT_LIMIT, DEF_SMTPD_RCPT_LIMIT, &var_smtpd_rcpt_limit, 1, 0,
VAR_SMTPD_SOFT_ERLIM, DEF_SMTPD_SOFT_ERLIM, &var_smtpd_soft_erlim, 1, 0,
VAR_SMTPD_HARD_ERLIM, DEF_SMTPD_HARD_ERLIM, &var_smtpd_hard_erlim, 1, 0,
+ VAR_SMTPD_JUNK_CMD, DEF_SMTPD_JUNK_CMD, &var_smtpd_junk_cmd_limit, 1, 0,
+ 0,
+ };
+ static const CONFIG_INT_TABLE int_table[] = {
VAR_QUEUE_MINFREE, DEF_QUEUE_MINFREE, &var_queue_minfree, 0, 0,
VAR_UNK_CLIENT_CODE, DEF_UNK_CLIENT_CODE, &var_unk_client_code, 0, 0,
VAR_BAD_NAME_CODE, DEF_BAD_NAME_CODE, &var_bad_name_code, 0, 0,
VAR_REJECT_CODE, DEF_REJECT_CODE, &var_reject_code, 0, 0,
VAR_DEFER_CODE, DEF_DEFER_CODE, &var_defer_code, 0, 0,
VAR_NON_FQDN_CODE, DEF_NON_FQDN_CODE, &var_non_fqdn_code, 0, 0,
- VAR_SMTPD_JUNK_CMD, DEF_SMTPD_JUNK_CMD, &var_smtpd_junk_cmd_limit, 1, 0,
VAR_SMTPD_RCPT_OVERLIM, DEF_SMTPD_RCPT_OVERLIM, &var_smtpd_rcpt_overlim, 1, 0,
VAR_SMTPD_HIST_THRSH, DEF_SMTPD_HIST_THRSH, &var_smtpd_hist_thrsh, 1, 0,
VAR_UNV_FROM_RCODE, DEF_UNV_FROM_RCODE, &var_unv_from_rcode, 200, 599,
VAR_STRESS, DEF_STRESS, &var_stress, 0, 0,
VAR_UNV_FROM_WHY, DEF_UNV_FROM_WHY, &var_unv_from_why, 0, 0,
VAR_UNV_RCPT_WHY, DEF_UNV_RCPT_WHY, &var_unv_rcpt_why, 0, 0,
+ VAR_REJECT_TMPF_ACT, DEF_REJECT_TMPF_ACT, &var_reject_tmpf_act, 1, 0,
+ VAR_UNK_NAME_TF_ACT, DEF_UNK_NAME_TF_ACT, &var_unk_name_tf_act, 1, 0,
+ VAR_UNK_ADDR_TF_ACT, DEF_UNK_ADDR_TF_ACT, &var_unk_addr_tf_act, 1, 0,
+ VAR_UNV_RCPT_TF_ACT, DEF_UNV_RCPT_TF_ACT, &var_unv_rcpt_tf_act, 1, 0,
+ VAR_UNV_FROM_TF_ACT, DEF_UNV_FROM_TF_ACT, &var_unv_from_tf_act, 1, 0,
0,
};
static const CONFIG_RAW_TABLE raw_table[] = {
* Pass control to the single-threaded service skeleton.
*/
single_server_main(argc, argv, smtpd_service,
+ MAIL_SERVER_NINT_TABLE, nint_table,
MAIL_SERVER_INT_TABLE, int_table,
MAIL_SERVER_STR_TABLE, str_table,
MAIL_SERVER_RAW_TABLE, raw_table,
static int check_recipient_rcpt_maps(SMTPD_STATE *, const char *);
static int check_rcpt_maps(SMTPD_STATE *, const char *, const char *);
+ /*
+ * Tempfail actions;
+ */
+static int unk_name_tf_act;
+static int unk_addr_tf_act;
+static int unv_rcpt_tf_act;
+static int unv_from_tf_act;
+
/*
* YASLM.
*/
* permit-style restriction fails. Otherwise, we could reject legitimate
* mail.
*/
-static void PRINTFLIKE(5, 6) defer_if(SMTPD_DEFER *, int, int, const char *, const char *,...);
+static int PRINTFLIKE(5, 6) defer_if(SMTPD_DEFER *, int, int, const char *, const char *,...);
static int PRINTFLIKE(5, 6) smtpd_check_reject(SMTPD_STATE *, int, int, const char *, const char *,...);
#define DEFER_IF_REJECT2(state, class, code, dsn, fmt, a1, a2) \
defer_if(&(state)->defer_if_reject, (class), (code), (dsn), (fmt), (a1), (a2), (a3))
#define DEFER_IF_REJECT4(state, class, code, dsn, fmt, a1, a2, a3, a4) \
defer_if(&(state)->defer_if_reject, (class), (code), (dsn), (fmt), (a1), (a2), (a3), (a4))
-#define DEFER_IF_PERMIT2(state, class, code, dsn, fmt, a1, a2) do { \
- if ((state)->warn_if_reject == 0) \
- defer_if(&(state)->defer_if_permit, (class), (code), (dsn), (fmt), (a1), (a2)); \
- else \
- (void) smtpd_check_reject((state), (class), (code), (dsn), (fmt), (a1), (a2)); \
- } while (0)
-#define DEFER_IF_PERMIT3(state, class, code, dsn, fmt, a1, a2, a3) do { \
- if ((state)->warn_if_reject == 0) \
- defer_if(&(state)->defer_if_permit, (class), (code), (dsn), (fmt), (a1), (a2), (a3)); \
- else \
- (void) smtpd_check_reject((state), (class), (code), (dsn), (fmt), (a1), (a2), (a3)); \
- } while (0)
-#define DEFER_IF_PERMIT4(state, class, code, dsn, fmt, a1, a2, a3, a4) do { \
- if ((state)->warn_if_reject == 0) \
- defer_if(&(state)->defer_if_permit, (class), (code), (dsn), (fmt), (a1), (a2), (a3), (a4)); \
- else \
- (void) smtpd_check_reject((state), (class), (code), (dsn), (fmt), (a1), (a2), (a3), (a4)); \
- } while (0)
+
+#define DEFER_EXPLICIT 1
+
+#define DEFER_IF_PERMIT2(type, state, class, code, dsn, fmt, a1, a2) \
+ (((state)->warn_if_reject == 0 && (type) != 0) ? \
+ defer_if(&(state)->defer_if_permit, (class), (code), (dsn), (fmt), (a1), (a2)) \
+ : \
+ smtpd_check_reject((state), (class), (code), (dsn), (fmt), (a1), (a2)))
+#define DEFER_IF_PERMIT3(type, state, class, code, dsn, fmt, a1, a2, a3) \
+ (((state)->warn_if_reject == 0 && (type) != 0) ? \
+ defer_if(&(state)->defer_if_permit, (class), (code), (dsn), (fmt), (a1), (a2), (a3)) \
+ : \
+ smtpd_check_reject((state), (class), (code), (dsn), (fmt), (a1), (a2), (a3)))
+#define DEFER_IF_PERMIT4(type, state, class, code, dsn, fmt, a1, a2, a3, a4) \
+ (((state)->warn_if_reject == 0 && (type) != 0) ? \
+ defer_if(&(state)->defer_if_permit, (class), (code), (dsn), (fmt), (a1), (a2), (a3), (a4)) \
+ : \
+ smtpd_check_reject((state), (class), (code), (dsn), (fmt), (a1), (a2), (a3), (a4)))
/*
* Cached RBL lookup state.
DEFER_IF_PERMIT,
0,
};
+ static NAME_CODE tempfail_actions[] = {
+ DEFER_ALL, 0,
+ DEFER_IF_PERMIT, 1,
+ 0, -1,
+ };
/*
* Pre-open access control lists before going to jail.
*/
local_rewrite_clients = smtpd_check_parse(SMTPD_CHECK_PARSE_MAPS,
var_local_rwr_clients);
+
+ /*
+ * Tempfail_actions.
+ *
+ * XXX This name-to-number mapping should be encapsulated in a separate
+ * mail_conf_name_code.c module.
+ */
+ if ((unk_name_tf_act = name_code(tempfail_actions, NAME_CODE_FLAG_NONE,
+ var_unk_name_tf_act)) < 0)
+ msg_fatal("bad configuration: %s = %s",
+ VAR_UNK_NAME_TF_ACT, var_unk_name_tf_act);
+ if ((unk_addr_tf_act = name_code(tempfail_actions, NAME_CODE_FLAG_NONE,
+ var_unk_addr_tf_act)) < 0)
+ msg_fatal("bad configuration: %s = %s",
+ VAR_UNK_ADDR_TF_ACT, var_unk_addr_tf_act);
+ if ((unv_rcpt_tf_act = name_code(tempfail_actions, NAME_CODE_FLAG_NONE,
+ var_unv_rcpt_tf_act)) < 0)
+ msg_fatal("bad configuration: %s = %s",
+ VAR_UNV_RCPT_TF_ACT, var_unv_rcpt_tf_act);
+ if ((unv_from_tf_act = name_code(tempfail_actions, NAME_CODE_FLAG_NONE,
+ var_unv_from_tf_act)) < 0)
+ msg_fatal("bad configuration: %s = %s",
+ VAR_UNV_FROM_TF_ACT, var_unv_from_tf_act);
+ if (msg_verbose) {
+ msg_info("%s = %s", VAR_UNK_NAME_TF_ACT, tempfail_actions[unk_name_tf_act].name);
+ msg_info("%s = %s", VAR_UNK_ADDR_TF_ACT, tempfail_actions[unk_addr_tf_act].name);
+ msg_info("%s = %s", VAR_UNV_RCPT_TF_ACT, tempfail_actions[unv_rcpt_tf_act].name);
+ msg_info("%s = %s", VAR_UNV_FROM_TF_ACT, tempfail_actions[unv_from_tf_act].name);
+ }
}
/* log_whatsup - log as much context as we have */
/* defer_if - prepare to change our mind */
-static void defer_if(SMTPD_DEFER *defer, int error_class,
- int code, const char *dsn,
- const char *fmt,...)
+static int defer_if(SMTPD_DEFER *defer, int error_class,
+ int code, const char *dsn,
+ const char *fmt,...)
{
va_list ap;
vstring_vsprintf(defer->reason, fmt, ap);
va_end(ap);
}
+ return (SMTPD_CHECK_DUNNO);
}
/* reject_dict_retry - reject with temporary failure if dict lookup fails */
"Malformed DNS server reply" :
"Host not found"));
else
- DEFER_IF_PERMIT2(state, MAIL_ERROR_POLICY,
- 450, "4.7.1",
- "<%s>: %s rejected: Host not found",
- reply_name, reply_class);
+ return (DEFER_IF_PERMIT2(unk_name_tf_act, state, MAIL_ERROR_POLICY,
+ 450, "4.7.1",
+ "<%s>: %s rejected: Host not found",
+ reply_name, reply_class));
}
return (SMTPD_CHECK_DUNNO);
}
"Malformed DNS server reply" :
"Domain not found"));
else
- DEFER_IF_PERMIT2(state, MAIL_ERROR_POLICY,
+ return (DEFER_IF_PERMIT2(unk_addr_tf_act, state, MAIL_ERROR_POLICY,
450, strcmp(reply_class, SMTPD_NAME_SENDER) == 0 ?
- "4.1.8" : "4.1.2",
- "<%s>: %s rejected: Domain not found",
- reply_name, reply_class);
+ "4.1.8" : "4.1.2",
+ "<%s>: %s rejected: Domain not found",
+ reply_name, reply_class));
}
return (SMTPD_CHECK_DUNNO);
}
static int reject_unverified_address(SMTPD_STATE *state, const char *addr,
const char *reply_name, const char *reply_class,
int unv_addr_dcode, int unv_addr_rcode,
+ int unv_addr_tf_act,
const char *alt_reply)
{
const char *myname = "reject_unverified_address";
}
if (verify_status != VRFY_STAT_OK) {
msg_warn("%s service failure", var_verify_service);
- DEFER_IF_PERMIT2(state, MAIL_ERROR_POLICY,
- 450, strcmp(reply_class, SMTPD_NAME_SENDER) == 0 ?
- SND_DSN : "4.1.1",
- "<%s>: %s rejected: address verification problem",
- reply_name, reply_class);
+ rqst_status =
+ DEFER_IF_PERMIT2(unv_addr_tf_act, state, MAIL_ERROR_POLICY,
+ 450, strcmp(reply_class, SMTPD_NAME_SENDER) == 0 ?
+ SND_DSN : "4.1.1",
+ "<%s>: %s rejected: address verification problem",
+ reply_name, reply_class);
} else {
switch (rcpt_status) {
default:
case 2:
break;
case 4:
- DEFER_IF_PERMIT3(state, MAIL_ERROR_POLICY,
+ rqst_status =
+ DEFER_IF_PERMIT3(unv_addr_tf_act, state, MAIL_ERROR_POLICY,
450, strcmp(reply_class, SMTPD_NAME_SENDER) == 0 ?
- SND_DSN : "4.1.1",
- "<%s>: %s rejected: unverified address: %.250s",
- reply_name, reply_class, STR(why));
+ SND_DSN : "4.1.1",
+ "<%s>: %s rejected: unverified address: %.250s",
+ reply_name, reply_class, STR(why));
break;
default:
if (reject_code != 0)
*/
if (STREQUAL(value, DEFER_IF_PERMIT, cmd_len)) {
dsn_split(&dp, "4.7.1", cmd_text);
- DEFER_IF_PERMIT3(state, MAIL_ERROR_POLICY,
- var_map_defer_code,
- smtpd_dsn_fix(DSN_STATUS(dp.dsn), reply_class),
- "<%s>: %s rejected: %s",
- reply_name, reply_class,
- *dp.text ? dp.text : "Service unavailable");
- return (SMTPD_CHECK_DUNNO);
+ return (DEFER_IF_PERMIT3(DEFER_EXPLICIT, state, MAIL_ERROR_POLICY,
+ var_map_defer_code,
+ smtpd_dsn_fix(DSN_STATUS(dp.dsn), reply_class),
+ "<%s>: %s rejected: %s",
+ reply_name, reply_class,
+ *dp.text ? dp.text : "Service unavailable"));
}
/*
status = check_policy_service(state, *++cpp, reply_name,
reply_class, def_acl);
} else if (strcasecmp(name, DEFER_IF_PERMIT) == 0) {
- DEFER_IF_PERMIT2(state, MAIL_ERROR_POLICY,
- 450, "4.7.0",
+ status = DEFER_IF_PERMIT2(DEFER_EXPLICIT, state, MAIL_ERROR_POLICY,
+ 450, "4.7.0",
"<%s>: %s rejected: defer_if_permit requested",
- reply_name, reply_class);
+ reply_name, reply_class);
} else if (strcasecmp(name, DEFER_IF_REJECT) == 0) {
DEFER_IF_REJECT2(state, MAIL_ERROR_POLICY,
450, "4.7.0",
status = reject_unverified_address(state, state->sender,
state->sender, SMTPD_NAME_SENDER,
var_unv_from_dcode, var_unv_from_rcode,
+ unv_from_tf_act,
var_unv_from_why);
} else if (strcasecmp(name, REJECT_NON_FQDN_SENDER) == 0) {
if (state->sender && *state->sender)
status = reject_unverified_address(state, state->recipient,
state->recipient, SMTPD_NAME_RECIPIENT,
var_unv_rcpt_dcode, var_unv_rcpt_rcode,
+ unv_rcpt_tf_act,
var_unv_rcpt_why);
}
char *var_unv_from_why;
char *var_unv_rcpt_why;
char *var_stress;
+char *var_unk_name_tf_act;
+char *var_unk_addr_tf_act;
+char *var_unv_rcpt_tf_act;
+char *var_unv_from_tf_act;
typedef struct {
char *name;
VAR_UNV_FROM_WHY, DEF_UNV_FROM_WHY, &var_unv_from_why,
VAR_UNV_RCPT_WHY, DEF_UNV_RCPT_WHY, &var_unv_rcpt_why,
VAR_STRESS, DEF_STRESS, &var_stress,
+ /* XXX Can't use ``$name'' type default values below. */
+ VAR_UNK_NAME_TF_ACT, DEF_REJECT_TMPF_ACT, &var_unk_name_tf_act,
+ VAR_UNK_ADDR_TF_ACT, DEF_REJECT_TMPF_ACT, &var_unk_addr_tf_act,
+ VAR_UNV_RCPT_TF_ACT, DEF_REJECT_TMPF_ACT, &var_unv_rcpt_tf_act,
+ VAR_UNV_FROM_TF_ACT, DEF_REJECT_TMPF_ACT, &var_unv_from_tf_act,
0,
};
#include <vstring_vstream.h>
#include <name_mask.h>
#include <argv.h>
+#include <myaddrinfo.h>
/* Global library. */
unsigned int sec_props; /* Postfix mechanism filter */
char *mechanism_list; /* filtered mechanism list */
ARGV *mechanism_argv; /* ditto */
+ MAI_HOSTADDR_STR server_addr; /* local IP address */
+ MAI_HOSTADDR_STR client_addr; /* remote IP address */
} XSASL_DOVECOT_SERVER;
/*
unsigned int major_version, minor_version;
int fd, success;
int sec_props;
+ const char *path;
if (msg_verbose)
msg_info("%s: Connecting", myname);
- if ((fd = unix_connect(xp->socket_path, BLOCKING, AUTH_TIMEOUT)) < 0) {
+ /*
+ * Not documented, but necessary for testing.
+ */
+ path = xp->socket_path;
+ if (strncmp(path, "inet:", 5) == 0) {
+ fd = inet_connect(path + 5, BLOCKING, AUTH_TIMEOUT);
+ } else {
+ if (strncmp(path, "unix:", 5) == 0)
+ path += 5;
+ fd = unix_connect(path, BLOCKING, AUTH_TIMEOUT);
+ }
+ if (fd < 0) {
msg_warn("SASL: Connect to %s failed: %m", xp->socket_path);
return (-1);
}
/* xsasl_dovecot_server_create - create server instance */
static XSASL_SERVER *xsasl_dovecot_server_create(XSASL_SERVER_IMPL *impl,
- VSTREAM *unused_stream,
+ VSTREAM *stream,
const char *service,
const char *realm,
const char *sec_props)
{
const char *myname = "xsasl_dovecot_server_create";
XSASL_DOVECOT_SERVER *server;
+ struct sockaddr_storage ss;
+ struct sockaddr *sa = (struct sockaddr *) & ss;
+ SOCKADDR_SIZE salen;
if (msg_verbose)
msg_info("%s: SASL service=%s, realm=%s",
name_mask_opt(myname, xsasl_dovecot_conf_sec_props,
sec_props, NAME_MASK_ANY_CASE | NAME_MASK_FATAL);
+ /*
+ * XXX This is not the right place: it ignores client overrides with the
+ * XCLIENT command.
+ */
+ salen = sizeof(ss);
+ if (getpeername(vstream_fileno(stream), sa, &salen) < 0
+ || sockaddr_to_hostaddr(sa, salen, &server->client_addr, 0, 0) != 0)
+ server->client_addr.buf[0] = 0;
+ salen = sizeof(ss);
+ if (getsockname(vstream_fileno(stream), sa, &salen) < 0
+ || sockaddr_to_hostaddr(sa, salen, &server->server_addr, 0, 0) != 0)
+ server->server_addr.buf[0] = 0;
+
return (&server->xsasl);
}
/* send the request */
server->last_request_id = ++server->impl->request_id_counter;
vstream_fprintf(server->impl->sasl_stream,
- "AUTH\t%u\t%s\tservice=%s\tnologin",
+ "AUTH\t%u\t%s\tservice=%s\tnologin\tlip=%s\trip=%s",
server->last_request_id, sasl_method,
- server->service);
+ server->service, server->server_addr.buf,
+ server->client_addr.buf);
if (init_response) {
/*