2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 05:38:06 +00:00

postfix-3.1-20151227

This commit is contained in:
Wietse Venema 2015-12-27 00:00:00 -05:00 committed by Viktor Dukhovni
parent f70b6c876b
commit 370fdfce00
35 changed files with 442 additions and 57 deletions

1
postfix/.indent.pro vendored
View File

@ -249,6 +249,7 @@
-TPLMYSQL
-TPLPGSQL
-TPOSTMAP_KEY_STATE
-TPOST_MAIL_FCLOSE_STATE
-TPOST_MAIL_STATE
-TPRIVATE_STR_TABLE
-TPSC_CALL_BACK_ENTRY

View File

@ -22030,3 +22030,32 @@ Apologies for any names omitted.
Bugfix (introduced: 20151128) bogus queue file parsing error.
File: showq/showq.c.
20151226
Cleanup: postlog(1) now pauses for 1s after reporting a
fatal or panic error. This makes behavior of scripts such
as postfix-script consistent with built-in error messages.
File: postlog/postlog.c.
20151227
Robustness: don't allow for whitespace in command-line
arguments. Files; postfix-install, conf/post-install.
Robustness: added a comment to discourage people who keep
adding code that calls gethostbyname() to determine the
default myhostname setting. This is a mistake: all Postfix
programs will hang when the DNS is unavailable. File:
global/mail_params.c.
Safety: a limit on the number of address verification probes
in the active queue (address_verify_pending_request_limit),
by default 1/4 of the active queue maximum size. The queue
manager tempfails probe messages that exceed the limit.
Files: mantools/postlink, proto/postconf.proto, cleanup/cleanup.h,
cleanup/cleanup_envelope.c, cleanup/cleanup_out_recipient.c,
cleanup/cleanup_state.c, global/mail_params.h, global/post_mail.c,
global/post_mail.h, global/verify.c, oqmgr/qmgr.c, oqmgr/qmgr.h,
oqmgr/qmgr_message.c, qmgr/qmgr.c, qmgr/qmgr.h,
qmgr/qmgr_message.c, verify/verify.c.

View File

@ -16,6 +16,23 @@ specifies the release date of a stable release or snapshot release.
If you upgrade from Postfix 2.11 or earlier, read RELEASE_NOTES-3.0
before proceeding.
Major changes with snaphot 20151227
===================================
This introduces a safety limit on the number of address verification
probes in the active queue (address_verify_pending_request_limit),
by default 1/4 of the active queue maximum size. The queue manager
enforces the limit by tempfailing probe messages that exceed the
limit. The design avoids dependency on global counters that may get
out of sync after a process crashes.
Tempfailing requests in this manner is not as bad as one might
think. The Postfix verify cache proactively updates active addresses
well before they expire. The address_verify_pending_request_limit
affects only unknown addresses and inactive addresses that have
expired (by default, after 31 days).
Incompatible change with Postfix snapshot 20150721
--------------------------------------------------

View File

@ -2,6 +2,12 @@ Wish list:
Things to do before the stable release:
Viktor's bitrot patches.
Not: SMTPUTF8 auto-conversion of lookups/matches.
---------------------end of Postfix 3.1.0 todo list
Spell-check, double-word check, and HTML validator check.
Disable -DSNAPSHOT and -DNONPROD in makedefs.
@ -17,7 +23,8 @@ Wish list:
smtp_reply_footer() undoable.
Type-checking wrappers for htable(3), ctable(3) and other
modules that take and return a void* pointer.
modules that take and return a void* pointer. This is
the next best thing to C++ style HTABLE<payload_type>.
TLS certificate provenance: indicate whether a subject
name/issuer are verified or not (for example, change the
@ -76,9 +83,8 @@ Wish list:
Log command=good/bad statistics in postscreen?
Implement smtpd_client_auth_rate limit?
Make the access map BCC action consistent with header_checks.
Remember multiple access map BCC actions, for consistency
with header_checks.
smtpd_checks tests either must use a DNS dummy resolver
(override the res_search API) or all names must be under
@ -93,11 +99,6 @@ Wish list:
along with other header-extracted information, and forward
the Message-ID in the bounce server notification request.
Find a way to show non-default OPT, DEBUG etc. settings at
the top of the makedefs.out file.
Update smtputf8_enable in postconf(5)
Clobber ORCPT when sender is owner-mumble?
Add milter_mumble_macros to the list of per-macro features.
@ -114,9 +115,6 @@ Wish list:
can return error descriptions instead of terminating with
a fatal error.
Make sure that proxy: can handle random:, pipe:, and other
multimaps.
Add a switch to consider postscreen deep protocol tests as
"completed" when receiving "RSET" after "RCPT TO" and the
session has passed all tests up to that point. RSET becomes

View File

@ -234,6 +234,8 @@ obsolete=; keep_list=;
for arg
do
case $arg in
*[" "]*) echo $0: "Error: argument contains whitespace: '$arg'"
exit 1;;
*=*) IFS= eval $arg; IFS="$BACKUP_IFS";;
create-missing) create=1;;
set-perm*) create=1; set_perms=1;;

View File

