]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.10-20240622
authorWietse Z Venema <wietse@porcupine.org>
Sat, 22 Jun 2024 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <ietf-dane@dukhovni.org>
Mon, 24 Jun 2024 00:24:40 +0000 (10:24 +1000)
19 files changed:
postfix/HISTORY
postfix/WISHLIST
postfix/html/SASL_README.html
postfix/html/master.5.html
postfix/html/pipe.8.html
postfix/html/postconf.5.html
postfix/html/smtpd.8.html
postfix/man/man5/master.5
postfix/man/man5/postconf.5
postfix/man/man8/pipe.8
postfix/man/man8/smtpd.8
postfix/proto/SASL_README.html
postfix/proto/master
postfix/proto/postconf.proto
postfix/proto/stop
postfix/proto/stop.double-history
postfix/src/global/mail_version.h
postfix/src/pipe/pipe.c
postfix/src/smtpd/smtpd.c

index 0ba4cfb5bc72adea7812be54a16bceb47e85d4fa..55a3c3e9bd2b3ab44d89cedf1466f86486c21374 100644 (file)
@@ -28095,3 +28095,21 @@ Apologies for any names omitted.
        Bugfix (defect introduced: Postfix 3.10, date 20230310):
        segfault after reading a null pointer, while responding to
        an unknown or unimplemented command. File: smtpd/smtpd.c.
+
+20240614
+
+       Documentation: made the descriptions of command-line arguments
+       inside {} more consistent. Files: proto/master, pipe/pipe.c.
+
+20240618
+
+       Code health: factored out duplicate code for unknown and
+       unimplemented commands in the SMTP server. File: smtpd/smtpd.c.
+
+20240622
+
+       Documentation: in the rbl_reply_maps description,added text
+       how it handles reject_rbl_* or reject_rhsbl_* queries with
+       an address filter. Also added text to clarify te differences
+       between rbl_reply_maps and postscreen_dnsbl_reply_map.
+       File: proto/postconf.proto.
index b3012592511966db0de335f663d5f9d6754f1909..f8cb62ffa129c28dbc2948d59acae5682f40781d 100644 (file)
@@ -16,6 +16,10 @@ Wish list:
        using FIFOs anymore, and trigger servers could use a proper
        (attribute, value) protocol.
 
+       The postsceen NON-SMTP test should log the command in
+       the same format as the BARE NEWLINE and PREGREET tests.
+       Consider logging the entire unadulterated command line.
+
        "postconf -d" should not complain about a missing master.cf
        file.
 
index ce3b893664873401a244ab297667fb47149ccd7f..c95ac8c84537ffe0cfc3ff04def021c4a396c51b 100644 (file)
@@ -909,7 +909,7 @@ stored as plaintext. </p>
 auxprop plugin. Instead, you can use "<code>saslauthd -a ldap</code>"
 to query the LDAP database directly, with appropriate configuration
 in <code>saslauthd.conf</code>, <a
-href="http://git.cyrusimap.org/cyrus-sasl/tree/saslauthd/LDAP_SASLAUTHD">as
+href="https://github.com/cyrusimap/cyrus-sasl/blob/master/saslauthd/LDAP_SASLAUTHD">as
 described here</a>.  You will not be able to use any of the
 methods that require access to plaintext passwords, such as the
 shared-secret methods CRAM-MD5 and DIGEST-MD5.  </p>
