]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.1-20151227
authorWietse Venema <wietse@porcupine.org>
Sun, 27 Dec 2015 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Mon, 28 Dec 2015 02:21:46 +0000 (21:21 -0500)
35 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/RELEASE_NOTES
postfix/WISHLIST
postfix/conf/post-install
postfix/html/oqmgr.8.html
postfix/html/postconf.5.html
postfix/html/postlog.1.html
postfix/html/qmgr.8.html
postfix/man/man1/postlog.1
postfix/man/man5/postconf.5
postfix/man/man8/oqmgr.8
postfix/man/man8/qmgr.8
postfix/mantools/postlink
postfix/postfix-install
postfix/proto/postconf.proto
postfix/src/cleanup/Makefile.in
postfix/src/cleanup/cleanup.h
postfix/src/cleanup/cleanup_envelope.c
postfix/src/cleanup/cleanup_out_recipient.c
postfix/src/cleanup/cleanup_state.c
postfix/src/global/mail_params.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/global/post_mail.c
postfix/src/global/post_mail.h
postfix/src/global/verify.c
postfix/src/oqmgr/qmgr.c
postfix/src/oqmgr/qmgr.h
postfix/src/oqmgr/qmgr_message.c
postfix/src/postlog/postlog.c
postfix/src/qmgr/qmgr.c
postfix/src/qmgr/qmgr.h
postfix/src/qmgr/qmgr_message.c
postfix/src/verify/verify.c

index 0e9462f1912127ff19ddf2e925d28e017734d728..5502f64db306cf54471f4173d96e9c7c8b52ae88 100644 (file)
 -TPLMYSQL
 -TPLPGSQL
 -TPOSTMAP_KEY_STATE
+-TPOST_MAIL_FCLOSE_STATE
 -TPOST_MAIL_STATE
 -TPRIVATE_STR_TABLE
 -TPSC_CALL_BACK_ENTRY
index 975fbec707e069d71561f83a14a5c23d14d4fe03..47bb88bfcaccd346e7eec8658d4e09a8b771741e 100644 (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.
index 0b51dee8deb87b9ef306c41a92c8ea386339717a..08f899c4bca3c2cbb62e18d404c639a9b79b1000 100644 (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
 --------------------------------------------------
 
index 4f2ec862f2d99621b78de64da032ffe73c3a21d1..f85ae3197d47b35b2d1e7a09155c1c5e14ea7929 100644 (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
index d5db2600e72d25aadc78a2c13875568f0ed2a962..904cefa58afec57a0f2a286b1a681d58dbbf5911 100644 (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;;
index d97ffc8d260cd923539d45b2eceaed801e043d8a..d952c0c7c97aba08c487b767b81ac04997a84038 100644 (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>
index 67edf42b6915fe39f709c70fa2a36b7d2e4dc62e..0cab4cfd151934a6d44e5f1c821dd3f41ae72472 100644 (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>
index 3ecbcbc089e6e57e36bb8fd17f15bc327e7efdad..514e7f3058b4bcf72c3674838f567881ad6d1538 100644 (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
index 7f2225d4cfa150ef1314692321fdceadb6d9f150..a919a173ddf939503c9cb759ab0ee147046e9270 100644 (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>
index b1fc218226e93b819803c30637af409df6a9909d..8aa798b54422cf096b0c23cf01c53406e167f993 100644 (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
index 24cdf21e0752caf9ee859f0e4397531aa94d4a2d..273a6164ff607be2d2e6117f2c12e8d5403f8b1d 100644 (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.
index 46514085ab483bdc60da023213719bc989768f07..54a01f060e895a8d5470bbd692d08edf81d67dce 100644 (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
index 400f789c5c0b90f1b4be4ac4b512b8f3e1f90401..de116a0432752082d99e6410eae8ed0ea06c87f8 100644 (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
index 82ec6bece1866d32c82adb594f56e4522054c2f3..2d1ab073644de1a70fa578a7e8b54286df66ecfc 100755 (executable)
@@ -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;
index 01d17b48565bc49241c3ad7616d7779a00d252d5..b80069093fcf667555fe5e33816591b9d8a9262e 100644 (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
 
index 7097015fda5b4e55cdcd7df045d49494d5b4be8b..33cf629232e259807b3cb5e4e76f95392f1a14b4 100644 (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>
index ad479d09cee5e2e0a0292722fa7011a855f47879..e44418862b6a27981db6780db589a9e31a833648 100644 (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
index 9bd7f1b87a9a4ad35a4981f94af0444ea72b1902..a0dc9fbc9164fbcb2033bc454df13fcbfc0707f7 100644 (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 */
index 261542ba81da64f8554411d561ae4a3caf70a834..abdc8f5d05ae2b4a41fd64f4e4abea9577fb4cf7 100644 (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;
index 25ffb90526cad0077feaa0e7dc47c95ef87c6953..bbe080365dae6d7f87bfd7d3d278b197dd6b05cb 100644 (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");
index 0d71b44ab1799b5e93658f793583341927709887..17a46172b222fad15de5323442dd76dcd724db14 100644 (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;
index 85e1ecfdbfd3abfb914e1aad9c50a54a6a1d21e1..4842d572feb58f031a7d8155b7b2b9e01a200385 100644 (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);
 }
 
index 91c7f126e2e68d8508c5e1c9f04ab17c7715f5c8..81464b1e09d7b07c2471a0dafe965d4210c248c8 100644 (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.
   */
index e7538e5b7a67527c064014f92f1247d103e7744a..3fa1ccd161f268203e1dde5bb5ffade269d3914e 100644 (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
index 002b8d99d7cc4664cb117fdfae026a95329c2206..fbb631d9b5ee29b525ddb37f95863f649712a24f 100644 (file)
 /*
 /*     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
 /*
 /*     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);
+    }
+}
index 70bb34f0d14b304f17d255a5f1f37c2bc3088863..eb7974a077b01411fbce27c5c2225b09f306fc43 100644 (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))
index d6bf36f67a4736fe2d630e7ea8892aa34d0a4d6e..8b20ac710bf915cf5fe4e67424ab7f815d8a77cf 100644 (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 {
index cca95c773a93ad29747d35dcdf1207b5460af465..4ea89e700454bdb37d113d8171dcff31c4aad398 100644 (file)
 /* .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[] = {
index b8c8d0e48bc53e11943845c17859972ce852477a..db4b394eb99098109384f2aa76d7e0d214bb57b8 100644 (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 *);
index 5b8596b074f8f000c162623de547032d20dfb80b..26d9bd37ee03b1ac17110d1a103fbc191948289a 100644 (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;
 /*     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
 
 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);
 }
 
index 518f45a1a3966723e04f4c252da5292f7a97cea3..7403b079ced0abf3bc4f3cf2c666e339ea358e93 100644 (file)
 /*     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);
 }
index 137cd93080c9c2fefe3a5a960d7d258c2139b1e5..657e44216837b6a50a44cecb828a925da93ce0c3 100644 (file)
 /* .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[] = {
index 88ce7920ebeb3293ca8a0fd32b8077cd8b57293a..17919d183275b486d66587c59e54d01c6f9475b5 100644 (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 *);
index a83e4a0aaddf0de9936b04047f8408ef67d8bfb6..495d52d93c65f26f400daa8caf47cab1d55c3332 100644 (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;
 /*     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
 
 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);
 }
 
index 300bd9ea3b3b538b3bc1b98542b339cc79d5a1e0..d9538a8b2d3d1cc95a3128b2f2b479f8ec96484f 100644 (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);