@ -314,9 +314,15 @@ OQMGR(8) OQMGR(8)
The time limit for the queue manager to send or receive informa-
tion over an internal communication channel.
Available in Postfix version 3.1 and later:
<b><a href="postconf.5.html#address_verify_pending_request_limit">address_verify_pending_request_limit</a> (see 'postconf -d' output)</b>
A safety limit that prevents address verification requests from
overwhelming the Postfix queue.
<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 <a href="master.5.html">master.cf</a> con-
The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
figuration files.
<b><a href="postconf.5.html#defer_transports">defer_transports</a> (empty)</b>
@ -324,11 +330,11 @@ OQMGR(8) OQMGR(8)
mail unless someone issues "<b>sendmail -q</b>" or equivalent.
<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 point when log-
The maximal number of digits after the decimal point when log-
ging sub-second delay values.
<b><a href="postconf.5.html#helpful_warnings">helpful_warnings</a> (yes)</b>
Log warnings about problematic configuration settings, and pro-
Log warnings about problematic configuration settings, and pro-
vide helpful suggestions.
<b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
@ -344,14 +350,14 @@ OQMGR(8) OQMGR(8)
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" becomes, for example, "post-
The mail system name that is prepended to the process name in
syslog records, so that "smtpd" becomes, for example, "post-
fix/smtpd".
Available in Postfix version 3.0 and later:
<b><a href="postconf.5.html#confirm_delay_cleared">confirm_delay_cleared</a> (no)</b>
After sending a "your message is delayed" notification, inform
After sending a "your message is delayed" notification, inform
the sender when the delay clears up.
<b>FILES</b>

View File

@ -294,6 +294,23 @@ This feature is available in Postfix 2.1 and later.
</p>
</DD>
<DT><b><a name="address_verify_pending_request_limit">address_verify_pending_request_limit</a>
(default: see "postconf -d" output)</b></DT><DD>
<p> A safety limit that prevents address verification requests from
overwhelming the Postfix queue. By default, the number of pending
requests is limited to 1/4 of the <a href="QSHAPE_README.html#active_queue">active queue</a> maximum size
(<a href="postconf.5.html#qmgr_message_active_limit">qmgr_message_active_limit</a>). The queue manager enforces the limit
by tempfailing requests that exceed the limit. This affects only
unknown addresses and inactive addresses that have expired, because
the <a href="verify.8.html">verify(8)</a> daemon automatically refreshes an active address
before it expires. </p>
<p> This feature is available in Postfix 3.1 and later. </p>
</DD>
<DT><b><a name="address_verify_poll_count">address_verify_poll_count</a>

View File

@ -31,9 +31,11 @@ POSTLOG(1) POSTLOG(1)
<b>-i</b> Include the process ID in the logging tag.
<b>-p</b> <i>priority</i>
Specifies the logging severity: <b>info</b> (default), <b>warn</b>, <b>error</b>,
<b>fatal</b>, or <b>panic</b>.
<b>-p</b> <i>priority</i> (default: <b>info</b>)
Specifies the logging severity: <b>info</b>, <b>warn</b>, <b>error</b>, <b>fatal</b>, or
<b>panic</b>. With Postfix 3.1 and later, the program will pause for 1
second after reporting a <b>fatal</b> or <b>panic</b> condition, just like
other Postfix programs.
<b>-t</b> <i>tag</i> Specifies the logging tag, that is, the identifying name that
appears at the beginning of each logging record. A default tag

View File

@ -376,9 +376,15 @@ QMGR(8) QMGR(8)
The time limit for the queue manager to send or receive informa-
tion over an internal communication channel.
Available in Postfix version 3.1 and later:
<b><a href="postconf.5.html#address_verify_pending_request_limit">address_verify_pending_request_limit</a> (see 'postconf -d' output)</b>
A safety limit that prevents address verification requests from
overwhelming the Postfix queue.
<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 <a href="master.5.html">master.cf</a> con-
The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
figuration files.
<b><a href="postconf.5.html#defer_transports">defer_transports</a> (empty)</b>
@ -386,11 +392,11 @@ QMGR(8) QMGR(8)
mail unless someone issues "<b>sendmail -q</b>" or equivalent.
<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 point when log-
The maximal number of digits after the decimal point when log-
ging sub-second delay values.
<b><a href="postconf.5.html#helpful_warnings">helpful_warnings</a> (yes)</b>
Log warnings about problematic configuration settings, and pro-
Log warnings about problematic configuration settings, and pro-
vide helpful suggestions.
<b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
@ -406,14 +412,14 @@ QMGR(8) QMGR(8)
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" becomes, for example, "post-
The mail system name that is prepended to the process name in
syslog records, so that "smtpd" becomes, for example, "post-
fix/smtpd".
Available in Postfix version 3.0 and later:
<b><a href="postconf.5.html#confirm_delay_cleared">confirm_delay_cleared</a> (no)</b>
After sending a "your message is delayed" notification, inform
After sending a "your message is delayed" notification, inform
the sender when the delay clears up.
<b>FILES</b>

View File