index 67fe3f30b5a57fdc07f95342b5448d2913bb7fb8..48f9cec493d1243e62762711d2017eb764279db8 100644 (file)
@@ -240,16 +240,14 @@ MASTER(5)                                                            MASTER(5)
                      verbose.
 
               <b>Command-line arguments that start with {</b>
-                     Specify "{" and "}" around command arguments  that  start
-                     with  "{"  (Postfix 3.0 and later). The outer "{" and "}"
-                     are removed from the input, together with any leading  or
-                     trailing whitespace.
-
-              <b>Other command-line arguments</b>
-                     Specify "{" and "}" around command arguments that contain
-                     whitespace (Postfix 3.0 and later). The outer "{" and "}"
-                     are  removed from the input, together with any leading or
-                     trailing whitespace.
+
+              <b>Command-line arguments that contain whitespace</b>
+
+              <b>Command-line arguments that must be empty</b>
+                     Specify "{" and "}" around such  arguments  (Postfix  3.0
+                     and  later).  The  outer  "{"  and  "}"  will be removed,
+                     together with any leading or trailing whitespace  in  the
+                     remaining text.
 
 <b>SEE ALSO</b>
        <a href="master.8.html">master(8)</a>, process manager
index d81395471a9ad8124f6cc05709088c4b1289b357..c22b91e5f35af03f52cb0a0b85824e94ac9e2df7 100644 (file)
@@ -195,8 +195,10 @@ PIPE(8)                                                                PIPE(8)
               interpreter.
 
               Specify "{" and "}" around command arguments that contain white-
-              space  (Postfix 3.0 and later). Whitespace after the opening "{"
-              and before the closing "}" is ignored.
+              space,  arguments that begin with "{", or arguments that must be
+              an empty string (Postfix 3.0 and later). The outer "{"  and  "}"
+              will  be  removed,  together with any leading or trailing white-
+              space in the remaining text.
 
               In the command argument vector, the following macros are  recog-
               nized and replaced with corresponding information from the Post-
index 6b926fb671cf2d50ce89e733bc40f46753e86eed..3734c5e89cb200607140c029b7794117fabcce96 100644 (file)
@@ -2670,7 +2670,7 @@ Instead of $name you can also specify ${name} or $(name).
 
 <p> Note: when an enhanced status code is specified in an RBL reply
 template, it is subject to modification.  The following transformations
-are needed when the same RBL reply template is used for client,
+are needed when the same RBL response template is used for client,
 helo, sender, or recipient access restrictions.  </p>
 
 <ul>
@@ -8798,6 +8798,11 @@ the file is read). </p>
    secret.zen.spamhaus.org      zen.spamhaus.org
 </pre>
 
+<p> NOTE: This feature differs from the Postfix SMTP server's
+<a href="postconf.5.html#rbl_reply_maps">rbl_reply_maps</a> feature, where 1) the table search key includes the
+optional "<i>=address</i>" filter, and where 2) the lookup result
+contains free text with <i>$name</i> variables. </p>
+
 <p> This feature is available in Postfix 2.8.  </p>
 
 
@@ -9807,15 +9812,46 @@ This feature is available in Postfix 2.0 and later.
 (default: empty)</b></DT><DD>
 
 <p>
-Optional lookup tables with RBL response templates. The tables are
-indexed by the RBL domain name. By default, Postfix uses the default
+Optional lookup tables with RBL or RHSBL response templates. The
+table search key is the reject_rbl_* or reject_rhsbl_* argument,
+including any optional "<i>=address-pattern</i>" filter. </p>
+
+<p> By default, Postfix uses the
 template as specified with the <a href="postconf.5.html#default_rbl_reply">default_rbl_reply</a> configuration
