Cleanup: minor cleanups and invisible fixes. Files:
postscreen/postscreen_misc.c, postscreen/postscreen.h,
postscreen/postscreen_tests.c.
+
+20100923
+
+ Cleanup: renamed MUMBLE_FLAG_MUMBLE aggregates to
+ MUMBLE_MASK_MUMBLE for consistency with other Postfix code.
+ Files: postscreen/*.[hc].
+
+20100930
+
+ Cleanup: flag PIPELINING errors with NOOP and VRFY. File:
+ smtpd/smtpd.c.
+
+20101006
+
+ Bugfix (introduced: 20100914) dangling pointer when a client
+ makes N > 1 simultaneous connections and closes M < N
+ connections before postscreen has delivered the DNSBL score
+ to the corresponding pseudothreads. In practice the pointer
+ will refer to a block of 0xff bytes; the program terminates
+ with a segmentation violation, and is restarted immediately
+ by the master daemon. Files: postscreen/postscreen_early.c,
+ postscreen/postscreen_dnsbl.c.
+
+ Cleanup: avoid repeated delivery to mailing list members
+ with pathological nested alias configurations. The local(8)
+ delivery agent now keeps the owner-alias attribute of the
+ parent alias, when delivering mail to a child alias that
+ does not have its own owner alias. With this change, local
+ addresses from that child alias will be written to a new
+ queue file, and a temporary error with one local address
+ will no longer result in repeated delivery to other mailing
+ list members. Specify "reset_owner_alias = yes" for the
+ older behavior. File: local/alias.c.
postscreen parameters always evaluate as if the stress value is
equal to the empty string.
+Incompatibility with snapshot 20101006
+======================================
+
+To avoid repeated delivery to mailing list members with pathological
+nested alias configurations, the local(8) delivery agent now keeps
+the owner-alias attribute of the parent alias, when delivering mail
+to a child alias that does not have its own owner alias.
+
+With this change, local addresses from that child alias will be
+written to a new queue file, and a temporary error with one local
+address will no longer result in repeated delivery to other mailing
+list members. Specify "reset_owner_alias = yes" for the older,
+more fragile, behavior.
+
Incompatibility with snapshot 20100912
======================================
Consistency: in postconf.proto make <dt>..</dt> tags bold.
+ Milter addrcpt - use Sendmail default DSN
+
postscreen(8): listen on multiple IP addresses and enforce
that the client contacts the primary MX address first (i.e.
punish hosts that contact the secondary before the primary).
built-in watchdog timer.
<b><a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> (empty)</b>
- Optional list of DNS blocklist domains.
+ Optional list of DNS blocklist domains, filters and
+ weight factors.
<b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
The time limit for sending or receiving information
over an internal communication channel.
<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#syslog_facility">syslog_facility</a> (mail)</b>
The syslog facility of Postfix logging.
<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"
+ The mail system name that is prepended to the
+ process name in syslog records, so that "smtpd"
becomes, for example, "postfix/smtpd".
<b>SEE ALSO</b>
syslogd(5), system logging
<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>
Defer delivery when a mailbox file is not owned by
its recipient.
+ <b><a href="postconf.5.html#reset_owner_alias">reset_owner_alias</a> (no)</b>
+ Reset the <a href="local.8.html"><b>local</b>(8)</a> delivery agent's idea of the
+ owner-alias attribute, when delivering mail to a
+ child alias that does not have its own owner alias.
+
<b>DELIVERY METHOD CONTROLS</b>
- 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_maps">mailbox_transport_maps</a>,
- <a href="postconf.5.html#mailbox_transport">mailbox_transport</a>, <a href="postconf.5.html#mailbox_command_maps">mailbox_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>, fallback_trans-
+ 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_maps">mailbox_transport_maps</a>,
+ <a href="postconf.5.html#mailbox_transport">mailbox_transport</a>, <a href="postconf.5.html#mailbox_command_maps">mailbox_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>, fallback_trans-
port_maps, <a href="postconf.5.html#fallback_transport">fallback_transport</a>, and <a href="postconf.5.html#luser_relay">luser_relay</a>.
<b><a href="postconf.5.html#alias_maps">alias_maps</a> (see 'postconf -d' output)</b>
- The alias databases that are used for <a href="local.8.html"><b>local</b>(8)</a>
+ The alias databases that are used for <a href="local.8.html"><b>local</b>(8)</a>
delivery.
<b><a href="postconf.5.html#forward_path">forward_path</a> (see 'postconf -d' output)</b>
The <a href="local.8.html"><b>local</b>(8)</a> delivery agent search list for finding
- a .forward file with user-specified delivery meth-
+ a .forward file with user-specified delivery meth-
ods.
<b><a href="postconf.5.html#mailbox_transport_maps">mailbox_transport_maps</a> (empty)</b>
- Optional lookup tables with per-recipient message
- delivery transports to use for <a href="local.8.html"><b>local</b>(8)</a> mailbox
- delivery, whether or not the recipients are found
+ Optional lookup tables with per-recipient message
+ delivery transports to use for <a href="local.8.html"><b>local</b>(8)</a> mailbox
+ delivery, whether or not the recipients are found
in the UNIX passwd database.
<b><a href="postconf.5.html#mailbox_transport">mailbox_transport</a> (empty)</b>
- Optional message delivery transport that the
- <a href="local.8.html"><b>local</b>(8)</a> delivery agent should use for mailbox
- delivery to all local recipients, whether or not
+ Optional message delivery transport that the
+ <a href="local.8.html"><b>local</b>(8)</a> delivery agent should use for mailbox
+ delivery to all local recipients, whether or not
they are found in the UNIX passwd database.
<b><a href="postconf.5.html#mailbox_command_maps">mailbox_command_maps</a> (empty)</b>
- Optional lookup tables with per-recipient external
+ Optional lookup tables with per-recipient external
commands to use for <a href="local.8.html"><b>local</b>(8)</a> mailbox delivery.
<b><a href="postconf.5.html#mailbox_command">mailbox_command</a> (empty)</b>
- Optional external command that the <a href="local.8.html"><b>local</b>(8)</a> deliv-
+ Optional external command that the <a href="local.8.html"><b>local</b>(8)</a> deliv-
ery agent should use for mailbox delivery.
<b><a href="postconf.5.html#home_mailbox">home_mailbox</a> (empty)</b>
- Optional pathname of a mailbox file relative to a
+ Optional pathname of a mailbox file relative to a
<a href="local.8.html"><b>local</b>(8)</a> user's home directory.
<b><a href="postconf.5.html#mail_spool_directory">mail_spool_directory</a> (see 'postconf -d' output)</b>
- The directory where <a href="local.8.html"><b>local</b>(8)</a> UNIX-style mailboxes
+ The directory where <a href="local.8.html"><b>local</b>(8)</a> UNIX-style mailboxes
are kept.
<b><a href="postconf.5.html#fallback_transport_maps">fallback_transport_maps</a> (empty)</b>
- Optional lookup tables with per-recipient message
- delivery transports for recipients that the
- <a href="local.8.html"><b>local</b>(8)</a> delivery agent could not find in the
+ Optional lookup tables with per-recipient message
+ delivery transports for recipients that the
+ <a href="local.8.html"><b>local</b>(8)</a> delivery agent could not find in the
<a href="aliases.5.html"><b>aliases</b>(5)</a> or UNIX password database.
<b><a href="postconf.5.html#fallback_transport">fallback_transport</a> (empty)</b>
- Optional message delivery transport that the
- <a href="local.8.html"><b>local</b>(8)</a> delivery agent should use for names that
- are not found in the <a href="aliases.5.html"><b>aliases</b>(5)</a> or UNIX password
+ Optional message delivery transport that the
+ <a href="local.8.html"><b>local</b>(8)</a> delivery agent should use for names that
+ are not found in the <a href="aliases.5.html"><b>aliases</b>(5)</a> or UNIX password
database.
<b><a href="postconf.5.html#luser_relay">luser_relay</a> (empty)</b>
Available in Postfix version 2.2 and later:
<b><a href="postconf.5.html#command_execution_directory">command_execution_directory</a> (empty)</b>
- The <a href="local.8.html"><b>local</b>(8)</a> delivery agent working directory for
+ The <a href="local.8.html"><b>local</b>(8)</a> delivery agent working directory for
delivery to external command.
<b>MAILBOX LOCKING CONTROLS</b>
sive lock on a mailbox file or <a href="bounce.8.html"><b>bounce</b>(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"><b>bounce</b>(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><a href="postconf.5.html#mailbox_delivery_lock">mailbox_delivery_lock</a> (see 'postconf -d' output)</b>
- How to lock a UNIX-style <a href="local.8.html"><b>local</b>(8)</a> mailbox before
+ How to lock a UNIX-style <a href="local.8.html"><b>local</b>(8)</a> mailbox before
attempting delivery.
<b>RESOURCE AND RATE CONTROLS</b>
Time limit for delivery to external commands.
<b><a href="postconf.5.html#duplicate_filter_limit">duplicate_filter_limit</a> (1000)</b>
- The maximal number of addresses remembered by the
- address duplicate filter for <a href="aliases.5.html"><b>aliases</b>(5)</a> or <a href="virtual.5.html"><b>vir-</b></a>
+ The maximal number of addresses remembered by the
+ address duplicate filter for <a href="aliases.5.html"><b>aliases</b>(5)</a> or <a href="virtual.5.html"><b>vir-</b></a>
<a href="virtual.5.html"><b>tual</b>(5)</a> alias expansion, or for <a href="showq.8.html"><b>showq</b>(8)</a> queue dis-
plays.
<b><a href="postconf.5.html#local_destination_concurrency_limit">local_destination_concurrency_limit</a> (2)</b>
- The maximal number of parallel deliveries via the
+ The maximal number of parallel deliveries via the
local mail delivery transport to the same recipient
- (when "<a href="postconf.5.html#local_destination_recipient_limit">local_destination_recipient_limit</a> = 1") or
- the maximal number of parallel deliveries to the
- same <a href="ADDRESS_CLASS_README.html#local_domain_class">local domain</a> (when "local_destination_recipi-
+ (when "<a href="postconf.5.html#local_destination_recipient_limit">local_destination_recipient_limit</a> = 1") or
+ the maximal number of parallel deliveries to the
+ same <a href="ADDRESS_CLASS_README.html#local_domain_class">local domain</a> (when "local_destination_recipi-
ent_limit > 1").
<b><a href="postconf.5.html#local_destination_recipient_limit">local_destination_recipient_limit</a> (1)</b>
<b>SECURITY CONTROLS</b>
<b><a href="postconf.5.html#allow_mail_to_commands">allow_mail_to_commands</a> (alias, forward)</b>
- Restrict <a href="local.8.html"><b>local</b>(8)</a> mail delivery to external com-
+ Restrict <a href="local.8.html"><b>local</b>(8)</a> mail delivery to external com-
mands.
<b><a href="postconf.5.html#allow_mail_to_files">allow_mail_to_files</a> (alias, forward)</b>
- Restrict <a href="local.8.html"><b>local</b>(8)</a> mail delivery to external files.
+ Restrict <a href="local.8.html"><b>local</b>(8)</a> mail delivery to external files.
<b><a href="postconf.5.html#command_expansion_filter">command_expansion_filter</a> (see 'postconf -d' output)</b>
- Restrict the characters that the <a href="local.8.html"><b>local</b>(8)</a> delivery
- agent allows in $name expansions of $<a href="postconf.5.html#mailbox_command">mailbox_com</a>-
+ Restrict the characters that the <a href="local.8.html"><b>local</b>(8)</a> delivery
+ agent allows in $name expansions of $<a href="postconf.5.html#mailbox_command">mailbox_com</a>-
<a href="postconf.5.html#mailbox_command">mand</a> and $<a href="postconf.5.html#command_execution_directory">command_execution_directory</a>.
<b><a href="postconf.5.html#default_privs">default_privs</a> (nobody)</b>
- The default rights used by the <a href="local.8.html"><b>local</b>(8)</a> delivery
+ The default rights used by the <a href="local.8.html"><b>local</b>(8)</a> delivery
agent for delivery to external file or command.
<b><a href="postconf.5.html#forward_expansion_filter">forward_expansion_filter</a> (see 'postconf -d' output)</b>
- Restrict the characters that the <a href="local.8.html"><b>local</b>(8)</a> delivery
- agent allows in $name expansions of $<a href="postconf.5.html#forward_path">forward_path</a>.
+ Restrict the characters that the <a href="local.8.html"><b>local</b>(8)</a> delivery
+ agent allows in $name expansions of $<a href="postconf.5.html#forward_path">forward_path</a>.
Available in Postfix version 2.2 and later:
<b><a href="postconf.5.html#execution_directory_expansion_filter">execution_directory_expansion_filter</a> (see 'postconf -d'</b>
<b>output)</b>
- Restrict the characters that the <a href="local.8.html"><b>local</b>(8)</a> delivery
+ Restrict the characters that the <a href="local.8.html"><b>local</b>(8)</a> delivery
agent allows in $name expansions of $<a href="postconf.5.html#command_execution_directory">command_execu</a>-
<a href="postconf.5.html#command_execution_directory">tion_directory</a>.
Available in Postfix version 2.5.3 and later:
<b><a href="postconf.5.html#strict_mailbox_ownership">strict_mailbox_ownership</a> (yes)</b>
- Defer delivery when a mailbox file is not owned by
+ Defer delivery when a mailbox file is not owned by
its recipient.
<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#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
- The maximal number of digits after the decimal
+ The maximal number of digits after the decimal
point when logging sub-second delay values.
<b><a href="postconf.5.html#export_environment">export_environment</a> (see 'postconf -d' output)</b>
- The list of environment variables that a Postfix
+ The list of environment variables that a Postfix
process will export to non-Postfix processes.
<b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
over an internal communication channel.
<b><a href="postconf.5.html#local_command_shell">local_command_shell</a> (empty)</b>
- Optional shell program for <a href="local.8.html"><b>local</b>(8)</a> delivery to
+ Optional shell program for <a href="local.8.html"><b>local</b>(8)</a> delivery to
non-Postfix command.
<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#prepend_delivered_header">prepend_delivered_header</a> (command, file, forward)</b>
- The message delivery contexts where the Postfix
- <a href="local.8.html"><b>local</b>(8)</a> delivery agent prepends a Delivered-To:
- message header with the address that the mail was
+ The message delivery contexts where the Postfix
+ <a href="local.8.html"><b>local</b>(8)</a> delivery agent prepends a Delivered-To:
+ message header with the address that the mail was
delivered 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#propagate_unmatched_extensions">propagate_unmatched_extensions</a> (canonical, virtual)</b>
- What address lookup tables copy an address exten-
+ What address lookup tables copy an address exten-
sion from the lookup key to the lookup result.
<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#require_home_directory">require_home_directory</a> (no)</b>
- Whether or not a <a href="local.8.html"><b>local</b>(8)</a> recipient's home direc-
- tory must exist before mail delivery is attempted.
+ Require that a <a href="local.8.html"><b>local</b>(8)</a> recipient's home directory
+ exists before mail delivery is attempted.
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
The syslog facility of Postfix logging.
</pre>
+</DD>
+
+<DT><b><a name="dnsblog_reply_delay">dnsblog_reply_delay</a>
+(default: 0s)</b></DT><DD>
+
+<p> A debugging aid to artifically delay DNS responses. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+
</DD>
<DT><b><a name="dont_remove">dont_remove</a>
</p>
+</DD>
+
+<DT><b><a name="reset_owner_alias">reset_owner_alias</a>
+(default: no)</b></DT><DD>
+
+<p> Reset the <a href="local.8.html">local(8)</a> delivery agent's idea of the owner-alias
+attribute, when delivering mail to a child alias that does not have
+its own owner alias. </p>
+
+<p> This feature is available in Postfix 2.8 and later. With older
+Postfix releases, the behavior is as if this parameter is set to
+"yes". </p>
+
+<p> As documented in <a href="aliases.5.html">aliases(5)</a>, when an alias <i>name</i> has a
+companion alias named owner-<i>name</i>, delivery errors will be
+reported to the owner alias instead of the sender. This configuration
+is recommended for mailing lists. <p>
+
+<p> A less known property of the owner alias is that it also forces
+the <a href="local.8.html">local(8)</a> delivery agent to write local and remote addresses
+from alias expansion to a new queue file, instead of attempting to
+deliver mail to local addresses as soon as they come out of alias
+expansion. </p>
+
+<p> Writing local addresses from alias expansion to a new queue
+file allows for robust handling of temporary delivery errors: errors
+with one local member have no effect on deliveries to other members
+of the list. On the other hand, delivery to local addresses as
+soon as they come out of alias expansion is fragile: a temporary
+error with one local address from alias expansion will cause the
+entire alias to be expanded repeatedly until the error goes away,
+or until the message expires in the queue. In that case, a problem
+with one list member results in multiple message deliveries to other
+list members. </p>
+
+<p> The default behavior of Postfix 2.8 and later is to keep the
+owner-alias attribute of the parent alias, when delivering mail to
+a child alias that does not have its own owner alias. Then, local
+addresses from that child alias will be written to a new queue file,
+and a temporary error with one local address will not affect delivery
+to other mailing list members. </p>
+
+<p> Unfortunately, older Postfix releases reset the owner-alias
+attribute when delivering mail to a child alias that does not have
+its own owner alias. The <a href="local.8.html">local(8)</a> delivery agent then attempts to
+deliver local addresses as soon as they come out of child alias
+expansion. If delivery to any address from child alias expansion
+fails with a temporary error condition, the entire mailing list may
+be expanded repeatedly until the mail expires in the queue, resulting
+in multiple deliveries of the same message to mailing list members.
+</p>
+
+
</DD>
<DT><b><a name="resolve_dequoted_address">resolve_dequoted_address</a>
.fi
.ad
.ft R
+.SH dnsblog_reply_delay (default: 0s)
+A debugging aid to artifically delay DNS responses.
+.PP
+This feature is available in Postfix 2.8.
.SH dont_remove (default: 0)
Don't remove queue files and save them to the "saved" mail queue.
This is a debugging aid. To inspect the envelope information and
before mail delivery is attempted. By default this test is disabled.
It can be useful for environments that import home directories to
the mail server (IMPORTING HOME DIRECTORIES IS NOT RECOMMENDED).
+.SH reset_owner_alias (default: no)
+Reset the \fBlocal\fR(8) delivery agent's idea of the owner-alias
+attribute, when delivering mail to a child alias that does not have
+its own owner alias.
+.PP
+This feature is available in Postfix 2.8 and later. With older
+Postfix releases, the behavior is as if this parameter is set to
+"yes".
+.PP
+As documented in \fBaliases\fR(5), when an alias \fIname\fR has a
+companion alias named owner-\fIname\fR, delivery errors will be
+reported to the owner alias instead of the sender. This configuration
+is recommended for mailing lists.
+.PP
+A less known property of the owner alias is that it also forces
+the \fBlocal\fR(8) delivery agent to write local and remote addresses
+from alias expansion to a new queue file, instead of attempting to
+deliver mail to local addresses as soon as they come out of alias
+expansion.
+.PP
+Writing local addresses from alias expansion to a new queue
+file allows for robust handling of temporary delivery errors: errors
+with one local member have no effect on deliveries to other members
+of the list. On the other hand, delivery to local addresses as
+soon as they come out of alias expansion is fragile: a temporary
+error with one local address from alias expansion will cause the
+entire alias to be expanded repeatedly until the error goes away,
+or until the message expires in the queue. In that case, a problem
+with one list member results in multiple message deliveries to other
+list members.
+.PP
+The default behavior of Postfix 2.8 and later is to keep the
+owner-alias attribute of the parent alias, when delivering mail to
+a child alias that does not have its own owner alias. Then, local
+addresses from that child alias will be written to a new queue file,
+and a temporary error with one local address will not affect delivery
+to other mailing list members.
+.PP
+Unfortunately, older Postfix releases reset the owner-alias
+attribute when delivering mail to a child alias that does not have
+its own owner alias. The \fBlocal\fR(8) delivery agent then attempts to
+deliver local addresses as soon as they come out of child alias
+expansion. If delivery to any address from child alias expansion
+fails with a temporary error condition, the entire mailing list may
+be expanded repeatedly until the mail expires in the queue, resulting
+in multiple deliveries of the same message to mailing list members.
.SH resolve_dequoted_address (default: yes)
Resolve a recipient address safely instead of correctly, by
looking inside quotes.
How much time a Postfix daemon process may take to handle a
request before it is terminated by a built-in watchdog timer.
.IP "\fBpostscreen_dnsbl_sites (empty)\fR"
-Optional list of DNS blocklist domains.
+Optional list of DNS blocklist domains, filters and weight
+factors.
.IP "\fBipc_timeout (3600s)\fR"
The time limit for sending or receiving information over an internal
communication channel.
Available in Postfix version 2.5.3 and later:
.IP "\fBstrict_mailbox_ownership (yes)\fR"
Defer delivery when a mailbox file is not owned by its recipient.
+.IP "\fBreset_owner_alias (no)\fR"
+Reset the \fBlocal\fR(8) delivery agent's idea of the owner-alias
+attribute, when delivering mail to a child alias that does not have
+its own owner alias.
.SH "DELIVERY METHOD CONTROLS"
.na
.nf
.IP "\fBrecipient_delimiter (empty)\fR"
The separator between user names and address extensions (user+foo).
.IP "\fBrequire_home_directory (no)\fR"
-Whether or not a \fBlocal\fR(8) recipient's home directory must exist
+Require that a \fBlocal\fR(8) recipient's home directory exists
before mail delivery is attempted.
.IP "\fBsyslog_facility (mail)\fR"
The syslog facility of Postfix logging.
s;\btls_append_default_CA\b;<a href="postconf.5.html#tls_append_default_CA">$&</a>;g;
s;\bfrozen_delivered_to\b;<a href="postconf.5.html#frozen_delivered_to">$&</a>;g;
+ s;\breset_owner_alias\b;<a href="postconf.5.html#reset_owner_alias">$&</a>;g;
# Transport-dependent magical parameters.
s;\bmulti_instance_enable\b;<a href="postconf.5.html#multi_instance_enable">$&</a>;g;
# postscreen
+ s;\bdnsblog_reply_delay\b;<a href="postconf.5.html#dnsblog_reply_delay">$&</a>;g;
s;\bpostscreen_cache_map\b;<a href="postconf.5.html#postscreen_cache_map">$&</a>;g;
s;\bpostscreen_cache_cleanup_interval\b;<a href="postconf.5.html#postscreen_cache_cleanup_interval">$&</a>;g;
s;\bpostscreen_cache_retention_time\b;<a href="postconf.5.html#postscreen_cache_retention_time">$&</a>;g;
<p> This feature is available in Postfix 2.8. </p>
+%PARAM dnsblog_reply_delay 0s
+
+<p> A debugging aid to artifically delay DNS responses. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM reset_owner_alias no
+
+<p> Reset the local(8) delivery agent's idea of the owner-alias
+attribute, when delivering mail to a child alias that does not have
+its own owner alias. </p>
+
+<p> This feature is available in Postfix 2.8 and later. With older
+Postfix releases, the behavior is as if this parameter is set to
+"yes". </p>
+
+<p> As documented in aliases(5), when an alias <i>name</i> has a
+companion alias named owner-<i>name</i>, delivery errors will be
+reported to the owner alias instead of the sender. This configuration
+is recommended for mailing lists. <p>
+
+<p> A less known property of the owner alias is that it also forces
+the local(8) delivery agent to write local and remote addresses
+from alias expansion to a new queue file, instead of attempting to
+deliver mail to local addresses as soon as they come out of alias
+expansion. </p>
+
+<p> Writing local addresses from alias expansion to a new queue
+file allows for robust handling of temporary delivery errors: errors
+with one local member have no effect on deliveries to other members
+of the list. On the other hand, delivery to local addresses as
+soon as they come out of alias expansion is fragile: a temporary
+error with one local address from alias expansion will cause the
+entire alias to be expanded repeatedly until the error goes away,
+or until the message expires in the queue. In that case, a problem
+with one list member results in multiple message deliveries to other
+list members. </p>
+
+<p> The default behavior of Postfix 2.8 and later is to keep the
+owner-alias attribute of the parent alias, when delivering mail to
+a child alias that does not have its own owner alias. Then, local
+addresses from that child alias will be written to a new queue file,
+and a temporary error with one local address will not affect delivery
+to other mailing list members. </p>
+
+<p> Unfortunately, older Postfix releases reset the owner-alias
+attribute when delivering mail to a child alias that does not have
+its own owner alias. The local(8) delivery agent then attempts to
+deliver local addresses as soon as they come out of child alias
+expansion. If delivery to any address from child alias expansion
+fails with a temporary error condition, the entire mailing list may
+be expanded repeatedly until the mail expires in the queue, resulting
+in multiple deliveries of the same message to mailing list members.
+</p>
/* How much time a Postfix daemon process may take to handle a
/* request before it is terminated by a built-in watchdog timer.
/* .IP "\fBpostscreen_dnsbl_sites (empty)\fR"
-/* Optional list of DNS blocklist domains.
+/* Optional list of DNS blocklist domains, filters and weight
+/* factors.
/* .IP "\fBipc_timeout (3600s)\fR"
/* The time limit for sending or receiving information over an internal
/* communication channel.
#include <mail_conf.h>
#include <mail_version.h>
#include <mail_proto.h>
+#include <mail_params.h>
/* DNS library. */
/* Application-specific. */
+ /*
+ * Tunable parameters.
+ */
+int var_dnsblog_delay;
+
/*
* Static so we don't allocate and free on every request.
*/
/* static void dnsblog_query - query DNSBL for client address */
-static VSTRING *dnsblog_query(VSTRING *result, const char *dnsbl_domain,
- const char *addr)
+static VSTRING *dnsblog_query(VSTRING *result, const char *dnsbl_domain,
+ const char *addr)
{
const char *myname = "dnsblog_query";
ARGV *octets;
ATTR_TYPE_STR, MAIL_ATTR_ACT_CLIENT_ADDR, addr,
ATTR_TYPE_END) == 2) {
(void) dnsblog_query(result, STR(rbl_domain), STR(addr));
+ if (var_dnsblog_delay > 0)
+ sleep(var_dnsblog_delay);
attr_print(client_stream, ATTR_FLAG_NONE,
ATTR_TYPE_STR, MAIL_ATTR_RBL_DOMAIN, STR(rbl_domain),
ATTR_TYPE_STR, MAIL_ATTR_ACT_CLIENT_ADDR, STR(addr),
int main(int argc, char **argv)
{
+ static const CONFIG_TIME_TABLE time_table[] = {
+ VAR_DNSBLOG_DELAY, DEF_DNSBLOG_DELAY, &var_dnsblog_delay, 0, 0,
+ 0,
+ };
/*
* Fingerprint executables and core dumps.
MAIL_VERSION_STAMP_ALLOCATE;
multi_server_main(argc, argv, dnsblog_service,
+ MAIL_SERVER_TIME_TABLE, time_table,
MAIL_SERVER_POST_INIT, post_jail_init,
MAIL_SERVER_UNLIMITED,
0);
#define DEF_FROZEN_DELIVERED 1
extern bool var_frozen_delivered;
+#define VAR_RESET_OWNER_ATTR "reset_owner_alias"
+#define DEF_RESET_OWNER_ATTR 0
+extern bool var_reset_owner_attr;
+
/*
* Delay logging time roundup.
*/
#define DEF_PS_DISABLE_VRFY "$" VAR_DISABLE_VRFY_CMD
extern bool var_ps_disable_vrfy;
+#define VAR_DNSBLOG_DELAY "dnsblog_reply_delay"
+#define DEF_DNSBLOG_DELAY "0s"
+extern int var_dnsblog_delay;
+
/* LICENSE
/* .ad
/* .fi
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20100923"
+#define MAIL_RELEASE_DATE "20101006"
#define MAIL_VERSION_NUMBER "2.8"
#ifdef SNAPSHOT
} else {
canon_owner = 0;
/* Note: this does not reset the envelope sender. */
- RESET_OWNER_ATTR(state.msg_attr, state.level);
+ if (var_reset_owner_attr)
+ RESET_OWNER_ATTR(state.msg_attr, state.level);
}
/*
/* Available in Postfix version 2.5.3 and later:
/* .IP "\fBstrict_mailbox_ownership (yes)\fR"
/* Defer delivery when a mailbox file is not owned by its recipient.
+/* .IP "\fBreset_owner_alias (no)\fR"
+/* Reset the \fBlocal\fR(8) delivery agent's idea of the owner-alias
+/* attribute, when delivering mail to a child alias that does not have
+/* its own owner alias.
/* DELIVERY METHOD CONTROLS
/* .ad
/* .fi
/* .IP "\fBrecipient_delimiter (empty)\fR"
/* The separator between user names and address extensions (user+foo).
/* .IP "\fBrequire_home_directory (no)\fR"
-/* Whether or not a \fBlocal\fR(8) recipient's home directory must exist
+/* Require that a \fBlocal\fR(8) recipient's home directory exists
/* before mail delivery is attempted.
/* .IP "\fBsyslog_facility (mail)\fR"
/* The syslog facility of Postfix logging.
char *var_mailbox_lock;
int var_mailbox_limit;
bool var_frozen_delivered;
+bool var_reset_owner_attr;
bool var_strict_mbox_owner;
int local_cmd_deliver_mask;
VAR_STAT_HOME_DIR, DEF_STAT_HOME_DIR, &var_stat_home_dir,
VAR_MAILTOOL_COMPAT, DEF_MAILTOOL_COMPAT, &var_mailtool_compat,
VAR_FROZEN_DELIVERED, DEF_FROZEN_DELIVERED, &var_frozen_delivered,
+ VAR_RESET_OWNER_ATTR, DEF_RESET_OWNER_ATTR, &var_reset_owner_attr,
VAR_STRICT_MBOX_OWNER, DEF_STRICT_MBOX_OWNER, &var_strict_mbox_owner,
0,
};
* tests. Whitelist the client when all enabled test results are still
* valid.
*/
- if ((state->flags & PS_STATE_FLAG_ANY_FAIL) == 0
+ if ((state->flags & PS_STATE_MASK_ANY_FAIL) == 0
&& ps_cache_map != 0
&& (stamp_str = ps_cache_lookup(ps_cache_map, state->smtp_client_addr)) != 0) {
saved_flags = state->flags;
if (msg_verbose)
msg_info("%s: cached + recent flags: %s",
myname, ps_print_state_flags(state->flags, myname));
- if ((state->flags & PS_STATE_FLAG_ANY_TODO_FAIL) == 0) {
+ if ((state->flags & PS_STATE_MASK_ANY_TODO_FAIL) == 0) {
msg_info("PASS OLD %s", state->smtp_client_addr);
ps_conclude(state);
return;
* If the client has no up-to-date results for some tests, do those tests
* first. Otherwise, skip the tests and hand off the connection.
*/
- if (state->flags & PS_STATE_FLAG_EARLY_TODO)
+ if (state->flags & PS_STATE_MASK_EARLY_TODO)
ps_early_tests(state);
- else if (state->flags & (PS_STATE_FLAG_SMTPD_TODO | PS_STATE_FLAG_NOFORWARD))
+ else if (state->flags & (PS_STATE_MASK_SMTPD_TODO | PS_STATE_FLAG_NOFORWARD))
ps_smtpd_tests(state);
else
ps_conclude(state);
* expired longer ago than the cache retention time.
*/
ps_parse_tests(&dummy, stamp_str, event_time() - var_ps_cache_ret);
- return ((dummy.flags & PS_STATE_FLAG_ANY_TODO) == 0);
+ return ((dummy.flags & PS_STATE_MASK_ANY_TODO) == 0);
}
/* pre_jail_init - pre-jail initialization */
time_t pregr_stamp; /* pregreet expiration time */
time_t dnsbl_stamp; /* dnsbl expiration time */
VSTRING *dnsbl_reply; /* dnsbl reject text */
+ int dnsbl_index; /* dnsbl request index */
/* Built-in SMTP protocol engine. */
time_t pipel_stamp; /* pipelining expiration time */
time_t nsmtp_stamp; /* non-smtp command expiration time */
/*
* Aggregates for individual tests.
*/
-#define PS_STATE_FLAG_PREGR_TODO_FAIL \
+#define PS_STATE_MASK_PREGR_TODO_FAIL \
(PS_STATE_FLAG_PREGR_TODO | PS_STATE_FLAG_PREGR_FAIL)
-#define PS_STATE_FLAG_DNSBL_TODO_FAIL \
+#define PS_STATE_MASK_DNSBL_TODO_FAIL \
(PS_STATE_FLAG_DNSBL_TODO | PS_STATE_FLAG_DNSBL_FAIL)
-#define PS_STATE_FLAG_PIPEL_TODO_FAIL \
+#define PS_STATE_MASK_PIPEL_TODO_FAIL \
(PS_STATE_FLAG_PIPEL_TODO | PS_STATE_FLAG_PIPEL_FAIL)
-#define PS_STATE_FLAG_NSMTP_TODO_FAIL \
+#define PS_STATE_MASK_NSMTP_TODO_FAIL \
(PS_STATE_FLAG_NSMTP_TODO | PS_STATE_FLAG_NSMTP_FAIL)
-#define PS_STATE_FLAG_BARLF_TODO_FAIL \
+#define PS_STATE_MASK_BARLF_TODO_FAIL \
(PS_STATE_FLAG_BARLF_TODO | PS_STATE_FLAG_BARLF_FAIL)
-#define PS_STATE_FLAG_PIPEL_TODO_SKIP \
+#define PS_STATE_MASK_PIPEL_TODO_SKIP \
(PS_STATE_FLAG_PIPEL_TODO | PS_STATE_FLAG_PIPEL_SKIP)
-#define PS_STATE_FLAG_NSMTP_TODO_SKIP \
+#define PS_STATE_MASK_NSMTP_TODO_SKIP \
(PS_STATE_FLAG_NSMTP_TODO | PS_STATE_FLAG_NSMTP_SKIP)
-#define PS_STATE_FLAG_BARLF_TODO_SKIP \
+#define PS_STATE_MASK_BARLF_TODO_SKIP \
(PS_STATE_FLAG_BARLF_TODO | PS_STATE_FLAG_BARLF_SKIP)
-#define PS_STATE_FLAG_PIPEL_TODO_PASS_FAIL \
- (PS_STATE_FLAG_PIPEL_TODO_FAIL | PS_STATE_FLAG_PIPEL_PASS)
-#define PS_STATE_FLAG_NSMTP_TODO_PASS_FAIL \
- (PS_STATE_FLAG_NSMTP_TODO_FAIL | PS_STATE_FLAG_NSMTP_PASS)
-#define PS_STATE_FLAG_BARLF_TODO_PASS_FAIL \
- (PS_STATE_FLAG_BARLF_TODO_FAIL | PS_STATE_FLAG_BARLF_PASS)
+#define PS_STATE_MASK_PIPEL_TODO_PASS_FAIL \
+ (PS_STATE_MASK_PIPEL_TODO_FAIL | PS_STATE_FLAG_PIPEL_PASS)
+#define PS_STATE_MASK_NSMTP_TODO_PASS_FAIL \
+ (PS_STATE_MASK_NSMTP_TODO_FAIL | PS_STATE_FLAG_NSMTP_PASS)
+#define PS_STATE_MASK_BARLF_TODO_PASS_FAIL \
+ (PS_STATE_MASK_BARLF_TODO_FAIL | PS_STATE_FLAG_BARLF_PASS)
/*
* Separate aggregates for early tests and deep tests.
*/
-#define PS_STATE_FLAG_EARLY_DONE \
+#define PS_STATE_MASK_EARLY_DONE \
(PS_STATE_FLAG_PREGR_DONE | PS_STATE_FLAG_DNSBL_DONE)
-#define PS_STATE_FLAG_EARLY_TODO \
+#define PS_STATE_MASK_EARLY_TODO \
(PS_STATE_FLAG_PREGR_TODO | PS_STATE_FLAG_DNSBL_TODO)
-#define PS_STATE_FLAG_EARLY_PASS \
+#define PS_STATE_MASK_EARLY_PASS \
(PS_STATE_FLAG_PREGR_PASS | PS_STATE_FLAG_DNSBL_PASS)
-#define PS_STATE_FLAG_EARLY_FAIL \
+#define PS_STATE_MASK_EARLY_FAIL \
(PS_STATE_FLAG_PREGR_FAIL | PS_STATE_FLAG_DNSBL_FAIL)
-#define PS_STATE_FLAG_SMTPD_TODO \
+#define PS_STATE_MASK_SMTPD_TODO \
(PS_STATE_FLAG_PIPEL_TODO | PS_STATE_FLAG_NSMTP_TODO | \
PS_STATE_FLAG_BARLF_TODO)
-#define PS_STATE_FLAG_SMTPD_PASS \
+#define PS_STATE_MASK_SMTPD_PASS \
(PS_STATE_FLAG_PIPEL_PASS | PS_STATE_FLAG_NSMTP_PASS | \
PS_STATE_FLAG_BARLF_PASS)
-#define PS_STATE_FLAG_SMTPD_FAIL \
+#define PS_STATE_MASK_SMTPD_FAIL \
(PS_STATE_FLAG_PIPEL_FAIL | PS_STATE_FLAG_NSMTP_FAIL | \
PS_STATE_FLAG_BARLF_FAIL)
/*
* Super-aggregates for all tests combined.
*/
-#define PS_STATE_FLAG_ANY_FAIL \
+#define PS_STATE_MASK_ANY_FAIL \
(PS_STATE_FLAG_BLIST_FAIL | \
- PS_STATE_FLAG_EARLY_FAIL | PS_STATE_FLAG_SMTPD_FAIL)
+ PS_STATE_MASK_EARLY_FAIL | PS_STATE_MASK_SMTPD_FAIL)
-#define PS_STATE_FLAG_ANY_PASS \
- (PS_STATE_FLAG_EARLY_PASS | PS_STATE_FLAG_SMTPD_PASS)
+#define PS_STATE_MASK_ANY_PASS \
+ (PS_STATE_MASK_EARLY_PASS | PS_STATE_MASK_SMTPD_PASS)
-#define PS_STATE_FLAG_ANY_TODO \
- (PS_STATE_FLAG_EARLY_TODO | PS_STATE_FLAG_SMTPD_TODO)
+#define PS_STATE_MASK_ANY_TODO \
+ (PS_STATE_MASK_EARLY_TODO | PS_STATE_MASK_SMTPD_TODO)
-#define PS_STATE_FLAG_ANY_TODO_FAIL \
- (PS_STATE_FLAG_ANY_TODO | PS_STATE_FLAG_ANY_FAIL)
+#define PS_STATE_MASK_ANY_TODO_FAIL \
+ (PS_STATE_MASK_ANY_TODO | PS_STATE_MASK_ANY_FAIL)
-#define PS_STATE_FLAG_ANY_UPDATE \
- (PS_STATE_FLAG_ANY_PASS)
+#define PS_STATE_MASK_ANY_UPDATE \
+ (PS_STATE_MASK_ANY_PASS)
/*
* See log_adhoc.c for discussion.
* postscreen_dnsbl.c
*/
extern void ps_dnsbl_init(void);
-extern int ps_dnsbl_retrieve(const char *, const char **);
-extern void ps_dnsbl_request(const char *, void (*) (int, char *), char *);
+extern int ps_dnsbl_retrieve(const char *, const char **, int);
+extern int ps_dnsbl_request(const char *, void (*) (int, char *), char *);
/*
* postscreen_tests.c
/*
/* void ps_dnsbl_init(void)
/*
-/* void ps_dnsbl_request(client_addr, callback, context)
+/* int ps_dnsbl_request(client_addr, callback, context)
/* char *client_addr;
/* void (*callback)(int, char *);
/* char *context;
/*
-/* int ps_dnsbl_retrieve(client_addr, dnsbl_name)
+/* int ps_dnsbl_retrieve(client_addr, dnsbl_name, dnsbl_index)
/* char *client_addr;
/* const char **dnsbl_name;
+/* int dnsbl_index;
/* DESCRIPTION
/* This module implements preliminary support for DNSBL lookups.
/* Multiple requests for the same information are handled with
/* on to the callback function. The callback should ignore its
/* first argument (it exists for compatibility with Postfix
/* generic event infrastructure).
+/* The result value is the index for the ps_dnsbl_retrieve()
+/* call.
/*
/* ps_dnsbl_retrieve() retrieves the result score requested with
/* ps_dnsbl_request() and decrements the reference count. It
(sp)->index = 0; \
} while (0)
+#define PS_CALL_BACK_INDEX_OF_LAST(sp) ((sp)->index - 1)
+
+#define PS_CALL_BACK_CANCEL(sp, idx) do { \
+ PS_CALL_BACK_ENTRY *_cb_; \
+ if ((idx) < 0 || (idx) >= (sp)->index) \
+ msg_panic("%s: index %d must be >= 0 and < %d", \
+ myname, (idx), (sp)->index); \
+ _cb_ = (sp)->table + (idx); \
+ event_cancel_timer(_cb_->callback, _cb_->context); \
+ _cb_->callback = 0; \
+ _cb_->context = 0; \
+ } while (0)
+
#define PS_CALL_BACK_EXTEND(hp, sp) do { \
if ((sp)->index >= (sp)->limit) { \
int _count_ = ((sp)->limit ? (sp)->limit * 2 : 5); \
#define PS_CALL_BACK_NOTIFY(sp, ev) do { \
PS_CALL_BACK_ENTRY *_cb_; \
for (_cb_ = (sp)->table; _cb_ < (sp)->table + (sp)->index; _cb_++) \
- _cb_->callback((ev), _cb_->context); \
+ if (_cb_->callback != 0) \
+ _cb_->callback((ev), _cb_->context); \
} while (0)
#define PS_NULL_EVENT (0)
/* ps_dnsbl_retrieve - retrieve blocklist score, decrement reference count */
-int ps_dnsbl_retrieve(const char *client_addr, const char **dnsbl_name)
+int ps_dnsbl_retrieve(const char *client_addr, const char **dnsbl_name,
+ int dnsbl_index)
{
const char *myname = "ps_dnsbl_retrieve";
PS_DNSBL_SCORE *score;
htable_find(dnsbl_score_cache, client_addr)) == 0)
msg_panic("%s: no blocklist score for %s", myname, client_addr);
+ /*
+ * Disable callbacks.
+ */
+ PS_CALL_BACK_CANCEL(score, dnsbl_index);
+
/*
* Reads are destructive.
*/
/* ps_dnsbl_request - send dnsbl query, increment reference count */
-void ps_dnsbl_request(const char *client_addr,
+int ps_dnsbl_request(const char *client_addr,
void (*callback) (int, char *),
char *context)
{
score->pending_lookups);
if (score->pending_lookups == 0)
event_request_timer(callback, context, EVENT_NULL_DELAY);
- return;
+ return (PS_CALL_BACK_INDEX_OF_LAST(score));
}
if (msg_verbose > 1)
msg_info("%s: create blocklist score for %s", myname, client_addr);
(char *) stream, DNSBLOG_TIMEOUT);
score->pending_lookups += 1;
}
+ return (PS_CALL_BACK_INDEX_OF_LAST(score));
}
/* ps_dnsbl_init - initialize */
/*
* Check if the SMTP client spoke before its turn.
*/
- if ((state->flags & PS_STATE_FLAG_PREGR_TODO_FAIL)
+ if ((state->flags & PS_STATE_MASK_PREGR_TODO_FAIL)
== PS_STATE_FLAG_PREGR_TODO) {
state->pregr_stamp = event_time() + var_ps_pregr_ttl;
PS_PASS_SESSION_STATE(state, "pregreet test",
if (state->flags & PS_STATE_FLAG_DNSBL_TODO) {
dnsbl_score =
- ps_dnsbl_retrieve(state->smtp_client_addr, &dnsbl_name);
+ ps_dnsbl_retrieve(state->smtp_client_addr, &dnsbl_name,
+ state->dnsbl_index);
if (dnsbl_score < var_ps_dnsbl_thresh) {
state->dnsbl_stamp = event_time() + var_ps_dnsbl_ttl;
PS_PASS_SESSION_STATE(state, "dnsbl test",
* Pass the connection to a real SMTP server, or enter the dummy
* engine for deep tests.
*/
- if (state->flags & (PS_STATE_FLAG_NOFORWARD | PS_STATE_FLAG_SMTPD_TODO))
+ if (state->flags & (PS_STATE_FLAG_NOFORWARD | PS_STATE_MASK_SMTPD_TODO))
ps_smtpd_tests(state);
else
ps_conclude(state);
read_buf, sizeof(read_buf) - 1, MSG_PEEK)) <= 0) {
/* Avoid memory leak. */
if (state->flags & PS_STATE_FLAG_DNSBL_TODO)
- (void) ps_dnsbl_retrieve(state->smtp_client_addr, &dnsbl_name);
+ (void) ps_dnsbl_retrieve(state->smtp_client_addr, &dnsbl_name,
+ state->dnsbl_index);
/* XXX Wait for DNS replies to come in. */
ps_hangup_event(state);
return;
case PS_ACT_DROP:
/* Avoid memory leak. */
if (state->flags & PS_STATE_FLAG_DNSBL_TODO)
- (void) ps_dnsbl_retrieve(state->smtp_client_addr, &dnsbl_name);
+ (void) ps_dnsbl_retrieve(state->smtp_client_addr, &dnsbl_name,
+ state->dnsbl_index);
PS_DROP_SESSION_STATE(state, "521 5.5.1 Protocol error\r\n");
return;
case PS_ACT_ENFORCE:
*/
state->flags |= PS_STATE_FLAG_PREGR_DONE;
if (elapsed.dt_sec >= PS_EFF_GREET_WAIT
- || ((state->flags & PS_STATE_FLAG_EARLY_DONE)
- == PS_STATE_FLAGS_TODO_TO_DONE(state->flags & PS_STATE_FLAG_EARLY_TODO)))
+ || ((state->flags & PS_STATE_MASK_EARLY_DONE)
+ == PS_STATE_FLAGS_TODO_TO_DONE(state->flags & PS_STATE_MASK_EARLY_TODO)))
ps_early_event(EVENT_TIME, context);
else
event_request_timer(ps_early_event, context,
* dangling pointer.
*/
state->flags |= PS_STATE_FLAG_DNSBL_DONE;
- if ((state->flags & PS_STATE_FLAG_EARLY_DONE)
- == PS_STATE_FLAGS_TODO_TO_DONE(state->flags & PS_STATE_FLAG_EARLY_TODO))
+ if ((state->flags & PS_STATE_MASK_EARLY_DONE)
+ == PS_STATE_FLAGS_TODO_TO_DONE(state->flags & PS_STATE_MASK_EARLY_TODO))
event_request_timer(ps_early_event, context, EVENT_NULL_DELAY);
}
* Run a DNS blocklist query.
*/
if ((state->flags & PS_STATE_FLAG_DNSBL_TODO) != 0)
- ps_dnsbl_request(state->smtp_client_addr, ps_early_dnsbl_event,
- (char *) state);
+ state->dnsbl_index =
+ ps_dnsbl_request(state->smtp_client_addr, ps_early_dnsbl_event,
+ (char *) state);
+ else
+ state->dnsbl_index = -1;
/*
* Wait for the client to respond or for DNS lookup to complete.
* blacklisting. There may still be unfinished tests; those tests will
* need to be completed when the client returns in a later session.
*/
- if (state->flags & PS_STATE_FLAG_ANY_FAIL)
- state->flags &= ~PS_STATE_FLAG_ANY_PASS;
+ if (state->flags & PS_STATE_MASK_ANY_FAIL)
+ state->flags &= ~PS_STATE_MASK_ANY_PASS;
/*
* Log our final blessing when all unfinished tests were completed.
*/
- if ((state->flags & PS_STATE_FLAG_ANY_PASS) ==
- PS_STATE_FLAGS_TODO_TO_PASS(state->flags & PS_STATE_FLAG_ANY_TODO))
+ if ((state->flags & PS_STATE_MASK_ANY_PASS) ==
+ PS_STATE_FLAGS_TODO_TO_PASS(state->flags & PS_STATE_MASK_ANY_TODO))
msg_info("PASS %s %s", (state->flags & PS_STATE_FLAG_NEW) == 0 ?
"OLD" : "NEW", state->smtp_client_addr);
* client gets whitelisted in the course of multiple sessions, as long as
* that client does not "fail" any test.
*/
- if ((state->flags & PS_STATE_FLAG_ANY_UPDATE) != 0
+ if ((state->flags & PS_STATE_MASK_ANY_UPDATE) != 0
&& ps_cache_map != 0) {
ps_print_tests(ps_temp, state);
ps_cache_update(ps_cache_map, state->smtp_client_addr, STR(ps_temp));
* Bare newline test.
*/
if (ch == '\n') {
- if ((state->flags & PS_STATE_FLAG_BARLF_TODO_SKIP)
+ if ((state->flags & PS_STATE_MASK_BARLF_TODO_SKIP)
== PS_STATE_FLAG_BARLF_TODO) {
msg_info("BARE NEWLINE from %s", state->smtp_client_addr);
PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_BARLF_FAIL);
break;
/* Non-SMTP command test. */
- if ((state->flags & PS_STATE_FLAG_NSMTP_TODO_SKIP)
+ if ((state->flags & PS_STATE_MASK_NSMTP_TODO_SKIP)
== PS_STATE_FLAG_NSMTP_TODO && cmdp->name == 0
&& (is_header(command)
|| (*var_ps_forbid_cmds
}
}
/* Command PIPELINING test. */
- if ((state->flags & PS_STATE_FLAG_PIPEL_TODO_SKIP)
+ if ((state->flags & PS_STATE_MASK_PIPEL_TODO_SKIP)
== PS_STATE_FLAG_PIPEL_TODO && !PS_SMTPD_BUFFER_EMPTY(state)) {
printable(command, '?');
msg_info("COMMAND PIPELINING from %s after %.100s",
* tests with some later command.
*/
if (cmdp->action == ps_rcpt_cmd) {
- if ((state->flags & PS_STATE_FLAG_BARLF_TODO_PASS_FAIL)
+ if ((state->flags & PS_STATE_MASK_BARLF_TODO_PASS_FAIL)
== PS_STATE_FLAG_BARLF_TODO) {
PS_PASS_SESSION_STATE(state, "bare newline test",
PS_STATE_FLAG_BARLF_PASS);
/* XXX Reset to PS_TIME_STAMP_DISABLED on failure. */
state->barlf_stamp = event_time() + var_ps_barlf_ttl;
}
- if ((state->flags & PS_STATE_FLAG_NSMTP_TODO_PASS_FAIL)
+ if ((state->flags & PS_STATE_MASK_NSMTP_TODO_PASS_FAIL)
== PS_STATE_FLAG_NSMTP_TODO) {
PS_PASS_SESSION_STATE(state, "non-smtp test",
PS_STATE_FLAG_NSMTP_PASS);
/* XXX Reset to PS_TIME_STAMP_DISABLED on failure. */
state->nsmtp_stamp = event_time() + var_ps_nsmtp_ttl;
}
- if ((state->flags & PS_STATE_FLAG_PIPEL_TODO_PASS_FAIL)
+ if ((state->flags & PS_STATE_MASK_PIPEL_TODO_PASS_FAIL)
== PS_STATE_FLAG_PIPEL_TODO) {
PS_PASS_SESSION_STATE(state, "pipelining test",
PS_STATE_FLAG_PIPEL_PASS);
* full postscreen_greet_wait too frequently.
*/
#if 0
- if (state->flags & PS_STATE_FLAG_EARLY_TODO) {
+ if (state->flags & PS_STATE_MASK_EARLY_TODO) {
if (PS_PREGR_TEST_ENABLE())
state->flags |= PS_STATE_FLAG_PREGR_TODO;
if (PS_DNSBL_TEST_ENABLE())
/*
* Sanity check.
*/
- if ((state->flags & PS_STATE_FLAG_ANY_UPDATE) == 0)
+ if ((state->flags & PS_STATE_MASK_ANY_UPDATE) == 0)
msg_panic("%s: attempt to save a no-update record", myname);
/*
SMTPD_CMD_RCPT, rcpt_cmd, 0,
SMTPD_CMD_DATA, data_cmd, SMTPD_CMD_FLAG_LAST,
SMTPD_CMD_RSET, rset_cmd, SMTPD_CMD_FLAG_LIMIT,
- SMTPD_CMD_NOOP, noop_cmd, SMTPD_CMD_FLAG_LIMIT | SMTPD_CMD_FLAG_PRE_TLS,
- SMTPD_CMD_VRFY, vrfy_cmd, SMTPD_CMD_FLAG_LIMIT,
+ SMTPD_CMD_NOOP, noop_cmd, SMTPD_CMD_FLAG_LIMIT | SMTPD_CMD_FLAG_PRE_TLS | SMTPD_CMD_FLAG_LAST,
+ SMTPD_CMD_VRFY, vrfy_cmd, SMTPD_CMD_FLAG_LIMIT | SMTPD_CMD_FLAG_LAST,
SMTPD_CMD_ETRN, etrn_cmd, SMTPD_CMD_FLAG_LIMIT,
SMTPD_CMD_QUIT, quit_cmd, SMTPD_CMD_FLAG_PRE_TLS,
SMTPD_CMD_XCLIENT, xclient_cmd, 0,
typedef struct EVENT_FDTABLE EVENT_FDTABLE;
struct EVENT_FDTABLE {
- EVENT_NOTIFY_RDWR callback;
+ EVENT_NOTIFY_RDWR_FN callback;
char *context;
};
static EVENT_MASK event_rmask; /* enabled read events */
struct EVENT_TIMER {
time_t when; /* when event is wanted */
- EVENT_NOTIFY_TIME callback; /* callback function */
+ EVENT_NOTIFY_TIME_FN callback; /* callback function */
char *context; /* callback context */
long loop_instance; /* event_loop() call instance */
RING ring; /* linkage */
/* event_enable_read - enable read events */
-void event_enable_read(int fd, EVENT_NOTIFY_RDWR callback, char *context)
+void event_enable_read(int fd, EVENT_NOTIFY_RDWR_FN callback, char *context)
{
const char *myname = "event_enable_read";
EVENT_FDTABLE *fdp;
/* event_enable_write - enable write events */
-void event_enable_write(int fd, EVENT_NOTIFY_RDWR callback, char *context)
+void event_enable_write(int fd, EVENT_NOTIFY_RDWR_FN callback, char *context)
{
const char *myname = "event_enable_write";
EVENT_FDTABLE *fdp;
/* event_request_timer - (re)set timer */
-time_t event_request_timer(EVENT_NOTIFY_TIME callback, char *context, int delay)
+time_t event_request_timer(EVENT_NOTIFY_TIME_FN callback, char *context, int delay)
{
const char *myname = "event_request_timer";
RING *ring;
/* event_cancel_timer - cancel timer */
-int event_cancel_timer(EVENT_NOTIFY_TIME callback, char *context)
+int event_cancel_timer(EVENT_NOTIFY_TIME_FN callback, char *context)
{
const char *myname = "event_cancel_timer";
RING *ring;
/*
* External interface.
*/
-typedef void (*EVENT_NOTIFY_RDWR) (int, char *);
-typedef void (*EVENT_NOTIFY_TIME) (int, char *);
+typedef void (*EVENT_NOTIFY_RDWR_FN) (int, char *);
+typedef void (*EVENT_NOTIFY_TIME_FN) (int, char *);
extern time_t event_time(void);
-extern void event_enable_read(int, EVENT_NOTIFY_RDWR, char *);
-extern void event_enable_write(int, EVENT_NOTIFY_RDWR, char *);
+extern void event_enable_read(int, EVENT_NOTIFY_RDWR_FN, char *);
+extern void event_enable_write(int, EVENT_NOTIFY_RDWR_FN, char *);
extern void event_disable_readwrite(int);
-extern time_t event_request_timer(EVENT_NOTIFY_TIME, char *, int);
-extern int event_cancel_timer(EVENT_NOTIFY_TIME, char *);
+extern time_t event_request_timer(EVENT_NOTIFY_TIME_FN, char *, int);
+extern int event_cancel_timer(EVENT_NOTIFY_TIME_FN, char *);
extern void event_loop(int);
extern void event_drain(int);
extern void event_fork(void);