@ -32,9 +32,12 @@ Read the \fBmain.cf\fR configuration file in the named directory
instead of the default configuration directory.
.IP \fB\-i\fR
Include the process ID in the logging tag.
.IP "\fB\-p \fIpriority\fR"
Specifies the logging severity: \fBinfo\fR (default), \fBwarn\fR,
\fBerror\fR, \fBfatal\fR, or \fBpanic\fR.
.IP "\fB\-p \fIpriority\fR (default: \fBinfo\fR)"
Specifies the logging severity: \fBinfo\fR, \fBwarn\fR,
\fBerror\fR, \fBfatal\fR, or \fBpanic\fR. With Postfix 3.1
and later, the program will pause for 1 second after reporting
a \fBfatal\fR or \fBpanic\fR condition, just like other
Postfix programs.
.IP "\fB\-t \fItag\fR"
Specifies the logging tag, that is, the identifying name that
appears at the beginning of each logging record. A default tag

View File

@ -177,6 +177,17 @@ be refreshed.
Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
.PP
This feature is available in Postfix 2.1 and later.
.SH address_verify_pending_request_limit (default: see "postconf \-d" output)
A safety limit that prevents address verification requests from
overwhelming the Postfix queue. By default, the number of pending
requests is limited to 1/4 of the active queue maximum size
(qmgr_message_active_limit). The queue manager enforces the limit
by tempfailing requests that exceed the limit. This affects only
unknown addresses and inactive addresses that have expired, because
the \fBverify\fR(8) daemon automatically refreshes an active address
before it expires.
.PP
This feature is available in Postfix 3.1 and later.
.SH address_verify_poll_count (default: normal: 3, overload: 1)
How many times to query the \fBverify\fR(8) service for the completion
of an address verification request in progress.

View File

@ -308,6 +308,11 @@ a request before it is terminated by a built\-in watchdog timer.
.IP "\fBqmgr_ipc_timeout (60s)\fR"
The time limit for the queue manager to send or receive information
over an internal communication channel.
.PP
Available in Postfix version 3.1 and later:
.IP "\fBaddress_verify_pending_request_limit (see 'postconf -d' output)\fR"
A safety limit that prevents address verification requests
from overwhelming the Postfix queue.
.SH "MISCELLANEOUS CONTROLS"
.na
.nf

View File

@ -356,6 +356,11 @@ a request before it is terminated by a built\-in watchdog timer.
.IP "\fBqmgr_ipc_timeout (60s)\fR"
The time limit for the queue manager to send or receive information
over an internal communication channel.
.PP
Available in Postfix version 3.1 and later:
.IP "\fBaddress_verify_pending_request_limit (see 'postconf -d' output)\fR"
A safety limit that prevents address verification requests
from overwhelming the Postfix queue.
.SH "MISCELLANEOUS CONTROLS"
.na
.nf

View File

@ -89,6 +89,7 @@ while (<>) {
s;\baddress_verify_service_name\b;<a href="postconf.5.html#address_verify_service_name">$&</a>;g;
s;\baddress_verify_transport_maps\b;<a href="postconf.5.html#address_verify_transport_maps">$&</a>;g;
s;\baddress_verify_virtual_transport\b;<a href="postconf.5.html#address_verify_virtual_transport">$&</a>;g;
s;\baddress_verify_pending_request_limit\b;<a href="postconf.5.html#address_verify_pending_request_limit">$&</a>;g;
s;\bsmtp_address_verify_target\b;<a href="postconf.5.html#smtp_address_verify_target">$&</a>;g;
s;\blmtp_address_verify_target\b;<a href="postconf.5.html#lmtp_address_verify_target">$&</a>;g;
s;\balias_database\b;<a href="postconf.5.html#alias_database">$&</a>;g;

View File

@ -216,10 +216,11 @@ USAGE="Usage: $0 [name=value] [option]
for arg
do
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;;
*[" "]*) echo "$0: Error: argument contains whitespace: '$arg'"; exit 1;;
*=*) 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
done
@ -597,14 +598,14 @@ do
esac
done
# Don't allow whitespace in parameter settings.
# Don't allow space or tab in parameter settings.
for name in $CONFIG_PARAMS sample_directory
do
eval junk=\$$name
case "$junk" in
*" "*|*" "*) echo $0: Error: $name value contains whitespace: "'$junk'" 1>&2
exit 1;;
*"[ ]"*) echo "$0: Error: $name value contains whitespace: '$junk'" 1>&2
exit 1;;
esac
done

View File

@ -16592,3 +16592,16 @@ clients). </p>
<p>
This feature is available in Postfix 3.1 and later.
</p>
%PARAM address_verify_pending_request_limit see "postconf -d" output
<p> A safety limit that prevents address verification requests from
overwhelming the Postfix queue. By default, the number of pending
requests is limited to 1/4 of the active queue maximum size
(qmgr_message_active_limit). The queue manager enforces the limit
by tempfailing requests that exceed the limit. This affects only
unknown addresses and inactive addresses that have expired, because
the verify(8) daemon automatically refreshes an active address
before it expires. </p>
<p> This feature is available in Postfix 3.1 and later. </p>

View File

