than $line_length_limit, causing postdrop to reject the
mail. Diagnosis by Victor Duchovni. File: sendmail/sendmail.c.
+20050202
+
+ Cleanup: explicit Makefile targets for "make package" and
+ "make non-interactive-package" to create ready-to-install
+ packages for distribution to other systems. Added extra
+ sanity checks to prevent attempts to overwrite your running
+ Postfix instance. Files: Makefile.in, proto/PACKAGE_README.
+
+ Cleanup: when bounce_queue_lifetime > maximal_queue_lifetime,
+ it is adjusted to maximal_queue_lifetime, and a warning is
+ logged. Files: *qmgr/qmgr.c.
+
+ Cleanup: trivial-rewrite detects changes to maps even in
+ the absence of connection events. File: trivial-rewrite.c.
+
Open problems:
- Low: document regexp usage in aliases and other sensitive
- maps.
+ Med: SunOS 4 has no strtoul(). Instead of sprintf/strtoul()
+ use hexen/decode() for the process generation number.
Low: pointers to postfinger and saslfinger. postfinger
is now bundled.
really try all the possibilities that one might expect to
be tried. For now, this gotcha is documented in access(5).
- Low: cap bounce queue life time with regular queue life
- time.
-
Med: the TLS certificate verification depth parameters
never worked.
Med: eliminate the tls_info data structure.
- Low: something to alias sdbm:name into btree:name?
-
Med: implement ${name[?:]value} in main.cf or update the
postconf(5) manual.
Low: should the Delivered-To: test in local(8) be configurable?
- Low: document propagate_unmatched_extensions in aliases(5)
- etc.
-
Low: make mail_addr_find() lookup configurable.
- Low: anvil(8) should log cache peak size, like scache(8).
-
Low: update events.c so that 1-second timer requests do
not suffer from rounding errors. This is needed for 1-second
SMTP session caching time limits.
- Low: trivial-rewrite should examine the map change status
- every N seconds.
-
Low: per-sender resolver personalities?
Low: configurable internal/system locking method.
install: update
$(SHELL) postfix-install
+package: update
+ $(SHELL) postfix-install -package
+
upgrade: update
$(SHELL) postfix-install -non-interactive
+non-interactive-package: update
+ $(SHELL) postfix-install -non-interactive -package
+
depend clean:
set -e; for i in $(DIRS); do \
(set -e; echo "[$$i]"; cd $$i; $(MAKE) $@) || exit 1; \
G\bGe\ben\bne\ber\bra\bal\bl d\bdi\bis\bst\btr\bri\bib\bbu\but\bti\bio\bon\bns\bs:\b: p\bpl\ble\bea\bas\bse\be p\bpr\bro\bov\bvi\bid\bde\be a\ba s\bsm\bma\bal\bll\bl d\bde\bef\bfa\bau\bul\blt\bt m\bma\bai\bin\bn.\b.c\bcf\bf f\bfi\bil\ble\be
The installed main.cf file must be small. PLEASE resist the temptation to list
-all 300+ parameters in the main.cf file. Postfix is supposed to be easy to
-configure. Listing all 300+ in main.cf defeats the purpose. It is an invitation
+all 400+ parameters in the main.cf file. Postfix is supposed to be easy to
+configure. Listing all 400+ in main.cf defeats the purpose. It is an invitation
for hobbyists to make random changes without understanding what they do, and
gets them into endless trouble.
First compile Postfix. After successful compilation, execute:
- % sh postfix-install
+ % m\bma\bak\bke\be p\bpa\bac\bck\bka\bag\bge\be
+
+With Postfix versions before 2.2 you must invoke the post-install script
+directly (% s\bsh\bh p\bpo\bos\bst\bt-\b-i\bin\bns\bst\bta\bal\bll\bl).
You will be prompted for installation parameters. Specify an install_root
directory other than /. The mail_owner and setgid_group installation parameter
If you want to fully automate this process, specify all the non-default
installation parameters on the command line:
- % sh postfix-install -non-interactive
- install_root=/some/where ...
+ % m\bma\bak\bke\be n\bno\bon\bn-\b-i\bin\bnt\bte\ber\bra\bac\bct\bti\biv\bve\be-\b-p\bpa\bac\bck\bka\bag\bge\be i\bin\bns\bst\bta\bal\bll\bl_\b_r\bro\boo\bot\bt=\b=/\b/s\bso\bom\bme\be/\b/w\bwh\bhe\ber\bre\be...
+
+With Postfix versions before 2.2 you must invoke the post-install script
+directly (% s\bsh\bh p\bpo\bos\bst\bt-\b-i\bin\bns\bst\bta\bal\bll\bl -\b-n\bno\bon\bn-\b-i\bin\bnt\bte\ber\bra\bac\bct\bti\biv\bve\be i\bin\bns\bst\bta\bal\bll\bl_\b_r\bro\boo\bot\bt.\b..\b..\b.).
B\bBe\beg\bgi\bin\bn S\bSe\bec\bcu\bur\bri\bit\bty\by A\bAl\ble\ber\brt\bt
and change the patchlevel and the release date. Patches are never
issued for snapshot releases.
-Incompatible changes with snapshot Postfix-2.2-20050131
+Incompatible changes with snapshot Postfix-2.2-20050202
=======================================================
Postfix rewrites message header addresses only in mail that originates
from the local machine. Specify "local_header_rewrite_clients =
static:all" to get the old behavior of Postfix 2.1 and earlier.
+Major changes with snapshot Postfix-2.2-20050202
+================================================
+
+To create a ready-to-install package for distribution to other
+systems use "make package" or "make non-interactive-package",
+instead of invoking the postfix-install script by hand (which is
+deprecated). See the PACKAGE_README file for details.
+
+New "permit_inet_interfaces" access restriction to allow access
+from local IP addresses only. This is used for the default, purist,
+setting of local_header_rewrite_clients.
+
+New "sleep time-in-seconds" pseudo access restriction to block
+zombie clients with reject_unauthorized_pipelining before the
+Postfix SMTP server sends the SMTP greeting. See postconf(5)
+for example.
+
+Safety: Postfix no longer tries to send mail to the fallback_relay
+when the local machine is MX host for the mail destination. See
+postconf(5) description of fallback_relay for details.
+
Incompatible changes with snapshot Postfix-2.2-20050117
=======================================================
# user+foo), the search is repeated for the unextended
# address (e.g., user).
#
+# The propagate_unmatched_extensions parameter controls
+# whether an unmatched address extension (+foo) is propa-
+# gated to the result of table lookup.
+#
+# SECURITY
+# The local(8) delivery agent disallows regular expression
+# substitution of $1 etc. in alias_maps, because that would
+# open a security hole.
+#
+# The local(8) delivery agent will silently ignore requests
+# to use the proxymap(8) server within alias_maps. Instead
+# it will open the table directly. Before Postfix version
+# 2.2, the local(8) delivery agent will terminate with a
+# fatal error.
+#
# CONFIGURATION PARAMETERS
# The following main.cf parameters are especially relevant.
# The text below provides only a parameter summary. See
# the right-hand side of the owner alias, instead
# using of the left-hand side address.
#
+# propagate_unmatched_extensions
+# A list of address rewriting or forwarding mecha-
+# nisms that propagate an address extension from the
+# original address to the result. Specify zero or
+# more of canonical, virtual, alias, forward, or
+# include.
+#
# owner_request_special
# Give special treatment to owner-listname and list-
# name-request addresses.
# Delimiter that separates recipients from address
# extensions.
#
-# BUGS
-# Regular expression alias lookup tables are allowed, but
-# substitution of $1 etc. is forbidden because that would
-# open a security loophole.
-#
# STANDARDS
# RFC 822 (ARPA Internet Text Messages)
#
file</h2>
<p> The installed main.cf file must be small. PLEASE resist the
-temptation to list all 300+ parameters in the main.cf file. Postfix
-is supposed to be easy to configure. Listing all 300+ in main.cf
+temptation to list all 400+ parameters in the main.cf file. Postfix
+is supposed to be easy to configure. Listing all 400+ in main.cf
defeats the purpose. It is an invitation for hobbyists to make
random changes without understanding what they do, and gets them
into endless trouble. </p>
<p> First compile Postfix. After successful compilation, execute:
</p>
-<blockquote> <pre> % sh postfix-install </pre> </blockquote>
+<blockquote> <pre> % <b>make package</b> </pre>
+</blockquote>
+
+<p> With Postfix versions before 2.2 you must invoke the post-install
+script directly (<tt>% <b>sh post-install</b></tt>). </p>
<p> You will be prompted for installation parameters. Specify an
install_root directory other than /. The <a href="postconf.5.html#mail_owner">mail_owner</a> and <a href="postconf.5.html#setgid_group">setgid_group</a>
<p> If you want to fully automate this process, specify all the
non-default installation parameters on the command line: </p>
-<blockquote> <pre> % sh postfix-install -non-interactive
-install_root=/some/where ... </pre> </blockquote>
+<blockquote>
+<pre> % <b>make non-interactive-package install_root=/some/where</b>...
+</pre> </blockquote>
+
+<p> With Postfix versions before 2.2 you must invoke the post-install
+script directly (<tt>% <b>sh post-install -non-interactive
+install_root...</b></tt>). </p>
<h2>Begin Security Alert</h2>
<i>user+foo</i>), the search is repeated for the unextended
address (e.g., <i>user</i>).
+ The <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a></b> parameter controls
+ whether an unmatched address extension (<i>+foo</i>) is propa-
+ gated to the result of table lookup.
+
+<b>SECURITY</b>
+ The <a href="local.8.html"><b>local</b>(8)</a> delivery agent disallows regular expression
+ substitution of $1 etc. in <b><a href="postconf.5.html#alias_maps">alias_maps</a></b>, because that would
+ open a security hole.
+
+ The <a href="local.8.html"><b>local</b>(8)</a> delivery agent will silently ignore requests
+ to use the <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server within <b><a href="postconf.5.html#alias_maps">alias_maps</a></b>. Instead
+ it will open the table directly. Before Postfix version
+ 2.2, the <a href="local.8.html"><b>local</b>(8)</a> delivery agent will terminate with a
+ fatal error.
+
<b>CONFIGURATION PARAMETERS</b>
The following <b>main.cf</b> parameters are especially relevant.
The text below provides only a parameter summary. See
<b><a href="postconf.5.html#alias_database">alias_database</a></b>
List of alias databases that are updated by the
- <a href="newaliases.1.html">newaliases(1)</a> command.
+ <a href="newaliases.1.html"><b>newaliases</b>(1)</a> command.
<b><a href="postconf.5.html#alias_maps">alias_maps</a></b>
- List of alias databases queried by the <a href="local.8.html">local(8)</a>
+ List of alias databases queried by the <a href="local.8.html"><b>local</b>(8)</a>
delivery agent.
<b><a href="postconf.5.html#allow_mail_to_commands">allow_mail_to_commands</a></b>
the right-hand side of the owner alias, instead
using of the left-hand side address.
+ <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a></b>
+ A list of address rewriting or forwarding mecha-
+ nisms that propagate an address extension from the
+ original address to the result. Specify zero or
+ more of <b>canonical</b>, <b>virtual</b>, <b>alias</b>, <b>forward</b>, or
+ <b>include</b>.
+
<b><a href="postconf.5.html#owner_request_special">owner_request_special</a></b>
Give special treatment to <b>owner-</b><i>listname</i> and <i>list-</i>
<i>name</i><b>-request</b> addresses.
Delimiter that separates recipients from address
extensions.
-<b>BUGS</b>
- Regular expression alias lookup tables are allowed, but
- substitution of $1 etc. is forbidden because that would
- open a security loophole.
-
<b>STANDARDS</b>
<a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a> (ARPA Internet Text Messages)
the postmaster is notified of bounces and of other trou-
ble.
+<b>SECURITY</b>
+ The <a href="local.8.html"><b>local</b>(8)</a> delivery agent needs a dual personality 1) to
+ access the private Postfix queue and IPC mechanisms, 2) to
+ impersonate the recipient and deliver to recipient-speci-
+ fied files or commands. It is therefore security sensi-
+ tive.
+
+ The <a href="local.8.html"><b>local</b>(8)</a> delivery agent disallows regular expression
+ substitution of $1 etc. in <b><a href="postconf.5.html#alias_maps">alias_maps</a></b>, because that would
+ open a security hole.
+
+ The <a href="local.8.html"><b>local</b>(8)</a> delivery agent will silently ignore requests
+ to use the <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server within <b><a href="postconf.5.html#alias_maps">alias_maps</a></b>. Instead
+ it will open the table directly. Before Postfix version
+ 2.2, the <a href="local.8.html"><b>local</b>(8)</a> delivery agent will terminate with a
+ fatal error.
+
<b>BUGS</b>
For security reasons, the message delivery status of
external commands or of external files is never check-
<b>CONFIGURATION PARAMETERS</b>
Changes to <b>main.cf</b> are picked up automatically, as
- <a href="local.8.html">local(8)</a> processes run for only a limited amount of time.
+ <a href="local.8.html"><b>local</b>(8)</a> processes run for only a limited amount of time.
Use the command "<b>postfix reload</b>" to speed up a change.
The text below provides only a parameter summary. See
Obsolete SUN mailtool compatibility feature.
<b>DELIVERY METHOD CONTROLS</b>
- The precedence of <a href="local.8.html">local(8)</a> delivery methods from high to
+ The precedence of <a href="local.8.html"><b>local</b>(8)</a> delivery methods from high to
low is: aliases, .forward files, <a href="postconf.5.html#mailbox_transport">mailbox_transport</a>, <a href="postconf.5.html#mailbox_command_maps">mail</a>-
<a href="postconf.5.html#mailbox_command_maps">box_command_maps</a>, <a href="postconf.5.html#mailbox_command">mailbox_command</a>, <a href="postconf.5.html#home_mailbox">home_mailbox</a>,
<a href="postconf.5.html#mail_spool_directory">mail_spool_directory</a>, <a href="postconf.5.html#fallback_transport">fallback_transport</a> and <a href="postconf.5.html#luser_relay">luser_relay</a>.
run "<b>newaliases</b>" to build the necessary DBM or DB file.
</p>
+<p>
+The <a href="local.8.html">local(8)</a> delivery agent disallows regular expression substitution
+of $1 etc. in <a href="postconf.5.html#alias_maps">alias_maps</a>, because that would open a security hole.
+</p>
+
+<p>
+The <a href="local.8.html">local(8)</a> delivery agent will silently ignore requests to use
+the <a href="proxymap.8.html">proxymap(8)</a> server within <a href="postconf.5.html#alias_maps">alias_maps</a>. Instead it will open the
+table directly. Before Postfix version 2.2, the <a href="local.8.html">local(8)</a> delivery
+agent will terminate with a fatal error.
+</p>
+
<p>
Examples:
</p>
<a href="postconf.5.html#reject_code">reject_code</a> configuration parameter specifies the response code to
rejected requests (default: 554).</dd>
+<dt><b><a name="sleep">sleep <i>seconds</i></a></b></dt>
+
+<dd>Pause for the specified number of seconds and proceed with
+the next restriction in the list, if any. This may stop zombie
+mail when used as: </dd>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ <a href="postconf.5.html#smtpd_client_restrictions">smtpd_client_restrictions</a> =
+ sleep 1, <a href="postconf.5.html#reject_unauth_pipelining">reject_unauth_pipelining</a>
+ <a href="postconf.5.html#smtpd_delay_reject">smtpd_delay_reject</a> = no
+</pre>
+</blockquote>
+
<dt><b><a name="warn_if_reject">warn_if_reject</a></b></dt>
<dd>Change the meaning of the next restriction, so that it logs
information are adequately protected. This program is not
designed to run chrooted.
+ The virtual delivery agent disallows regular expression
+ substitution of $1 etc. in regular expression lookup
+ tables, because that would open a security hole.
+
+ The virtual delivery agent will silently ignore requests
+ to use the <a href="proxymap.8.html">proxymap(8)</a> server. Instead it will open the
+ table directly. Before Postfix version 2.2, the virtual
+ delivery agent will terminate with a fatal error.
+
<b>STANDARDS</b>
<a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a> (ARPA Internet Text Messages)
recipient is over disk quota. In all other cases, mail for
an existing recipient is deferred and a warning is logged.
- Problems and transactions are logged to <b>syslogd</b>(8). Cor-
- rupted message files are marked so that the queue manager
+ Problems and transactions are logged to <b>syslogd</b>(8). Cor-
+ rupted message files are marked so that the queue manager
can move them to the <b>corrupt</b> queue afterwards.
- Depending on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b> parameter,
- the postmaster is notified of bounces and of other trou-
+ Depending on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b> parameter,
+ the postmaster is notified of bounces and of other trou-
ble.
<b>BUGS</b>
- This delivery agent supports address extensions in email
+ This delivery agent supports address extensions in email
addresses and in lookup table keys, but does not propagate
- address extension information to the result of table
+ address extension information to the result of table
lookup.
Postfix should have lookup tables that can return multiple
- result attributes. In order to avoid the inconvenience of
+ result attributes. In order to avoid the inconvenience of
maintaining three tables, use an LDAP or MYSQL database.
<b>CONFIGURATION PARAMETERS</b>
- Changes to <b>main.cf</b> are picked up automatically, as vir-
- tual(8) processes run for only a limited amount of time.
+ Changes to <b>main.cf</b> are picked up automatically, as vir-
+ tual(8) processes run for only a limited amount of time.
Use the command "<b>postfix reload</b>" to speed up a change.
- 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 including examples.
<b>MAILBOX DELIVERY CONTROLS</b>
<b><a href="postconf.5.html#virtual_mailbox_base">virtual_mailbox_base</a> (empty)</b>
- A prefix that the <a href="virtual.8.html">virtual(8)</a> delivery agent
- prepends to all pathname results from $<a href="postconf.5.html#virtual_mailbox_maps">vir</a>-
+ A prefix that the <a href="virtual.8.html">virtual(8)</a> delivery agent
+ prepends to all pathname results from $<a href="postconf.5.html#virtual_mailbox_maps">vir</a>-
<a href="postconf.5.html#virtual_mailbox_maps">tual_mailbox_maps</a> table lookups.
<b><a href="postconf.5.html#virtual_mailbox_maps">virtual_mailbox_maps</a> (empty)</b>
- Optional lookup tables with all valid addresses in
+ Optional lookup tables with all valid addresses in
the domains that match $<a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a>.
<b><a href="postconf.5.html#virtual_minimum_uid">virtual_minimum_uid</a> (100)</b>
- The minimum user ID value that the <a href="virtual.8.html">virtual(8)</a>
- delivery agent accepts as a result from <b>$<a href="postconf.5.html#virtual_uid_maps">vir</a>-</b>
+ The minimum user ID value that the <a href="virtual.8.html">virtual(8)</a>
+ delivery agent accepts as a result from <b>$<a href="postconf.5.html#virtual_uid_maps">vir</a>-</b>
<b><a href="postconf.5.html#virtual_uid_maps">tual_uid_maps</a></b> table lookup.
<b><a href="postconf.5.html#virtual_uid_maps">virtual_uid_maps</a> (empty)</b>
- Lookup tables with the per-recipient user ID that
+ Lookup tables with the per-recipient user ID that
the <a href="virtual.8.html">virtual(8)</a> delivery agent uses while writing to
the recipient's mailbox.
<b><a href="postconf.5.html#virtual_gid_maps">virtual_gid_maps</a> (empty)</b>
- Lookup tables with the per-recipient group ID for
+ Lookup tables with the per-recipient group ID for
<a href="virtual.8.html">virtual(8)</a> mailbox delivery.
Available in Postfix version 2.0 and later:
<b><a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a> ($<a href="postconf.5.html#virtual_mailbox_maps">virtual_mailbox_maps</a>)</b>
Postfix is final destination for the specified list
- of domains; mail is delivered via the $<a href="postconf.5.html#virtual_transport">vir</a>-
+ of domains; mail is delivered via the $<a href="postconf.5.html#virtual_transport">vir</a>-
<a href="postconf.5.html#virtual_transport">tual_transport</a> mail delivery transport.
<b><a href="postconf.5.html#virtual_transport">virtual_transport</a> (virtual)</b>
- The default mail delivery transport for domains
- that match the $<a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a> parameter
+ The default mail delivery transport for domains
+ that match the $<a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a> parameter
value.
<b>LOCKING CONTROLS</b>
<b><a href="postconf.5.html#virtual_mailbox_lock">virtual_mailbox_lock</a> (see 'postconf -d' output)</b>
- How to lock a UNIX-style <a href="virtual.8.html">virtual(8)</a> mailbox before
+ How to lock a UNIX-style <a href="virtual.8.html">virtual(8)</a> mailbox before
attempting delivery.
<b><a href="postconf.5.html#deliver_lock_attempts">deliver_lock_attempts</a> (20)</b>
sive lock on a mailbox file or <a href="bounce.8.html">bounce(8)</a> logfile.
<b><a href="postconf.5.html#deliver_lock_delay">deliver_lock_delay</a> (1s)</b>
- The time between attempts to acquire an exclusive
+ The time between attempts to acquire an exclusive
lock on a mailbox file or <a href="bounce.8.html">bounce(8)</a> logfile.
<b><a href="postconf.5.html#stale_lock_time">stale_lock_time</a> (500s)</b>
- The time after which a stale exclusive mailbox
+ The time after which a stale exclusive mailbox
lockfile is removed.
<b>RESOURCE AND RATE CONTROLS</b>
<b><a href="postconf.5.html#virtual_destination_concurrency_limit">virtual_destination_concurrency_limit</a> ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destina</a>-</b>
<b><a href="postconf.5.html#default_destination_concurrency_limit">tion_concurrency_limit</a>)</b>
- The maximal number of parallel deliveries to the
- same destination via the virtual message delivery
+ The maximal number of parallel deliveries to the
+ same destination via the virtual message delivery
transport.
<b><a href="postconf.5.html#virtual_destination_recipient_limit">virtual_destination_recipient_limit</a> ($<a href="postconf.5.html#default_destination_recipient_limit">default_destina</a>-</b>
<b><a href="postconf.5.html#default_destination_recipient_limit">tion_recipient_limit</a>)</b>
- The maximal number of recipients per delivery via
+ The maximal number of recipients per delivery via
the virtual message delivery transport.
<b><a href="postconf.5.html#virtual_mailbox_limit">virtual_mailbox_limit</a> (51200000)</b>
- The maximal size in bytes of an individual mailbox
+ The maximal size in bytes of an individual mailbox
or maildir file, or zero (no limit).
<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 main.cf and
+ The default location of the Postfix main.cf and
master.cf 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#ipc_timeout">ipc_timeout</a> (3600s)</b>
over an internal communication channel.
<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 the next service request
+ The maximum amount of time that an idle Postfix
+ daemon process waits for the next service request
before exiting.
<b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
- The maximal number of connection requests before a
+ The maximal number of connection requests before a
Postfix daemon process terminates.
<b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
- The process ID of a Postfix command or daemon pro-
+ The process ID of a Postfix command or daemon pro-
cess.
<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#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 pro-
+ The mail system name that is prepended to the pro-
cess name in syslog records, so that "smtpd"
becomes, for example, "postfix/smtpd".
<a href="VIRTUAL_README.html">VIRTUAL_README</a>, domain hosting howto
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>HISTORY</b>
- This delivery agent was originally based on the Postfix
- local delivery agent. Modifications mainly consisted of
- removing code that either was not applicable or that was
- not safe in this context: aliases, ~user/.forward files,
+ This delivery agent was originally based on the Postfix
+ local delivery agent. Modifications mainly consisted of
+ removing code that either was not applicable or that was
+ not safe in this context: aliases, ~user/.forward files,
delivery to "|command" or to /file/name.
The <b>Delivered-To:</b> message header appears in the <b>qmail</b> sys-
tem by Daniel Bernstein.
- The <b>maildir</b> structure appears in the <b>qmail</b> system by
+ The <b>maildir</b> structure appears in the <b>qmail</b> system by
Daniel Bernstein.
<b>AUTHOR(S)</b>
When alias database search fails, and the recipient localpart
contains the optional recipient delimiter (e.g., \fIuser+foo\fR),
the search is repeated for the unextended address (e.g., \fIuser\fR).
+
+The \fBpropagate_unmatched_extensions\fR parameter controls
+whether an unmatched address extension (\fI+foo\fR) is
+propagated to the result of table lookup.
+.SH "SECURITY"
+.na
+.nf
+.ad
+.fi
+The \fBlocal\fR(8) delivery agent disallows regular expression
+substitution of $1 etc. in \fBalias_maps\fR, because that
+would open a security hole.
+
+The \fBlocal\fR(8) delivery agent will silently ignore
+requests to use the \fBproxymap\fR(8) server within
+\fBalias_maps\fR. Instead it will open the table directly.
+Before Postfix version 2.2, the \fBlocal\fR(8) delivery
+agent will terminate with a fatal error.
.SH "CONFIGURATION PARAMETERS"
.na
.nf
The text below provides only a parameter summary. See
postconf(5) for more details including examples.
.IP \fBalias_database\fR
-List of alias databases that are updated by the newaliases(1) command.
+List of alias databases that are updated by the
+\fBnewaliases\fR(1) command.
.IP \fBalias_maps\fR
-List of alias databases queried by the local(8) delivery agent.
+List of alias databases queried by the \fBlocal\fR(8) delivery agent.
.IP \fBallow_mail_to_commands\fR
Restrict the usage of mail delivery to external command.
.IP \fBallow_mail_to_files\fR
When delivering to an alias that has an \fBowner-\fR companion alias,
set the envelope sender address to the right-hand side of the
owner alias, instead using of the left-hand side address.
+.IP \fBpropagate_unmatched_extensions\fR
+A list of address rewriting or forwarding mechanisms that
+propagate an address extension from the original address
+to the result. Specify zero or more of \fBcanonical\fR,
+\fBvirtual\fR, \fBalias\fR, \fBforward\fR, or \fBinclude\fR.
.IP \fBowner_request_special\fR
Give special treatment to \fBowner-\fIlistname\fR and
\fIlistname\fB-request\fR
addresses.
.IP \fBrecipient_delimiter\fR
Delimiter that separates recipients from address extensions.
-.SH BUGS
-.ad
-.fi
-Regular expression alias lookup tables are allowed, but
-substitution of $1 etc. is forbidden because that would
-open a security loophole.
.SH "STANDARDS"
.na
.nf
(or wherever your system stores the mail alias file), or simply
run "\fBnewaliases\fR" to build the necessary DBM or DB file.
.PP
+The local(8) delivery agent disallows regular expression substitution
+of $1 etc. in alias_maps, because that would open a security hole.
+.PP
+The local(8) delivery agent will silently ignore requests to use
+the proxymap(8) server within alias_maps. Instead it will open the
+table directly. Before Postfix version 2.2, the local(8) delivery
+agent will terminate with a fatal error.
+.PP
Examples:
.PP
.nf
The external command to execute when a Postfix daemon program is
invoked with the -D option.
.PP
-Use "command .. & sleep 5" so that the debugger can attach before
+Use "command .. & sleep 5" so that the debugger can attach before
the process marches on. If you use an X-based debugger, be sure to
set up your XAUTHORITY environment variable before starting Postfix.
.PP
.ft C
debugger_command =
PATH=/usr/bin:/usr/X11R6/bin
- xxgdb $daemon_directory/$process_name $process_id & sleep 5
+ xxgdb $daemon_directory/$process_name $process_id & sleep 5
.fi
.ad
.ft R
a restriction list, to make the default policy explicit. The
reject_code configuration parameter specifies the response code to
rejected requests (default: 554).
+.IP "\fBsleep \fIseconds\fR\fR"
+Pause for the specified number of seconds and proceed with
+the next restriction in the list, if any. This may stop zombie
+mail when used as:
+.na
+.nf
+.in +4
+.nf
+.na
+.ft C
+/etc/postfix/main.cf:
+ smtpd_client_restrictions =
+ sleep 1, reject_unauth_pipelining
+ smtpd_delay_reject = no
+.fi
+.ad
+.ft R
+.in -4
+.fi
+.ad
.IP "\fBwarn_if_reject\fR"
Change the meaning of the next restriction, so that it logs
a warning instead of rejecting a request (look for logfile records
Depending on the setting of the \fBnotify_classes\fR parameter,
the postmaster is notified of bounces and of other trouble.
+.SH "SECURITY"
+.na
+.nf
+.ad
+.fi
+The \fBlocal\fR(8) delivery agent needs a dual personality
+1) to access the private Postfix queue and IPC mechanisms,
+2) to impersonate the recipient and deliver to recipient-specified
+files or commands. It is therefore security sensitive.
+
+The \fBlocal\fR(8) delivery agent disallows regular expression
+substitution of $1 etc. in \fBalias_maps\fR, because that
+would open a security hole.
+
+The \fBlocal\fR(8) delivery agent will silently ignore
+requests to use the \fBproxymap\fR(8) server within
+\fBalias_maps\fR. Instead it will open the table directly.
+Before Postfix version 2.2, the \fBlocal\fR(8) delivery
+agent will terminate with a fatal error.
.SH BUGS
.ad
.fi
.nf
.ad
.fi
-Changes to \fBmain.cf\fR are picked up automatically, as local(8)
+Changes to \fBmain.cf\fR are picked up automatically, as \fBlocal\fR(8)
processes run for only a limited amount of time. Use the command
"\fBpostfix reload\fR" to speed up a change.
.nf
.ad
.fi
-The precedence of local(8) delivery methods from high to low is:
+The precedence of \fBlocal\fR(8) delivery methods from high to low is:
aliases, .forward files, mailbox_transport, mailbox_command_maps,
mailbox_command, home_mailbox, mail_spool_directory, fallback_transport
and luser_relay.
The virtual delivery agent is not security sensitive, provided
that the lookup tables with recipient user/group ID information are
adequately protected. This program is not designed to run chrooted.
+
+The virtual delivery agent disallows regular expression
+substitution of $1 etc. in regular expression lookup tables,
+because that would open a security hole.
+
+The virtual delivery agent will silently ignore requests
+to use the proxymap(8) server. Instead it will open the
+table directly. Before Postfix version 2.2, the virtual
+delivery agent will terminate with a fatal error.
.SH "STANDARDS"
.na
.nf
$block =~ s/<br>\s*/\n.br\n/g;
$block =~ s/</</g;
$block =~ s/>/>/g;
+ $block =~ s/&/\&/g;
$block =~ s/\s+\n/\n/g;
$block =~ s/^\n//g;
print $block;
USAGE="Usage: $0 [name=value] [option]
-non-interactive Do not ask for installation parameters.
+ -package Build a ready-to-install package.
name=value Specify an installation parameter".
# Process command-line options and parameter settings. Work around
case $arg in
*=*) IFS= eval $arg; IFS="$BACKUP_IFS";;
-non-int*) non_interactive=1;;
+ -package) need_install_root=install_root;;
*) echo "$0: Error: $USAGE" 1>&2; exit 1;;
esac
shift
/) install_root=
esac
+test -z "$need_install_root" || test -n "$install_root" || {
+ echo $0: Error: invalid package root directory: \"install_root=/\" 1>&2
+ exit 1
+}
+
CONFIG_DIRECTORY=$install_root$config_directory
# If a parameter is not set via the command line or environment,
file</h2>
<p> The installed main.cf file must be small. PLEASE resist the
-temptation to list all 300+ parameters in the main.cf file. Postfix
-is supposed to be easy to configure. Listing all 300+ in main.cf
+temptation to list all 400+ parameters in the main.cf file. Postfix
+is supposed to be easy to configure. Listing all 400+ in main.cf
defeats the purpose. It is an invitation for hobbyists to make
random changes without understanding what they do, and gets them
into endless trouble. </p>
<p> First compile Postfix. After successful compilation, execute:
</p>
-<blockquote> <pre> % sh postfix-install </pre> </blockquote>
+<blockquote> <pre> % <b>make package</b> </pre>
+</blockquote>
+
+<p> With Postfix versions before 2.2 you must invoke the post-install
+script directly (<tt>% <b>sh post-install</b></tt>). </p>
<p> You will be prompted for installation parameters. Specify an
install_root directory other than /. The mail_owner and setgid_group
<p> If you want to fully automate this process, specify all the
non-default installation parameters on the command line: </p>
-<blockquote> <pre> % sh postfix-install -non-interactive
-install_root=/some/where ... </pre> </blockquote>
+<blockquote>
+<pre> % <b>make non-interactive-package install_root=/some/where</b>...
+</pre> </blockquote>
+
+<p> With Postfix versions before 2.2 you must invoke the post-install
+script directly (<tt>% <b>sh post-install -non-interactive
+install_root...</b></tt>). </p>
<h2>Begin Security Alert</h2>
# When alias database search fails, and the recipient localpart
# contains the optional recipient delimiter (e.g., \fIuser+foo\fR),
# the search is repeated for the unextended address (e.g., \fIuser\fR).
+#
+# The \fBpropagate_unmatched_extensions\fR parameter controls
+# whether an unmatched address extension (\fI+foo\fR) is
+# propagated to the result of table lookup.
+# SECURITY
+# .ad
+# .fi
+# The \fBlocal\fR(8) delivery agent disallows regular expression
+# substitution of $1 etc. in \fBalias_maps\fR, because that
+# would open a security hole.
+#
+# The \fBlocal\fR(8) delivery agent will silently ignore
+# requests to use the \fBproxymap\fR(8) server within
+# \fBalias_maps\fR. Instead it will open the table directly.
+# Before Postfix version 2.2, the \fBlocal\fR(8) delivery
+# agent will terminate with a fatal error.
# CONFIGURATION PARAMETERS
# .ad
# .fi
# The text below provides only a parameter summary. See
# postconf(5) for more details including examples.
# .IP \fBalias_database\fR
-# List of alias databases that are updated by the newaliases(1) command.
+# List of alias databases that are updated by the
+# \fBnewaliases\fR(1) command.
# .IP \fBalias_maps\fR
-# List of alias databases queried by the local(8) delivery agent.
+# List of alias databases queried by the \fBlocal\fR(8) delivery agent.
# .IP \fBallow_mail_to_commands\fR
# Restrict the usage of mail delivery to external command.
# .IP \fBallow_mail_to_files\fR
# When delivering to an alias that has an \fBowner-\fR companion alias,
# set the envelope sender address to the right-hand side of the
# owner alias, instead using of the left-hand side address.
+# .IP \fBpropagate_unmatched_extensions\fR
+# A list of address rewriting or forwarding mechanisms that
+# propagate an address extension from the original address
+# to the result. Specify zero or more of \fBcanonical\fR,
+# \fBvirtual\fR, \fBalias\fR, \fBforward\fR, or \fBinclude\fR.
# .IP \fBowner_request_special\fR
# Give special treatment to \fBowner-\fIlistname\fR and
# \fIlistname\fB-request\fR
# addresses.
# .IP \fBrecipient_delimiter\fR
# Delimiter that separates recipients from address extensions.
-# BUGS
-# Regular expression alias lookup tables are allowed, but
-# substitution of $1 etc. is forbidden because that would
-# open a security loophole.
# STANDARDS
# RFC 822 (ARPA Internet Text Messages)
# SEE ALSO
(or wherever your system stores the mail alias file), or simply
run "<b>newaliases</b>" to build the necessary DBM or DB file.
</p>
+
+<p>
+The local(8) delivery agent disallows regular expression substitution
+of $1 etc. in alias_maps, because that would open a security hole.
+</p>
+
+<p>
+The local(8) delivery agent will silently ignore requests to use
+the proxymap(8) server within alias_maps. Instead it will open the
+table directly. Before Postfix version 2.2, the local(8) delivery
+agent will terminate with a fatal error.
+</p>
<p>
Examples:
reject_code configuration parameter specifies the response code to
rejected requests (default: 554).</dd>
+<dt><b><a name="sleep">sleep <i>seconds</i></a></b></dt>
+
+<dd>Pause for the specified number of seconds and proceed with
+the next restriction in the list, if any. This may stop zombie
+mail when used as: </dd>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_client_restrictions =
+ sleep 1, reject_unauth_pipelining
+ smtpd_delay_reject = no
+</pre>
+</blockquote>
+
<dt><b><a name="warn_if_reject">warn_if_reject</a></b></dt>
<dd>Change the meaning of the next restriction, so that it logs
static char *max_rcpt_user;
static time_t max_rcpt_time;
+static int max_cache;
+static time_t max_cache_time;
+
/*
* Remote connection state, one instance for each (service, client) pair.
*/
anvil_remote = (ANVIL_REMOTE *) mymalloc(sizeof(*anvil_remote));
ANVIL_REMOTE_FIRST(anvil_remote, ident);
htable_enter(anvil_remote_map, ident, (char *) anvil_remote);
+ if (max_cache < anvil_remote_map->used) {
+ max_cache = anvil_remote_map->used;
+ max_cache_time = event_time();
+ }
} else {
ANVIL_REMOTE_NEXT(anvil_remote);
}
static void anvil_status_dump(char *unused_name, char **unused_argv)
{
- if (max_rate > 1) {
+ if (max_rate > 0) {
msg_info("statistics: max connection rate %d/%ds for (%s) at %.15s",
max_rate, var_anvil_time_unit,
max_rate_user, ctime(&max_rate_time) + 4);
max_rate = 0;
}
- if (max_count > 1) {
+ if (max_count > 0) {
msg_info("statistics: max connection count %d for (%s) at %.15s",
max_count, max_count_user, ctime(&max_count_time) + 4);
max_count = 0;
}
- if (max_mail > 1) {
+ if (max_mail > 0) {
msg_info("statistics: max message rate %d/%ds for (%s) at %.15s",
max_mail, var_anvil_time_unit,
max_mail_user, ctime(&max_mail_time) + 4);
max_mail = 0;
}
- if (max_rcpt > 1) {
+ if (max_rcpt > 0) {
msg_info("statistics: max recipient rate %d/%ds for (%s) at %.15s",
max_rcpt, var_anvil_time_unit,
max_rcpt_user, ctime(&max_rcpt_time) + 4);
max_rcpt = 0;
}
+ if (max_cache > 0) {
+ msg_info("statistics: max ident cache size %d at %.15s",
+ max_cache, ctime(&max_cache_time) + 4);
+ max_cache = 0;
+ }
}
/* anvil_status_update - log and reset extreme usage periodically */
#define DEFER_IF_PERMIT "defer_if_permit"
#define DEFER_IF_REJECT "defer_if_reject"
+#define SLEEP "sleep"
+
#define REJECT_UNKNOWN_CLIENT "reject_unknown_client"
#define VAR_UNK_CLIENT_CODE "unknown_client_reject_code"
#define DEF_UNK_CLIENT_CODE 450
* Patches change the patchlevel and the release date. Snapshots change the
* release date only.
*/
-#define MAIL_RELEASE_DATE "20050131"
+#define MAIL_RELEASE_DATE "20050202"
#define MAIL_VERSION_NUMBER "2.2"
#define VAR_MAIL_VERSION "mail_version"
/*
/* Depending on the setting of the \fBnotify_classes\fR parameter,
/* the postmaster is notified of bounces and of other trouble.
+/* SECURITY
+/* .ad
+/* .fi
+/* The \fBlocal\fR(8) delivery agent needs a dual personality
+/* 1) to access the private Postfix queue and IPC mechanisms,
+/* 2) to impersonate the recipient and deliver to recipient-specified
+/* files or commands. It is therefore security sensitive.
+/*
+/* The \fBlocal\fR(8) delivery agent disallows regular expression
+/* substitution of $1 etc. in \fBalias_maps\fR, because that
+/* would open a security hole.
+/*
+/* The \fBlocal\fR(8) delivery agent will silently ignore
+/* requests to use the \fBproxymap\fR(8) server within
+/* \fBalias_maps\fR. Instead it will open the table directly.
+/* Before Postfix version 2.2, the \fBlocal\fR(8) delivery
+/* agent will terminate with a fatal error.
/* BUGS
/* For security reasons, the message delivery status of external commands
/* or of external files is never checkpointed to file. As a result,
/* CONFIGURATION PARAMETERS
/* .ad
/* .fi
-/* Changes to \fBmain.cf\fR are picked up automatically, as local(8)
+/* Changes to \fBmain.cf\fR are picked up automatically, as \fBlocal\fR(8)
/* processes run for only a limited amount of time. Use the command
/* "\fBpostfix reload\fR" to speed up a change.
/*
/* DELIVERY METHOD CONTROLS
/* .ad
/* .fi
-/* The precedence of local(8) delivery methods from high to low is:
+/* The precedence of \fBlocal\fR(8) delivery methods from high to low is:
/* aliases, .forward files, mailbox_transport, mailbox_command_maps,
/* mailbox_command, home_mailbox, mail_spool_directory, fallback_transport
/* and luser_relay.
int wakeup_time; /* wakeup interval */
int *listen_fd; /* incoming requests */
int listen_fd_count; /* nr of descriptors */
+#ifdef MASTER_SERV_TYPE_PASS
+ struct PASS_INFO *pass_info; /* descriptor passing state */
+#endif
union {
struct {
char *port; /* inet listen port */
struct INET_ADDR_LIST *addr;/* inet listen address */
- } inet_ep;
+ } inet_ep;
#define MASTER_INET_ADDRLIST(s) ((s)->endpoint.inet_ep.addr)
#define MASTER_INET_PORT(s) ((s)->endpoint.inet_ep.port)
- } endpoint;
+ } endpoint;
int max_proc; /* upper bound on # processes */
char *path; /* command pathname */
struct ARGV *args; /* argument vector */
#define MASTER_SERV_TYPE_UNIX 1 /* AF_UNIX domain socket */
#define MASTER_SERV_TYPE_INET 2 /* AF_INET domain socket */
#define MASTER_SERV_TYPE_FIFO 3 /* fifo (named pipe) */
+/*#define MASTER_SERV_TYPE_PASS 4 /* AF_UNIX domain socket */
/*
* Default process management policy values. This is only the bare minimum.
} else if (STR_SAME(transport, MASTER_XPORT_NAME_FIFO)) {
serv->type = MASTER_SERV_TYPE_FIFO;
serv->listen_fd_count = 1;
+#ifdef MASTER_SERV_TYPE_PASS
+ } else if (STR_SAME(transport, MASTER_XPORT_NAME_PASS)) {
+ serv->type = MASTER_SERV_TYPE_PASS;
+ serv->listen_fd_count = 1;
+#endif
} else {
fatal_with_context("bad transport type: %s", transport);
}
} else if (serv->type == MASTER_SERV_TYPE_FIFO) {
serv->name = mail_pathname(private ? MAIL_CLASS_PRIVATE :
MAIL_CLASS_PUBLIC, name);
+#ifdef MASTER_SERV_TYPE_PASS
+ } else if (serv->type == MASTER_SERV_TYPE_PASS) {
+ serv->name = mail_pathname(private ? MAIL_CLASS_PRIVATE :
+ MAIL_CLASS_PUBLIC, name);
+#endif
} else {
msg_panic("bad transport type: %d", serv->type);
}
serv->type == MASTER_SERV_TYPE_UNIX ? MASTER_XPORT_NAME_UNIX :
serv->type == MASTER_SERV_TYPE_FIFO ? MASTER_XPORT_NAME_FIFO :
serv->type == MASTER_SERV_TYPE_INET ? MASTER_XPORT_NAME_INET :
+#ifdef MASTER_SERV_TYPE_PASS
+ serv->type == MASTER_SERV_TYPE_PASS ? MASTER_XPORT_NAME_PASS :
+#endif
"unknown transport type");
msg_info("listen_fd_count: %d", serv->listen_fd_count);
msg_info("wakeup: %d", serv->wakeup_time);
myfree(end_point);
}
break;
+
+ /*
+ * Descriptor passing endpoints always come as singlets.
+ */
+#ifdef MASTER_SERV_TYPE_PASS
+ case MASTER_SERV_TYPE_PASS:
+ set_eugid(var_owner_uid, var_owner_gid);
+ serv->listen_fd[0] =
+ PASS_LISTEN(serv->name, serv->max_proc > var_proc_limit ?
+ serv->max_proc : var_proc_limit, NON_BLOCKING,
+ &(serv->pass_info));
+ close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
+ set_ugid(getuid(), getgid());
+ break;
+#endif
default:
msg_panic("%s: unknown service type: %d", myname, serv->type);
}
* listener. The 4.4BSD shutdown(2) man page promises an ENOTCONN error
* when shutdown(2) is applied to a socket that is not connected.
*/
+#ifdef MASTER_SERV_TYPE_PASS
+ if (serv->type == MASTER_SERV_TYPE_PASS)
+ PASS_SHUTDOWN(&(serv->pass_info));
+#endif
for (n = 0; n < serv->listen_fd_count; n++) {
if (close(serv->listen_fd[n]) < 0)
msg_warn("%s: close listener socket %d: %m",
#define MASTER_XPORT_NAME_UNIX "unix" /* local IPC */
#define MASTER_XPORT_NAME_FIFO "fifo" /* local IPC */
#define MASTER_XPORT_NAME_INET "inet" /* non-local IPC */
+/*#define MASTER_XPORT_NAME_PASS "pass" /* local IPC */
/*
* Format of a status message sent by a child process to the process
case MASTER_SERV_TYPE_UNIX:
status = LOCAL_TRIGGER(serv->name, &wakeup, sizeof(wakeup), BRIEFLY);
break;
+#ifdef MASTER_SERV_TYPE_PASS
+ case MASTER_SERV_TYPE_PASS:
+ /* Can't send data to a service that expects descriptors. */
+ status = 0;
+ break;
+#endif
/*
* If someone compromises the postfix account then this must not
multi_server_wakeup(fd);
}
+#ifdef MASTER_XPORT_NAME_PASS
+
+/* multi_server_accept_pass - accept descriptor */
+
+static void multi_server_accept_pass(int unused_event, char *context)
+{
+ int listen_fd = CAST_CHAR_PTR_TO_INT(context);
+ int time_left = -1;
+ int fd;
+
+ /*
+ * Be prepared for accept() to fail because some other process already
+ * got the connection (the number of processes competing for clients is
+ * kept small, so this is not a "thundering herd" problem). If the
+ * accept() succeeds, be sure to disable non-blocking I/O, in order to
+ * minimize confusion.
+ */
+ if (client_count == 0 && var_idle_limit > 0)
+ time_left = event_cancel_timer(multi_server_timeout, (char *) 0);
+
+ if (multi_server_pre_accept)
+ multi_server_pre_accept(multi_server_name, multi_server_argv);
+ fd = PASS_ACCEPT(listen_fd);
+ if (multi_server_lock != 0
+ && myflock(vstream_fileno(multi_server_lock), INTERNAL_LOCK,
+ MYFLOCK_OP_NONE) < 0)
+ msg_fatal("select unlock: %m");
+ if (fd < 0) {
+ if (errno != EAGAIN)
+ msg_fatal("accept connection: %m");
+ if (time_left >= 0)
+ event_request_timer(multi_server_timeout, (char *) 0, time_left);
+ return;
+ }
+ multi_server_wakeup(fd);
+}
+
+#endif
+
/* multi_server_accept_inet - accept client connection request */
static void multi_server_accept_inet(int unused_event, char *context)
multi_server_accept = multi_server_accept_inet;
else if (strcasecmp(transport, MASTER_XPORT_NAME_UNIX) == 0)
multi_server_accept = multi_server_accept_local;
+#ifdef MASTER_XPORT_NAME_PASS
+ else if (strcasecmp(transport, MASTER_XPORT_NAME_PASS) == 0)
+ multi_server_accept = multi_server_accept_pass;
+#endif
else
msg_fatal("unsupported transport type: %s", transport);
}
single_server_wakeup(fd);
}
+#ifdef MASTER_XPORT_NAME_PASS
+
+/* single_server_accept_pass - accept descriptor */
+
+static void single_server_accept_pass(int unused_event, char *context)
+{
+ int listen_fd = CAST_CHAR_PTR_TO_INT(context);
+ int time_left = -1;
+ int fd;
+
+ /*
+ * Be prepared for accept() to fail because some other process already
+ * got the connection. We use select() + accept(), instead of simply
+ * blocking in accept(), because we must be able to detect that the
+ * master process has gone away unexpectedly.
+ */
+ if (var_idle_limit > 0)
+ time_left = event_cancel_timer(single_server_timeout, (char *) 0);
+
+ if (single_server_pre_accept)
+ single_server_pre_accept(single_server_name, single_server_argv);
+ fd = PASS_ACCEPT(listen_fd);
+ if (single_server_lock != 0
+ && myflock(vstream_fileno(single_server_lock), INTERNAL_LOCK,
+ MYFLOCK_OP_NONE) < 0)
+ msg_fatal("select unlock: %m");
+ if (fd < 0) {
+ if (errno != EAGAIN)
+ msg_fatal("accept connection: %m");
+ if (time_left >= 0)
+ event_request_timer(single_server_timeout, (char *) 0, time_left);
+ return;
+ }
+ single_server_wakeup(fd);
+}
+
+#endif
+
/* single_server_accept_inet - accept client connection request */
static void single_server_accept_inet(int unused_event, char *context)
single_server_accept = single_server_accept_inet;
else if (strcasecmp(transport, MASTER_XPORT_NAME_UNIX) == 0)
single_server_accept = single_server_accept_local;
+#ifdef MASTER_XPORT_NAME_PASS
+ else if (strcasecmp(transport, MASTER_XPORT_NAME_PASS) == 0)
+ single_server_accept = single_server_accept_pass;
+#endif
else
msg_fatal("unsupported transport type: %s", transport);
}
close(fd);
}
+#ifdef MASTER_XPORT_NAME_PASS
+
+/* trigger_server_accept_pass - accept descriptor */
+
+static void trigger_server_accept_pass(int unused_event, char *context)
+{
+ char *myname = "trigger_server_accept_pass";
+ int listen_fd = CAST_CHAR_PTR_TO_INT(context);
+ int time_left = 0;
+ int fd;
+
+ if (msg_verbose)
+ msg_info("%s: trigger arrived", myname);
+
+ /*
+ * Read a message from a socket. Be prepared for accept() to fail because
+ * some other process already got the connection. The socket is
+ * non-blocking so we won't get stuck when multiple processes wake up.
+ * Don't get stuck when the client connects but sends no data. Restart
+ * the idle timer if this was a false alarm.
+ */
+ if (var_idle_limit > 0)
+ time_left = event_cancel_timer(trigger_server_timeout, (char *) 0);
+
+ if (trigger_server_pre_accept)
+ trigger_server_pre_accept(trigger_server_name, trigger_server_argv);
+ fd = PASS_ACCEPT(listen_fd);
+ if (trigger_server_lock != 0
+ && myflock(vstream_fileno(trigger_server_lock), INTERNAL_LOCK,
+ MYFLOCK_OP_NONE) < 0)
+ msg_fatal("select unlock: %m");
+ if (fd < 0) {
+ if (errno != EAGAIN)
+ msg_fatal("accept connection: %m");
+ if (time_left >= 0)
+ event_request_timer(trigger_server_timeout, (char *) 0, time_left);
+ return;
+ }
+ close_on_exec(fd, CLOSE_ON_EXEC);
+ if (read_wait(fd, 10) == 0)
+ trigger_server_wakeup(fd);
+ else if (time_left >= 0)
+ event_request_timer(trigger_server_timeout, (char *) 0, time_left);
+ close(fd);
+}
+
+#endif
+
/* trigger_server_main - the real main program */
NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,...)
trigger_server_accept = trigger_server_accept_local;
else if (strcasecmp(transport, MASTER_XPORT_NAME_FIFO) == 0)
trigger_server_accept = trigger_server_accept_fifo;
+#ifdef MASTER_XPORT_NAME_PASS
+ else if (strcasecmp(transport, MASTER_XPORT_NAME_PASS) == 0)
+ trigger_server_accept = trigger_server_accept_pass;
+#endif
else
msg_fatal("unsupported transport type: %s", transport);
}
* Sanity check.
*/
if (var_qmgr_rcpt_limit < var_qmgr_active_limit) {
- msg_warn("%s is smaller than %s",
- VAR_QMGR_RCPT_LIMIT, VAR_QMGR_ACT_LIMIT);
+ msg_warn("%s is smaller than %s - adjusting %s",
+ VAR_QMGR_RCPT_LIMIT, VAR_QMGR_ACT_LIMIT, VAR_QMGR_RCPT_LIMIT);
var_qmgr_rcpt_limit = var_qmgr_active_limit;
}
+ if (var_dsn_queue_time > var_max_queue_time) {
+ msg_warn("%s is larger than %s - adjusting %s",
+ VAR_DSN_QUEUE_TIME, VAR_MAX_QUEUE_TIME, VAR_DSN_QUEUE_TIME);
+ var_dsn_queue_time = var_max_queue_time;
+ }
/*
* This routine runs after the skeleton code has entered the chroot jail.
* Sanity check.
*/
if (var_qmgr_rcpt_limit < var_qmgr_active_limit) {
- msg_warn("%s is smaller than %s",
- VAR_QMGR_RCPT_LIMIT, VAR_QMGR_ACT_LIMIT);
+ msg_warn("%s is smaller than %s - adjusting %s",
+ VAR_QMGR_RCPT_LIMIT, VAR_QMGR_ACT_LIMIT, VAR_QMGR_RCPT_LIMIT);
var_qmgr_rcpt_limit = var_qmgr_active_limit;
}
+ if (var_dsn_queue_time > var_max_queue_time) {
+ msg_warn("%s is larger than %s - adjusting %s",
+ VAR_DSN_QUEUE_TIME, VAR_MAX_QUEUE_TIME, VAR_DSN_QUEUE_TIME);
+ var_dsn_queue_time = var_max_queue_time;
+ }
/*
* This routine runs after the skeleton code has entered the chroot jail.
if (state->client != 0
&& SMTPD_STAND_ALONE(state) == 0
- && vstream_peek(state->client) > 0
+ && (vstream_peek(state->client) > 0
+ || peekfd(vstream_fileno(state->client)) > 0)
&& (strcasecmp(state->protocol, MAIL_PROTO_ESMTP) != 0
|| strcasecmp(state->where, "DATA") == 0)) {
return (smtpd_check_reject(state, MAIL_ERROR_PROTOCOL,
} else if (strcasecmp(name, REJECT_UNAUTH_PIPE) == 0) {
status = reject_unauth_pipelining(state, reply_name, reply_class);
} else if (strcasecmp(name, CHECK_POLICY_SERVICE) == 0) {
- if (cpp[1] == 0)
+ if (cpp[1] == 0 || strchr(cpp[1], ':') == 0) {
msg_warn("restriction %s must be followed by transport:server",
CHECK_POLICY_SERVICE);
- else
+ longjmp(smtpd_check_buf, smtpd_check_reject(state,
+ MAIL_ERROR_SOFTWARE, "451 Server configuration error"));
+ } else
status = check_policy_service(state, *++cpp, reply_name,
reply_class, def_acl);
} else if (strcasecmp(name, DEFER_IF_PERMIT) == 0) {
DEFER_IF_REJECT2(state, MAIL_ERROR_POLICY,
"450 <%s>: %s rejected: defer_if_reject requested",
reply_name, reply_class);
+ } else if (strcasecmp(name, SLEEP) == 0) {
+ if (cpp[1] == 0 || alldig(cpp[1]) == 0) {
+ msg_warn("restriction %s must be followed by number", SLEEP);
+ longjmp(smtpd_check_buf, smtpd_check_reject(state,
+ MAIL_ERROR_SOFTWARE, "451 Server configuration error"));
+ } else
+ sleep(atoi(*++cpp));
}
/*
static void rewrite_service(VSTREAM *stream, char *unused_service, char **argv)
{
int status = -1;
+ static time_t last;
+ time_t now = event_time();
+ const char *table;
/*
* Sanity check. This service takes no command-line arguments.
if (argv[0])
msg_fatal("unexpected command-line argument: %s", argv[0]);
+ /*
+ * Connections are persistent. Be sure to refesh timely.
+ */
+ if (now - last > 10) {
+ if ((table = dict_changed_name()) != 0) {
+ msg_info("table %s has changed -- restarting", table);
+ exit(0);
+ }
+ last = now;
+ }
+
/*
* This routine runs whenever a client connects to the UNIX-domain socket
* dedicated to address rewriting. All connection-management stuff is
multi_server_disconnect(stream);
}
-/* pre_accept - see if tables have changed */
-
-static void pre_accept(char *unused_name, char **unused_argv)
-{
- const char *table;
-
- if ((table = dict_changed_name()) != 0) {
- msg_info("table %s has changed -- restarting", table);
- exit(0);
- }
-}
-
/* pre_jail_init - initialize before entering chroot jail */
static void pre_jail_init(char *unused_name, char **unused_argv)
MAIL_SERVER_BOOL_TABLE, bool_table,
MAIL_SERVER_PRE_INIT, pre_jail_init,
MAIL_SERVER_POST_INIT, post_jail_init,
- MAIL_SERVER_PRE_ACCEPT, pre_accept,
0);
}
extern int fifo_listen(const char *, int, int);
extern int stream_listen(const char *, int, int);
+#define upass_listen(path, mode, log) fifo_listen((path), (mode), (log))
+
extern int inet_accept(int);
extern int unix_accept(int);
extern int stream_accept(int);
+extern int upass_accept(int);
/* LICENSE
/* .ad
#include <sys_defs.h>
#include <string.h>
-#ifdef STRCASECMP_IN_STRING_H
-#include <string.h>
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
#endif
/* Utility library. */
--- /dev/null
+/*++
+/* NAME
+/* upass_listen 3
+/* SUMMARY
+/* start UNIX-domain file descriptor listener
+/* SYNOPSIS
+/* #include <listen.h>
+/*
+/* int upass_listen(path, backlog, block_mode)
+/* const char *path;
+/* int backlog;
+/* int block_mode;
+/*
+/* int upass_accept(fd)
+/* int fd;
+/* DESCRIPTION
+/* This module implements a listener that receives one file descriptor
+/* across each UNIX-domain connection that is made to it.
+/*
+/* upass_listen() creates a listener endpoint with the specified
+/* permissions, and returns a file descriptor to be used for accepting
+/* descriptors.
+/*
+/* upass_accept() accepts a descriptor.
+/*
+/* Arguments:
+/* .IP path
+/* Null-terminated string with connection destination.
+/* .IP backlog
+/* This argument exists for compatibility and is ignored.
+/* .IP block_mode
+/* Either NON_BLOCKING or BLOCKING. This does not affect the
+/* mode of accepted connections.
+/* .IP fd
+/* File descriptor returned by upass_listen().
+/* DIAGNOSTICS
+/* Fatal errors: upass_listen() aborts upon any system call failure.
+/* upass_accept() leaves all error handling up to the caller.
+/* 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 <sys/socket.h>
+#include <errno.h>
+#include <unistd.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <sane_accept.h>
+#include <listen.h>
+
+/* upass_accept - accept descriptor */
+
+int upass_accept(int listen_fd)
+{
+ const char *myname = "upass_accept";
+ int accept_fd;
+ int recv_fd;
+
+ accept_fd = sane_accept(listen_fd, (struct sockaddr *) 0, (int *) 0);
+ if (accept_fd < 0) {
+ if (errno != EAGAIN)
+ msg_warn("%s: accept connection: %m", myname);
+ return (-1);
+ } else {
+ if ((recv_fd = unix_recv_fd(accept_fd)) < 0)
+ msg_warn("%s: cannot receive file descriptor: %m", myname);
+ if (close(accept_fd) < 0)
+ msg_warn("%s: close: %m", myname);
+ return (recv_fd);
+ }
+}
+
+#if 0
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <events.h>
+#include <sane_accept.h>
+#include <iostuff.h>
+#include <listen.h>
+
+ /*
+ * It would be nice if a client could make one UNIX-domain connection to a
+ * Postfix master service, send multiple descriptors, and have each
+ * descriptor handled by the first available child process.
+ *
+ * Possible solutions:
+ *
+ * - Either the master process accepts the UNIX-domain connection and forwards
+ * each descriptor sent by the client to the first available child process.
+ * That's what the code below does. Unfortunately, this approach is
+ * inconsistent with the Postfix architecture which tries to eliminate the
+ * master from connection management as much as possible.
+ *
+ * - Or one child processes accepts the UNIX-domain connection and sends a
+ * shared socketpair half to the client. The other socketpair half is shared
+ * with the master and all the child's siblings. The client then sends its
+ * descriptors over the socketpair, and each descriptor is available to any
+ * child process that is waiting for work.
+ *
+ * If the second solution did not use a shared socketpair, then all the
+ * client's descriptors would be available only to the child process that
+ * accepted the UNIX-domain connection. That results in poor performance.
+ *
+ * Unfortunately, having to receive a descriptor before being able to send one
+ * or more descriptors is ugly from the client's point of view.
+ */
+
+#define upass_accept(fd) unix_recv_fd(fd)
+
+/* upass_plumbing - operate the hidden descriptor passing machinery */
+
+static void upass_plumbing(int unused_event, char *context)
+{
+ const char *myname = "upass_plumbing";
+ UPASS_INFO *info = (UNIX_UPASS_INFO *) context;
+ int fd;
+
+ /*
+ * Each time a client connects to the hidden UNIX-domain socket, call
+ * unix_send_fd() to send one half of the hidden socketpair across a
+ * short-lived UNIX-domain connection. Wait until the client closes the
+ * UNIX-domain connection before closing the connection. This wait needs
+ * to be time limited.
+ */
+ fd = sane_accept(info->unixsock, (struct sockaddr *) 0, (int *) 0);
+ if (fd < 0) {
+ if (errno != EAGAIN)
+ msg_fatal("%s: accept connection: %m", myname);
+ } else {
+ if (unix_send_fd(fd, info->halfpair) < 0)
+ msg_warn("%s: cannot send file descriptor: %m", myname);
+ if (read_wait(fd, 5) < 0)
+ msg_warn("%s: read timeout", myname);
+ if (close(fd) < 0)
+ msg_warn("%s: close: %m", myname);
+ }
+}
+
+/* upass_listen - set up hidden descriptor passing machinery */
+
+int upass_listen(const char *path, int backlog, int blocking, UPASS_INFO **ip)
+{
+ int pair[2];
+ UPASS_INFO *info;
+
+ /*
+ * Create a UNIX-domain socket with unix_listen() and create a
+ * socketpair. One socketpair half is returned to the caller. The other
+ * half is part of the hidden machinery, together with the UNIX-domain
+ * socket.
+ */
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0)
+ msg_fatal("socketpair: %m");
+ info = (UPASS_INFO *) mymalloc(sizeof(*info));
+ info->halfpair = pair[0];
+ info->unixsock = unix_listen(path, backlog, blocking);
+ event_request_read(info->unixsock, upass_plumbing, (char *) info);
+ *ip = info;
+ return (pair[1]);
+}
+
+/* upass_shutdown - tear down hidden descriptor passing machinery */
+
+void upass_shutdown(UPASS_INFO *info)
+{
+ event_disable_readwrite(upass_info->unixsock)
+ if (close(info->unixsock) < 0)
+ msg_warn("%s: close unixsock: %m", myname);
+ if (close(info->halfpair) < 0)
+ msg_warn("%s: close halfpair: %m", myname);
+ myfree((char *) info);
+}
+
+#endif
break;
default:
/* Advance by at least 1 character position or terminate. */
- len = strspn(cp, "0123456789abcdefABCDEF");
- if (len /* - strspn(cp, "0") */ > 4) {
+ len = strspn((char *) cp, "0123456789abcdefABCDEF");
+ if (len /* - strspn((char *) cp, "0") */ > 4) {
if (gripe)
msg_warn("%s: malformed IPv6 address: %.100s",
myname, addr);
/* The virtual delivery agent is not security sensitive, provided
/* that the lookup tables with recipient user/group ID information are
/* adequately protected. This program is not designed to run chrooted.
+/*
+/* The virtual delivery agent disallows regular expression
+/* substitution of $1 etc. in regular expression lookup tables,
+/* because that would open a security hole.
+/*
+/* The virtual delivery agent will silently ignore requests
+/* to use the proxymap(8) server. Instead it will open the
+/* table directly. Before Postfix version 2.2, the virtual
+/* delivery agent will terminate with a fatal error.
/* STANDARDS
/* RFC 822 (ARPA Internet Text Messages)
/* DIAGNOSTICS