-parameter. See there for a discussion of the syntax of RBL reply
-templates.
+parameter. See there for a discussion of the response template
+syntax.
+</p>
+
+<p> Example: </p>
+
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+    <a href="postconf.5.html#rbl_reply_maps">rbl_reply_maps</a> = <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/rbl_reply
+    <a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> =
+        <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>,
+        <a href="postconf.5.html#reject_rbl_client">reject_rbl_client</a> <i>secret</i>.zen.dq.spamhaus.net=127.0.0.[2..11],
+        ...
+<br>
+/etc/postfix/rbl_reply:
+    # See https://www.postfix.org/postconf.5.html#<a href="postconf.5.html#default_rbl_reply">default_rbl_reply</a>
+    # for the definition of the $client_address and $rbl_class etc.
+    # variables.
+    <i>secret</i>.zen.dq.spamhaus.net=127.0.0.[2..11]
+        554 $rbl_class $rbl_what blocked using ZEN - see <a href="https://www.spamhaus.org/query/ip/$client_address">https://www.spamhaus.org/query/ip/$client_address</a> for details
+    <i>secret</i>.zen.dq.spamhaus.net
+        554 $rbl_class $rbl_what blocked using ZEN - see <a href="https://www.spamhaus.org/query/ip/$client_address">https://www.spamhaus.org/query/ip/$client_address</a> for details
+</pre>
+
+<p>
+NOTE: This feature differs from <a href="postconf.5.html#postscreen_dnsbl_reply_map">postscreen_dnsbl_reply_map</a> where
+the table search key is a domain name (no "<i>=address</i>" filter,
+no "<i>*weight</i>" factor) and where the lookup result should be
+a domain name (no free text, no <i>$name</i> variables).
 </p>
 
 <p>
 This feature is available in Postfix 2.0 and later.
+The "=address-pattern" filter is available in Postfix 2.8 and later.
 </p>
 
 
index 338a7ec8f49c5d37f911c6c422179fc404d02d89..4466acac7c43872606f02a6b3dd1176ef8cf48dd 100644 (file)
@@ -1316,7 +1316,7 @@ SMTPD(8)                                                              SMTPD(8)
               <a href="postconf.5.html#reject_multi_recipient_bounce">ent_bounce</a> restriction.
 
        <b><a href="postconf.5.html#rbl_reply_maps">rbl_reply_maps</a> (empty)</b>
-              Optional lookup tables with RBL response templates.
+              Optional lookup tables with RBL or RHSBL response templates.
 
        Available in Postfix version 2.6 and later:
 
index 9c517ecd02647b35ee4f5c77e392ac8aa4b69ed2..5dda48f265de9b36ca2e66eb264ed097c6717278 100644 (file)
@@ -243,15 +243,12 @@ personalities via master.cf.
 Increase the verbose logging level. Specify multiple \fB\-v\fR
 options to make a Postfix daemon process increasingly verbose.
 .IP "\fBCommand\-line arguments that start with {\fR"
-Specify "{" and "}" around command arguments that start
-with "{" (Postfix 3.0 and later). The outer "{" and "}" are
-removed from the input, together with any leading or trailing
-whitespace.
-.IP "\fBOther command\-line arguments\fR"
-Specify "{" and "}" around command arguments that contain
-whitespace (Postfix 3.0 and later). The outer "{" and "}"
-are removed from the input, together with any leading or
-trailing whitespace.
+.IP "\fBCommand\-line arguments that contain whitespace\fR"
+.IP "\fBCommand\-line arguments that must be empty\fR"
+Specify "{" and "}" around such arguments (Postfix 3.0 and
+later). The outer "{" and "}" will be removed, together
+with any leading or trailing whitespace in the remaining
+text.
 .SH "SEE ALSO"
 .na
 .nf
index 02a3e008300d233667ae83f14cb2a05cec588c52..04bba9d9104c11da7a9cee156fa099eacabbea05 100644 (file)
@@ -1732,7 +1732,7 @@ Instead of $name you can also specify ${name} or $(name).
 .PP
 Note: when an enhanced status code is specified in an RBL reply
 template, it is subject to modification.  The following transformations
-are needed when the same RBL reply template is used for client,
+are needed when the same RBL response template is used for client,
 helo, sender, or recipient access restrictions.
 .IP \(bu
 When rejecting a sender address, the Postfix SMTP server
@@ -5570,6 +5570,11 @@ Example:
 .ad
 .ft R
 .PP
+NOTE: This feature differs from the Postfix SMTP server's
+rbl_reply_maps feature, where 1) the table search key includes the
+optional "\fI=address\fR" filter, and where 2) the lookup result
+contains free text with \fI$name\fR variables.
+.PP
 This feature is available in Postfix 2.8.
 .SH postscreen_dnsbl_sites (default: empty)
 Optional list of patterns with DNS allow/denylist domains, filters