@ -760,7 +760,9 @@ cleanup_envelope.o: ../../include/attr.h
cleanup_envelope.o: ../../include/been_here.h
cleanup_envelope.o: ../../include/check_arg.h
cleanup_envelope.o: ../../include/cleanup_user.h
cleanup_envelope.o: ../../include/deliver_request.h
cleanup_envelope.o: ../../include/dict.h
cleanup_envelope.o: ../../include/dsn.h
cleanup_envelope.o: ../../include/dsn_mask.h
cleanup_envelope.o: ../../include/header_body_checks.h
cleanup_envelope.o: ../../include/header_opts.h
@ -775,6 +777,7 @@ cleanup_envelope.o: ../../include/match_list.h
cleanup_envelope.o: ../../include/milter.h
cleanup_envelope.o: ../../include/mime_state.h
cleanup_envelope.o: ../../include/msg.h
cleanup_envelope.o: ../../include/msg_stats.h
cleanup_envelope.o: ../../include/myflock.h
cleanup_envelope.o: ../../include/mymalloc.h
cleanup_envelope.o: ../../include/nvtable.h
@ -1161,6 +1164,7 @@ cleanup_out_recipient.o: ../../include/sys_defs.h
cleanup_out_recipient.o: ../../include/tok822.h
cleanup_out_recipient.o: ../../include/trace.h
cleanup_out_recipient.o: ../../include/vbuf.h
cleanup_out_recipient.o: ../../include/verify.h
cleanup_out_recipient.o: ../../include/vstream.h
cleanup_out_recipient.o: ../../include/vstring.h
cleanup_out_recipient.o: cleanup.h

View File

@ -64,6 +64,7 @@ typedef struct CLEANUP_STATE {
ARGV *auto_hdrs; /* MTA's own header(s) */
ARGV *hbc_rcpt; /* header/body checks BCC addresses */
int flags; /* processing options, status flags */
int tflags; /* User- or MTA-requested tracing */
int qmgr_opts; /* qmgr processing options */
int errs; /* any badness experienced */
int err_mask; /* allowed badness */

View File

@ -68,6 +68,7 @@
#include <dsn_mask.h>
#include <rec_attr_map.h>
#include <smtputf8.h>
#include <deliver_request.h>
/* Application-specific. */
@ -488,6 +489,16 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type,
return;
}
}
if (strcmp(attr_name, MAIL_ATTR_TRACE_FLAGS) == 0) {
if (!alldig(attr_value)) {
msg_warn("%s: message rejected: bad TFLAG record <%.200s>",
state->queue_id, buf);
state->errs |= CLEANUP_STAT_BAD;
return;
}
if (state->tflags == 0)
state->tflags = DEL_REQ_TRACE_FLAGS(atoi(attr_value));
}
nvtable_update(state->attr, attr_name, attr_value);
cleanup_out(state, type, buf, len);
return;

View File