@@ -6160,13 +6165,46 @@ queue and schedules delivery requests.
 .PP
 This feature is available in Postfix 2.0 and later.
 .SH rbl_reply_maps (default: empty)
-Optional lookup tables with RBL response templates. The tables are
-indexed by the RBL domain name. By default, Postfix uses the default
+Optional lookup tables with RBL or RHSBL response templates. The
+table search key is the reject_rbl_* or reject_rhsbl_* argument,
+including any optional "\fI=address\-pattern\fR" filter.
+.PP
+By default, Postfix uses the
 template as specified with the default_rbl_reply configuration
-parameter. See there for a discussion of the syntax of RBL reply
-templates.
+parameter. See there for a discussion of the response template
+syntax.
+.PP
+Example:
+.PP
+.nf
+.na
+.ft C
+/etc/postfix/main.cf:
+    rbl_reply_maps = hash:/etc/postfix/rbl_reply
+    smtpd_recipient_restrictions =
+        permit_mynetworks,
+        reject_rbl_client \fIsecret\fR.zen.dq.spamhaus.net=127.0.0.[2..11],
+        ...
+.br
+/etc/postfix/rbl_reply:
+    # See https://www.postfix.org/postconf.5.html#default_rbl_reply
+    # for the definition of the $client_address and $rbl_class etc.
+    # variables.
+    \fIsecret\fR.zen.dq.spamhaus.net=127.0.0.[2..11]
+        554 $rbl_class $rbl_what blocked using ZEN \- see https://www.spamhaus.org/query/ip/$client_address for details
+    \fIsecret\fR.zen.dq.spamhaus.net
+        554 $rbl_class $rbl_what blocked using ZEN \- see https://www.spamhaus.org/query/ip/$client_address for details
+.fi
+.ad
+.ft R
+.PP
+NOTE: This feature differs from postscreen_dnsbl_reply_map where
+the table search key is a domain name (no "\fI=address\fR" filter,
+no "\fI*weight\fR" factor) and where the lookup result should be
+a domain name (no free text, no \fI$name\fR variables).
 .PP
 This feature is available in Postfix 2.0 and later.
+The "=address\-pattern" filter is available in Postfix 2.8 and later.
 .SH readme_directory (default: see "postconf \-d" output)
 The location of Postfix README files that describe how to build,
 configure or operate a specific Postfix subsystem or feature.
index efb9e0e5f3af2a2ba3dc7ca7b17271334c213e49..566cf89c8756fb664d19c9667564ad8446f5fff6 100644 (file)
@@ -201,8 +201,10 @@ The command is executed directly, i.e. without interpretation of
 shell meta characters by a shell command interpreter.
 .sp
 Specify "{" and "}" around command arguments that contain
-whitespace (Postfix 3.0 and later). Whitespace
-after the opening "{" and before the closing "}" is ignored.
+whitespace, arguments that begin with "{", or arguments
+that must be an empty string (Postfix 3.0 and later). The
+outer "{" and "}" will be removed, together with any leading
+or trailing whitespace in the remaining text.
 .sp
 In the command argument vector, the following macros are recognized
 and replaced with corresponding information from the Postfix queue
index 0c0bc2e0babc1ebcebc12be2771647b6245e8572..fdfe4862d372f6ba09c1e013ef5be4b87a4a1285 100644 (file)
@@ -1140,7 +1140,7 @@ The numerical Postfix SMTP server response code when a remote SMTP
 client request is blocked by the reject_multi_recipient_bounce
 restriction.
 .IP "\fBrbl_reply_maps (empty)\fR"
-Optional lookup tables with RBL response templates.
+Optional lookup tables with RBL or RHSBL response templates.
 .PP
 Available in Postfix version 2.6 and later:
 .IP "\fBaccess_map_defer_code (450)\fR"
index 14d959b4c785a9bea591e7a2c114c96d77fe6091..2af2e7bfb9a702ed8c63b12982ca863dfd1b7325 100644 (file)
@@ -909,7 +909,7 @@ stored as plaintext. </p>
 auxprop plugin. Instead, you can use "<code>saslauthd -a ldap</code>"
 to query the LDAP database directly, with appropriate configuration
 in <code>saslauthd.conf</code>, <a
-href="http://git.cyrusimap.org/cyrus-sasl/tree/saslauthd/LDAP_SASLAUTHD">as
+href="https://github.com/cyrusimap/cyrus-sasl/blob/master/saslauthd/LDAP_SASLAUTHD">as
 described here</a>.  You will not be able to use any of the
 methods that require access to plaintext passwords, such as the
 shared-secret methods CRAM-MD5 and DIGEST-MD5.  </p>
index efd88e55df58542b8ed5acd73c71af646bd55a4f..3b3bd3ea110346b545900d77b879e3b707ff4739 100644 (file)
 #      Increase the verbose logging level. Specify multiple \fB-v\fR
 #      options to make a Postfix daemon process increasingly verbose.
 # .IP "\fBCommand-line arguments that start with {\fR"
-#      Specify "{" and "}" around command arguments that start
-#      with "{" (Postfix 3.0 and later). The outer "{" and "}" are
-#      removed from the input, together with any leading or trailing
-#      whitespace.
-# .IP "\fBOther command-line arguments\fR"
-       Specify "{" and "}" around command arguments that contain
-#      whitespace (Postfix 3.0 and later). The outer "{" and "}"
-#      are removed from the input, together with any leading or
-#      trailing whitespace.
+# .IP "\fBCommand-line arguments that contain whitespace\fR"
+# .IP "\fBCommand-line arguments that must be empty\fR"
+#      Specify "{" and "}" around such arguments (Postfix 3.0 and
+#      later). The outer "{" and "}" will be removed, together
+#      with any leading or trailing whitespace in the remaining
+#      text.
 # SEE ALSO
 #      master(8), process manager
 #      postconf(5), configuration parameters
index 9dda8f29ece991df3c17b67d9fc19a7653189bf9..36aab443ec722d2efa1ad180eaee81065dcec66c 100644 (file)
@@ -1254,7 +1254,7 @@ Instead of $name you can also specify ${name} or $(name).
 
 <p> Note: when an enhanced status code is specified in an RBL reply
 template, it is subject to modification.  The following transformations
-are needed when the same RBL reply template is used for client,
+are needed when the same RBL response template is used for client,
 helo, sender, or recipient access restrictions.  </p>
 
 <ul>
@@ -3586,15 +3586,46 @@ The default time unit is s (seconds).  </p>
 %PARAM rbl_reply_maps 
 
 <p>
-Optional lookup tables with RBL response templates. The tables are
-indexed by the RBL domain name. By default, Postfix uses the default
+Optional lookup tables with RBL or RHSBL response templates. The
+table search key is the reject_rbl_* or reject_rhsbl_* argument,
+including any optional "<i>=address-pattern</i>" filter. </p>
+
+<p> By default, Postfix uses the
 template as specified with the default_rbl_reply configuration
-parameter. See there for a discussion of the syntax of RBL reply
-templates.
+parameter. See there for a discussion of the response template
+syntax.
+</p>
+
+<p> Example: </p>
+
+<pre>
+/etc/postfix/main.cf:
+    rbl_reply_maps = hash:/etc/postfix/rbl_reply
+    smtpd_recipient_restrictions =
+        permit_mynetworks, 
+        reject_rbl_client <i>secret</i>.zen.dq.spamhaus.net=127.0.0.[2..11],
+       ...
+<br>
+/etc/postfix/rbl_reply:
+    # See https://www.postfix.org/postconf.5.html#default_rbl_reply
+    # for the definition of the $client_address and $rbl_class etc.
+    # variables.
+    <i>secret</i>.zen.dq.spamhaus.net=127.0.0.[2..11]
+        554 $rbl_class $rbl_what blocked using ZEN - see https://www.spamhaus.org/query/ip/$client_address for details
+    <i>secret</i>.zen.dq.spamhaus.net
+        554 $rbl_class $rbl_what blocked using ZEN - see https://www.spamhaus.org/query/ip/$client_address for details 
+</pre>
+
+<p>
+NOTE: This feature differs from postscreen_dnsbl_reply_map where
+the table search key is a domain name (no "<i>=address</i>" filter,
+no "<i>*weight</i>" factor) and where the lookup result should be
+a domain name (no free text, no <i>$name</i> variables).
 </p>
 
 <p>
 This feature is available in Postfix 2.0 and later.