@ -76,6 +76,7 @@
#include <recipient_list.h>
#include <dsn.h>
#include <trace.h>
#include <verify.h>
#include <mail_queue.h> /* cleanup_trace_path */
#include <mail_proto.h>
#include <msg_stats.h>
@ -104,6 +105,20 @@ static void cleanup_trace_append(CLEANUP_STATE *state, RECIPIENT *rcpt,
}
}
/* cleanup_verify_append - update verify daemon */
static void cleanup_verify_append(CLEANUP_STATE *state, RECIPIENT *rcpt,
DSN *dsn, int verify_status)
{
MSG_STATS stats;
if (verify_append(state->queue_id, CLEANUP_MSG_STATS(&stats, state),
rcpt, "none", dsn, verify_status) != 0) {
msg_warn("%s: verify service update error", state->queue_id);
state->errs |= CLEANUP_STAT_WRITE;
}
}
/* cleanup_out_recipient - envelope recipient output filter */
void cleanup_out_recipient(CLEANUP_STATE *state,
@ -193,6 +208,15 @@ void cleanup_out_recipient(CLEANUP_STATE *state,
* recipient information, also ignore differences in DSN attributes. We
* do, however, keep the DSN attributes of the recipient that survives
* duplicate elimination.
*
* In the case of a verify(8) request for a one-to-many alias, declare the
* alias address as "deliverable". Do not verify the individual addresses
* in the expansion because that results in multiple verify(8) updates
* for one verify(8) request.
*
* Multiple verify(8) updates for one verify(8) request would overwrite
* each other's status, and if the last status update is "undeliverable",
* then the whole alias is flagged as undeliverable.
*/
else {
RECIPIENT rcpt;
@ -200,6 +224,14 @@ void cleanup_out_recipient(CLEANUP_STATE *state,
argv = cleanup_map1n_internal(state, recip, cleanup_virt_alias_maps,
cleanup_ext_prop_mask & EXT_PROP_VIRTUAL);
if (argv->argc > 1 && (state->tflags & DEL_REQ_FLAG_MTA_VRFY)) {
(void) DSN_SIMPLE(&dsn, "2.0.0", "aliased to multiple recipients");
dsn.action = "deliverable";
RECIPIENT_ASSIGN(&rcpt, 0, dsn_orcpt, dsn_notify, orcpt, recip);
cleanup_verify_append(state, &rcpt, &dsn, DEL_RCPT_STAT_OK);
argv_free(argv);
return;
}
if ((dsn_notify & DSN_NOTIFY_SUCCESS)
&& (argv->argc > 1 || strcmp(recip, argv->argv[0]) != 0)) {
(void) DSN_SIMPLE(&dsn, "2.0.0", "alias expanded");

View File

@ -81,6 +81,7 @@ CLEANUP_STATE *cleanup_state_alloc(VSTREAM *src)
state->auto_hdrs = argv_alloc(1);
state->hbc_rcpt = 0;
state->flags = 0;
state->tflags = 0;
state->qmgr_opts = 0;
state->errs = 0;
state->err_mask = 0;

View File

@ -368,13 +368,21 @@ static const char *check_myhostname(void)
/*
* If the local machine name is not in FQDN form, try to append the
* contents of $mydomain. Use a default domain as a final workaround.
*
* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - IT MAKES EVERY POSTFIX
* PROGRAM HANG WHEN DNS SERVICE IS UNAVAILABLE. IF YOU DON'T LIKE THE
* DEFAULT, THEN EDIT MAIN.CF.
*/
name = get_hostname();
/* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
if ((dot = strchr(name, '.')) == 0) {
/* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
if ((domain = mail_conf_lookup_eval(VAR_MYDOMAIN)) == 0)
domain = DEF_MYDOMAIN;
/* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
name = concatenate(name, ".", domain, (char *) 0);
}
/* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
return (name);
}
@ -386,9 +394,16 @@ static const char *check_mydomainname(void)
/*
* Use a default domain when the hostname is not a FQDN ("foo").
*
* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - IT MAKES EVERY POSTFIX
* PROGRAM HANG WHEN DNS SERVICE IS UNAVAILABLE. IF YOU DON'T LIKE THE
* DEFAULT, THEN EDIT MAIN.CF.
*/
/* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
if ((dot = strchr(var_myhostname, '.')) == 0)
/* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
return (DEF_MYDOMAIN);
/* DO NOT CALL GETHOSTBYNAME OR GETNAMEINFO HERE - EDIT MAIN.CF */
return (dot + 1);
}

View File

@ -2706,6 +2706,10 @@ extern int var_scache_ttl_lim;
#define DEF_SCACHE_STAT_TIME "600s"
extern int var_scache_stat_time;
#define VAR_VRFY_PEND_LIMIT "address_verify_pending_request_limit"
#define DEF_VRFY_PEND_LIMIT (DEF_QMGR_ACT_LIMIT / 4)
extern int var_vrfy_pend_limit;
/*
* Address verification service.
*/

View File

@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
#define MAIL_RELEASE_DATE "20151218"
#define MAIL_RELEASE_DATE "20151227"
#define MAIL_VERSION_NUMBER "3.1"
#ifdef SNAPSHOT

View File

@ -54,6 +54,11 @@
/*
/* int post_mail_fclose(stream)
/* VSTREAM *STREAM;
/*
/* void post_mail_fclose_async(stream, notify, context)
/* VSTREAM *stream;
/* void (*notify)(int status, void *context);
/* void *context;
/* DESCRIPTION
/* This module provides a convenient interface for the most
/* common case of sending one message to one recipient. It
@ -91,6 +96,11 @@
/*
/* post_mail_fclose() completes the posting of a message.
/*
/* post_mail_fclose_async() completes the posting of a message
/* and upon completion invokes the caller-specified notify
/* routine, with the cleanup status and caller-specified context
/* as arguments.
/*
/* Arguments:
/* .IP sender
/* The sender envelope address. It is up to the application
@ -187,6 +197,16 @@ typedef struct {
VSTRING *queue_id;
} POST_MAIL_STATE;
/*
* Call-back state for asynchronous close requests.
*/
typedef struct {
int status;
VSTREAM *stream;
POST_MAIL_FCLOSE_NOTIFY notify;
void *context;
} POST_MAIL_FCLOSE_STATE;
/* post_mail_init - initial negotiations */
static void post_mail_init(VSTREAM *stream, const char *sender,
@ -205,6 +225,13 @@ static void post_mail_init(VSTREAM *stream, const char *sender,
GETTIMEOFDAY(&now);
date = mail_date(now.tv_sec);
/*
* XXX Don't flush buffers while sending the initial message records.
* That would cause deadlock between verify(8) and cleanup(8) servers.
*/
vstream_control(stream, VSTREAM_CTL_BUFSIZE, 2 * VSTREAM_BUFSIZE,
VSTREAM_CTL_END);
/*
* Negotiate with the cleanup service. Give up if we can't agree.
*/
@ -435,3 +462,94 @@ int post_mail_fclose(VSTREAM *cleanup)
(void) vstream_fclose(cleanup);
return (status);
}
/* post_mail_fclose_event - event handler */
static void post_mail_fclose_event(int event, void *context)
{
POST_MAIL_FCLOSE_STATE *state = (POST_MAIL_FCLOSE_STATE *) context;
int status = state->status;
switch (event) {
/*
* Final server reply. Pick up the completion status.
*/
case EVENT_READ:
if (status == 0) {
if (vstream_ferror(state->stream) != 0
|| attr_scan(state->stream, ATTR_FLAG_MISSING,
ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status,
ATTR_TYPE_END) != 1)
status = CLEANUP_STAT_WRITE;
}
break;
/*
* No response or error.
*/
default:
msg_warn("error talking to service: %s", var_cleanup_service);
status = CLEANUP_STAT_WRITE;
break;
}
/*
* Stop the watchdog timer, and disable further read events that end up
* calling this function.
*/
event_cancel_timer(post_mail_fclose_event, context);
event_disable_readwrite(vstream_fileno(state->stream));
/*
* Notify the requestor and clean up.
*/
state->notify(status, state->context);
(void) vstream_fclose(state->stream);
myfree((void *) state);
}
/* post_mail_fclose_async - finish posting of message */
void post_mail_fclose_async(VSTREAM *stream,
void (*notify) (int status, void *context),
void *context)
{
POST_MAIL_FCLOSE_STATE *state;
int status = 0;
/*
* Send the message end marker only when there were no errors.
*/
if (vstream_ferror(stream) != 0) {
status = CLEANUP_STAT_WRITE;
} else {
rec_fputs(stream, REC_TYPE_XTRA, "");
rec_fputs(stream, REC_TYPE_END, "");
if (vstream_fflush(stream))
status = CLEANUP_STAT_WRITE;
}
/*
* Bundle up the suspended state.
*/
state = (POST_MAIL_FCLOSE_STATE *) mymalloc(sizeof(*state));
state->status = status;
state->stream = stream;
state->notify = notify;
state->context = context;
/*
* To keep interfaces as simple as possible we report all errors via the
* same interface as all successes.
*/
if (status == 0) {
event_enable_read(vstream_fileno(stream), post_mail_fclose_event,
(void *) state);
event_request_timer(post_mail_fclose_event, (void *) state,
var_daemon_timeout);
} else {
event_request_timer(post_mail_fclose_event, (void *) state, 0);
}
}

View File

@ -28,7 +28,7 @@
/*
* External interface.
*/
typedef void (*POST_MAIL_NOTIFY)(VSTREAM *, void *);
typedef void (*POST_MAIL_NOTIFY) (VSTREAM *, void *);
extern VSTREAM *post_mail_fopen(const char *, const char *, int, int, int, VSTRING *);
extern VSTREAM *post_mail_fopen_nowait(const char *, const char *, int, int, int, VSTRING *);
extern void post_mail_fopen_async(const char *, const char *, int, int, int, VSTRING *, POST_MAIL_NOTIFY, void *);
@ -36,6 +36,8 @@ extern int PRINTFLIKE(2, 3) post_mail_fprintf(VSTREAM *, const char *,...);
extern int post_mail_fputs(VSTREAM *, const char *);
extern int post_mail_buffer(VSTREAM *, const char *, int);
extern int post_mail_fclose(VSTREAM *);
typedef void (*POST_MAIL_FCLOSE_NOTIFY) (int, void *);
extern void post_mail_fclose_async(VSTREAM *, POST_MAIL_FCLOSE_NOTIFY, void *);
#define POST_MAIL_BUFFER(v, b) \
post_mail_buffer((v), vstring_str(b), VSTRING_LEN(b))

View File

@ -102,8 +102,9 @@ int verify_append(const char *queue_id, MSG_STATS *stats,
if (var_verify_neg_cache || vrfy_stat == DEL_RCPT_STAT_OK) {
req_stat = verify_clnt_update(recipient->orig_addr, vrfy_stat,
my_dsn.reason);
/* Two verify updates for one verify request! */
if (req_stat == VRFY_STAT_OK
&& strcasecmp_utf8(recipient->address, recipient->orig_addr) != 0)
&& strcasecmp_utf8(recipient->address, recipient->orig_addr) != 0)
req_stat = verify_clnt_update(recipient->address, vrfy_stat,
my_dsn.reason);
} else {

View File

@ -272,6 +272,11 @@
/* .IP "\fBqmgr_ipc_timeout (60s)\fR"
/* The time limit for the queue manager to send or receive information
/* over an internal communication channel.
/* .PP
/* Available in Postfix version 3.1 and later:
/* .IP "\fBaddress_verify_pending_request_limit (see 'postconf -d' output)\fR"
/* A safety limit that prevents address verification requests
/* from overwhelming the Postfix queue.
/* MISCELLANEOUS CONTROLS
/* .ad
/* .fi
@ -405,6 +410,7 @@ char *var_def_filter_nexthop;
int var_qmgr_daemon_timeout;
int var_qmgr_ipc_timeout;
int var_dsn_delay_cleared;
int var_vrfy_pend_limit;
static QMGR_SCAN *qmgr_scans[2];
@ -664,6 +670,7 @@ int main(int argc, char **argv)
VAR_LOCAL_RCPT_LIMIT, DEF_LOCAL_RCPT_LIMIT, &var_local_rcpt_lim, 0, 0,
VAR_LOCAL_CON_LIMIT, DEF_LOCAL_CON_LIMIT, &var_local_con_lim, 0, 0,
VAR_CONC_COHORT_LIM, DEF_CONC_COHORT_LIM, &var_conc_cohort_limit, 0, 0,
VAR_VRFY_PEND_LIMIT, DEF_VRFY_PEND_LIMIT, &var_vrfy_pend_limit, 1, 0,
0,
};
static const CONFIG_BOOL_TABLE bool_table[] = {

View File

@ -330,6 +330,7 @@ struct QMGR_MESSAGE {
extern int qmgr_message_count;
extern int qmgr_recipient_count;
extern int qmgr_vrfy_pend_count;
extern void qmgr_message_free(QMGR_MESSAGE *);
extern void qmgr_message_update_warn(QMGR_MESSAGE *);

View File

@ -8,6 +8,7 @@
/*
/* int qmgr_message_count;
/* int qmgr_recipient_count;
/* int qmgr_vrfy_pend_count;
/*
/* QMGR_MESSAGE *qmgr_message_alloc(class, name, qflags, mode)
/* const char *class;
@ -38,6 +39,13 @@
/* of in-core recipient structures (i.e. the sum of all recipients
/* in all in-core message structures).
/*
/* qmgr_vrfy_pend_count is a global counter for the total
/* number of in-core message structures that are associated
/* with an address verification request. Requests that exceed
/* the address_verify_pending_limit are deferred immediately.
/* This is a backup mechanism for a more refined enforcement
/* mechanism in the verify(8) daemon.
/*
/* qmgr_message_alloc() creates an in-core message structure
/* with sender and recipient information taken from the named queue
/* file. A null result means the queue file could not be read or
@ -136,6 +144,7 @@
int qmgr_message_count;
int qmgr_recipient_count;
int qmgr_vrfy_pend_count;
/* qmgr_message_create - create in-core message structure */
@ -705,11 +714,15 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
* after the logfile is deleted.
*/
else if (strcmp(name, MAIL_ATTR_TRACE_FLAGS) == 0) {
message->tflags = DEL_REQ_TRACE_FLAGS(atoi(value));
if (message->tflags == DEL_REQ_FLAG_RECORD)
message->tflags_offset = curr_offset;
else
message->tflags_offset = 0;
if (message->tflags == 0) {
message->tflags = DEL_REQ_TRACE_FLAGS(atoi(value));
if (message->tflags == DEL_REQ_FLAG_RECORD)
message->tflags_offset = curr_offset;
else
message->tflags_offset = 0;
if ((message->tflags & DEL_REQ_FLAG_MTA_VRFY) != 0)
qmgr_vrfy_pend_count++;
}
}
continue;
}
@ -1107,6 +1120,14 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
}
}
/*
* Safety: defer excess address verification requests.
*/
if ((message->tflags & DEL_REQ_FLAG_MTA_VRFY) != 0
&& qmgr_vrfy_pend_count > var_vrfy_pend_limit)
QMGR_REDIRECT(&reply, MAIL_SERVICE_RETRY,
"4.3.2 Too many address verification requests");
/*
* Look up or instantiate the proper transport.
*/
@ -1310,6 +1331,8 @@ void qmgr_message_free(QMGR_MESSAGE *message)
myfree(message->rewrite_context);
recipient_list_free(&message->rcpt_list);
qmgr_message_count--;
if ((message->tflags & DEL_REQ_FLAG_MTA_VRFY) != 0)
qmgr_vrfy_pend_count--;
myfree((void *) message);
}

View File

@ -26,9 +26,12 @@
/* instead of the default configuration directory.
/* .IP \fB-i\fR
/* Include the process ID in the logging tag.
/* .IP "\fB-p \fIpriority\fR"
/* Specifies the logging severity: \fBinfo\fR (default), \fBwarn\fR,
/* \fBerror\fR, \fBfatal\fR, or \fBpanic\fR.
/* .IP "\fB-p \fIpriority\fR (default: \fBinfo\fR)"
/* Specifies the logging severity: \fBinfo\fR, \fBwarn\fR,
/* \fBerror\fR, \fBfatal\fR, or \fBpanic\fR. With Postfix 3.1
/* and later, the program will pause for 1 second after reporting
/* a \fBfatal\fR or \fBpanic\fR condition, just like other
/* Postfix programs.
/* .IP "\fB-t \fItag\fR"
/* Specifies the logging tag, that is, the identifying name that
/* appears at the beginning of each logging record. A default tag
@ -261,5 +264,11 @@ int main(int argc, char **argv)
} else {
log_stream(level, VSTREAM_IN);
}
/*
* Consistency with msg(3) functions.
*/
if (level >= MSG_FATAL)
sleep(1);
exit(0);
}

View File

@ -318,6 +318,11 @@
/* .IP "\fBqmgr_ipc_timeout (60s)\fR"
/* The time limit for the queue manager to send or receive information
/* over an internal communication channel.
/* .PP
/* Available in Postfix version 3.1 and later:
/* .IP "\fBaddress_verify_pending_request_limit (see 'postconf -d' output)\fR"
/* A safety limit that prevents address verification requests
/* from overwhelming the Postfix queue.
/* MISCELLANEOUS CONTROLS
/* .ad
/* .fi
@ -465,6 +470,7 @@ char *var_def_filter_nexthop;
int var_qmgr_daemon_timeout;
int var_qmgr_ipc_timeout;
int var_dsn_delay_cleared;
int var_vrfy_pend_limit;
static QMGR_SCAN *qmgr_scans[2];
@ -739,6 +745,7 @@ int main(int argc, char **argv)
VAR_LOCAL_RCPT_LIMIT, DEF_LOCAL_RCPT_LIMIT, &var_local_rcpt_lim, 0, 0,
VAR_LOCAL_CON_LIMIT, DEF_LOCAL_CON_LIMIT, &var_local_con_lim, 0, 0,
VAR_CONC_COHORT_LIM, DEF_CONC_COHORT_LIM, &var_conc_cohort_limit, 0, 0,
VAR_VRFY_PEND_LIMIT, DEF_VRFY_PEND_LIMIT, &var_vrfy_pend_limit, 1, 0,
0,
};
static const CONFIG_BOOL_TABLE bool_table[] = {

View File

@ -380,6 +380,7 @@ struct QMGR_MESSAGE {
extern int qmgr_message_count;
extern int qmgr_recipient_count;
extern int qmgr_vrfy_pend_count;
extern void qmgr_message_free(QMGR_MESSAGE *);
extern void qmgr_message_update_warn(QMGR_MESSAGE *);

View File

@ -8,6 +8,7 @@
/*
/* int qmgr_message_count;
/* int qmgr_recipient_count;
/* int qmgr_vrfy_pend_count;
/*
/* QMGR_MESSAGE *qmgr_message_alloc(class, name, qflags, mode)
/* const char *class;
@ -38,6 +39,13 @@
/* of in-core recipient structures (i.e. the sum of all recipients
/* in all in-core message structures).
/*
/* qmgr_vrfy_pend_count is a global counter for the total
/* number of in-core message structures that are associated
/* with an address verification request. Requests that exceed
/* the address_verify_pending_limit are deferred immediately.
/* This is a backup mechanism for a more refined enforcement
/* mechanism in the verify(8) daemon.
/*
/* qmgr_message_alloc() creates an in-core message structure
/* with sender and recipient information taken from the named queue
/* file. A null result means the queue file could not be read or
@ -145,6 +153,7 @@
int qmgr_message_count;
int qmgr_recipient_count;
int qmgr_vrfy_pend_count;
/* qmgr_message_create - create in-core message structure */
@ -746,11 +755,15 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
* after the logfile is deleted.
*/
else if (strcmp(name, MAIL_ATTR_TRACE_FLAGS) == 0) {
message->tflags = DEL_REQ_TRACE_FLAGS(atoi(value));
if (message->tflags == DEL_REQ_FLAG_RECORD)
message->tflags_offset = curr_offset;
else
message->tflags_offset = 0;
if (message->tflags == 0) {
message->tflags = DEL_REQ_TRACE_FLAGS(atoi(value));
if (message->tflags == DEL_REQ_FLAG_RECORD)
message->tflags_offset = curr_offset;
else
message->tflags_offset = 0;
if ((message->tflags & DEL_REQ_FLAG_MTA_VRFY) != 0)
qmgr_vrfy_pend_count++;
}
}
continue;
}
@ -1166,6 +1179,14 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
}
}
/*
* Safety: defer excess address verification requests.
*/
if ((message->tflags & DEL_REQ_FLAG_MTA_VRFY) != 0
&& qmgr_vrfy_pend_count > var_vrfy_pend_limit)
QMGR_REDIRECT(&reply, MAIL_SERVICE_RETRY,
"4.3.2 Too many address verification requests");
/*
* Look up or instantiate the proper transport.
*/
@ -1431,6 +1452,8 @@ void qmgr_message_free(QMGR_MESSAGE *message)
myfree(message->rewrite_context);
recipient_list_free(&message->rcpt_list);
qmgr_message_count--;
if ((message->tflags & DEL_REQ_FLAG_MTA_VRFY) != 0)
qmgr_vrfy_pend_count--;
myfree((void *) message);
}