+The "=address-pattern" filter is available in Postfix 2.8 and later.
 </p>
 
 %PARAM receive_override_options 
@@ -15418,6 +15449,11 @@ the file is read). </p>
    secret.zen.spamhaus.org     zen.spamhaus.org
 </pre>
 
+<p> NOTE: This feature differs from the Postfix SMTP server's
+rbl_reply_maps feature, where 1) the table search key includes the
+optional "<i>=address</i>" filter, and where 2) the lookup result
+contains free text with <i>$name</i> variables. </p>
+
 <p> This feature is available in Postfix 2.8.  </p>
 
 %PARAM postscreen_dnsbl_timeout 10s
index 52f34ab433d5ba9d2fba5b5a40873b3f7e0f4969..fb1da4859e3186028eb61c17b855036711efa155 100644 (file)
@@ -1604,3 +1604,5 @@ LLC
 Maadani
 GTEST
 javascript
+SMFI
+RHSBL
index 1122e5e6108b1a39f3e900d7d761af6dde93815b..843e59edec6d82d65c071512b2b9cf47679eb286 100644 (file)
@@ -126,3 +126,5 @@ proto  proto mysql_table proto pgsql_table proto ldap_table
  a domain File postalias postalias c 
  File spawn spawn c 
  an unknown or unimplemented command File smtpd smtpd c 
+ inside more consistent Files proto master pipe pipe c 
+ unimplemented commands in the SMTP server File smtpd smtpd c 
index 7f926fb12fcd21b032e6b90e159c306dc6257633..d23ed66400257c0ff20b7c02481edb4d0f14a1e6 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      "20240612"
+#define MAIL_RELEASE_DATE      "20240622"
 #define MAIL_VERSION_NUMBER    "3.10"
 
 #ifdef SNAPSHOT
index 301793743bbe1b4d4e52c8ec757f077bc890e205..eceae2b3df73a3edf221eeff5c0489ca976b9f5d 100644 (file)
 /*     shell meta characters by a shell command interpreter.
 /* .sp
 /*     Specify "{" and "}" around command arguments that contain
-/*     whitespace (Postfix 3.0 and later). Whitespace
-/*     after the opening "{" and before the closing "}" is ignored.
+/*     whitespace, arguments that begin with "{", or arguments
+/*     that must be an empty string (Postfix 3.0 and later). The
+/*     outer "{" and "}" will be removed, together with any leading
+/*     or trailing whitespace in the remaining text.
 /* .sp
 /*     In the command argument vector, the following macros are recognized
 /*     and replaced with corresponding information from the Postfix queue
index 9b8cbbe85059eed0276ac9c5ab2dfd4094d47c9a..8c5ce4717188e6f2886c9cd3e939156cc2f6ffa7 100644 (file)
 /*     client request is blocked by the reject_multi_recipient_bounce
 /*     restriction.
 /* .IP "\fBrbl_reply_maps (empty)\fR"
-/*     Optional lookup tables with RBL response templates.
+/*     Optional lookup tables with RBL or RHSBL response templates.
 /* .PP
 /*     Available in Postfix version 2.6 and later:
 /* .IP "\fBaccess_map_defer_code (450)\fR"
@@ -5501,11 +5501,43 @@ static void tls_reset(SMTPD_STATE *state)
 
 #endif
 
+/* milter_unknown_reply_override - common code for unknown/unimplemented case */
+
+static int milter_unknown_reply_override(SMTPD_STATE *state)
+{
+    const char *err;
+
+    /*
+     * XXX The Postfix libmilter implementation does not indicate whether it
+     * returns:
+     * 
+     * 1) A generic "command rejected" etc. reply text that is generated by the
+     * Postfix milter library, when the Sendmail milter library replies with
+     * SMFI_REJECT or SMFI_TEMPFAIL.
+     * 
+     * 2) A custom reply text that is generated by a milter application, when
+     * the Sendmail milter library replies with SMFI_REPLY.
+     * 
+     * As a compromise, we will not override the Postfix SMTP server's specific
+     * "5XX Unknown command" etc. reply.
+     */
+    if (state->milters != 0
+       && (err = milter_unknown_event(state->milters,
+                                      STR(state->buffer))) != 0) {
+       if (err[0] == '4') {
+           smtpd_chat_reply(state, "%s", err);
+           return (1);
+       } else if (err[0] != '5') {
+           msg_warn("unexpected SMFIC_UNKNOWN response: %s", err);
+       }
+    }
+    return (0);
+}
+
 /* unimpl_cmd - dummy for functionality that is not compiled in */
 
 static int unimpl_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
 {
-    const char *err = 0;
 
     /*
      * When a connection is closed we want to log the request counts for
@@ -5516,16 +5548,8 @@ static int unimpl_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
      * it must either tempfail or reject.
      */
     state->error_mask |= MAIL_ERROR_PROTOCOL;
-    if (state->milters != 0
-       && (err = milter_unknown_event(state->milters,
-                                      STR(state->buffer))) != 0
-       && err[0] == '4') {
-       smtpd_chat_reply(state, "%s", err);
-    } else {
-       if (err && err[0] != '5')
-           msg_warn("unexpected SMFIC_UNKNOWN response: %s", err);
+    if (milter_unknown_reply_override(state) == 0)
        smtpd_chat_reply(state, "502 5.5.1 Error: command not implemented");
-    }
     return (-1);
 }
 
@@ -5553,7 +5577,7 @@ typedef struct SMTPD_CMD {
 #define SMTPD_CMD_FLAG_PRE_TLS (1<<1)  /* allow before STARTTLS */
 #define SMTPD_CMD_FLAG_LAST    (1<<2)  /* last in PIPELINING command group */
 
-static int  help_cmd(SMTPD_STATE *, int, SMTPD_TOKEN *);
+static int help_cmd(SMTPD_STATE *, int, SMTPD_TOKEN *);
 
 static SMTPD_CMD smtpd_cmd_table[] = {
     {SMTPD_CMD_HELO, helo_cmd, SMTPD_CMD_FLAG_LIMIT | SMTPD_CMD_FLAG_PRE_TLS | SMTPD_CMD_FLAG_LAST,},
@@ -6021,19 +6045,9 @@ static void smtpd_proto(SMTPD_STATE *state)
            }
            /* state->access_denied == 0 || cmdp->action == quit_cmd */
            if (cmdp->name == 0) {
-               /* See unimpl_cmd() for valid xxfi_unknown() return values. */
-               err = 0;
-               if (state->milters != 0
-                   && (err = milter_unknown_event(state->milters,
-                                                  STR(state->buffer))) != 0
-                   && err[0] == '4') {
-                   smtpd_chat_reply(state, "%s", err);
-               } else {
-                   if (err && err[0] != '5')
-                       msg_warn("unexpected SMFIC_UNKNOWN response: %s", err);
+               if (milter_unknown_reply_override(state) == 0)
                    smtpd_chat_reply(state,
                                 "500 5.5.2 Error: command not recognized");
-               }
                state->error_mask |= MAIL_ERROR_PROTOCOL;
                state->error_count++;
                continue;