View File

@ -400,9 +400,17 @@ static void verify_update_service(VSTREAM *client_stream)
vstring_free(text);
}
/* verify_post_mail_fclose_action - callback */
static void verify_post_mail_fclose_action(int unused_status,
void *unused_context)
{
/* no code here, we just need to avoid blocking in post_mail_fclose() */
}
/* verify_post_mail_action - callback */
static void verify_post_mail_action(VSTREAM *stream, void *unused_context)
static void verify_post_mail_action(VSTREAM *stream, void *context)
{
/*
@ -410,7 +418,7 @@ static void verify_post_mail_action(VSTREAM *stream, void *unused_context)
* deferred, or bounced.
*/
if (stream != 0)
post_mail_fclose(stream);
post_mail_fclose_async(stream, verify_post_mail_fclose_action, context);
}
/* verify_query_service - query address status */
@ -500,8 +508,8 @@ static void verify_query_service(VSTREAM *client_stream)
(addr_status != DEL_RCPT_STAT_OK && updated + var_verify_neg_try < now)
if (now - probed > PROBE_TTL
&& (POSITIVE_REFRESH_NEEDED(addr_status, updated)
|| NEGATIVE_REFRESH_NEEDED(addr_status, updated))) {
&& (POSITIVE_REFRESH_NEEDED(addr_status, updated)
|| NEGATIVE_REFRESH_NEEDED(addr_status, updated))) {
if (msg_verbose)
msg_info("PROBE %s status=%d probed=%ld updated=%ld",
STR(addr), addr_status, now, updated);