Prereq: "3.10.7" diff -ur --new-file /var/tmp/postfix-3.10.7/src/global/mail_version.h ./src/global/mail_version.h --- /var/tmp/postfix-3.10.7/src/global/mail_version.h 2025-12-05 15:02:59.000000000 -0500 +++ ./src/global/mail_version.h 2026-02-18 14:24:21.000000000 -0500 @@ -20,8 +20,8 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20251205" -#define MAIL_VERSION_NUMBER "3.10.7" +#define MAIL_RELEASE_DATE "20260218" +#define MAIL_VERSION_NUMBER "3.10.8" #ifdef SNAPSHOT #define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE diff -ur --new-file /var/tmp/postfix-3.10.7/HISTORY ./HISTORY --- /var/tmp/postfix-3.10.7/HISTORY 2025-12-05 15:02:01.000000000 -0500 +++ ./HISTORY 2026-02-18 11:53:15.000000000 -0500 @@ -29258,3 +29258,24 @@ large for the stable releases. Instead, the command "make makefiles" will figure out how to make the compiler backwards-compatible. File: makedefs. + +20251208 + + Improved Milter error handling for messages that arrive + over a long-lived SMTP connection, by changing the default + milter_default_action from "tempfail" to the new "shutdown" + action (i.e. disconnect the remote SMTP client). + + The problem was that after a single Milter error, Postfix + could tempfail all messages that the client sends over a + long-lived connection, even if the Milter error was only + temporary. This problem was reported by Ankit Kulkarni. + + Files: proto/postconf.proto global/mail_params.h milter/milter8.c. + +20260217 + + Bugfix: (defect introduced: Postfix 2.11): panic() after + recursive logging loop with "posttls-finger -v -v -v". + Reported by Geert Hendrickx, diagnosed by Viktor Dukhovni, + and fixed by Wietse. Files: util/vstream.[hc], util/msg_vstream.c. diff -ur --new-file /var/tmp/postfix-3.10.7/html/postconf.5.html ./html/postconf.5.html --- /var/tmp/postfix-3.10.7/html/postconf.5.html 2025-11-25 12:31:07.000000000 -0500 +++ ./html/postconf.5.html 2026-02-18 14:20:01.000000000 -0500 @@ -7363,7 +7363,7 @@
The default action when a Milter (mail filter) response is unavailable (for example, bad Postfix configuration or Milter @@ -7380,11 +7380,20 @@
The current default action is "shutdown", i.e. disconnect the +SMTP client. With the old "tempfail" default, Postfix could tempfail +all messages that the client sends over a long-lived connection, +even if a Milter failure is only temporary.
+This feature is available in Postfix 2.3 and later.
diff -ur --new-file /var/tmp/postfix-3.10.7/man/man5/postconf.5 ./man/man5/postconf.5 --- /var/tmp/postfix-3.10.7/man/man5/postconf.5 2025-11-25 12:31:07.000000000 -0500 +++ ./man/man5/postconf.5 2026-02-18 14:20:01.000000000 -0500 @@ -4496,7 +4496,7 @@ for a list of available macro names and their meanings. .PP This feature is available in Postfix 2.3 and later. -.SH milter_default_action (default: tempfail) +.SH milter_default_action (default: see 'postconf \-d milter_default_action' output) The default action when a Milter (mail filter) response is unavailable (for example, bad Postfix configuration or Milter failure). Specify one of the following: @@ -4511,12 +4511,22 @@ Reject all further commands in this session with a temporary status code. .br +.IP "shutdown" +Close the SMTP connection after sending a 421 +SMTP reply. Available in Postfix 3.11, 3.10.8, 3.9.9, 3.8.15, 3.7.20, +and later. +.br .IP "quarantine" Like "accept", but freeze the message in the "hold" queue. Available with Postfix 2.6 and later. .br .br .PP +The current default action is "shutdown", i.e. disconnect the +SMTP client. With the old "tempfail" default, Postfix could tempfail +all messages that the client sends over a long\-lived connection, +even if a Milter failure is only temporary. +.PP This feature is available in Postfix 2.3 and later. .SH milter_end_of_data_macros (default: see "postconf \-d" output) The macros that are sent to Milter (mail filter) applications diff -ur --new-file /var/tmp/postfix-3.10.7/proto/postconf.proto ./proto/postconf.proto --- /var/tmp/postfix-3.10.7/proto/postconf.proto 2025-11-25 12:19:06.000000000 -0500 +++ ./proto/postconf.proto 2026-02-18 11:51:40.000000000 -0500 @@ -12274,7 +12274,7 @@This feature is available in Postfix 2.3 and later.
-%PARAM milter_default_action tempfail +%PARAM milter_default_action see 'postconf -d milter_default_action' outputThe default action when a Milter (mail filter) response is unavailable (for example, bad Postfix configuration or Milter @@ -12291,11 +12291,20 @@
The current default action is "shutdown", i.e. disconnect the +SMTP client. With the old "tempfail" default, Postfix could tempfail +all messages that the client sends over a long-lived connection, +even if a Milter failure is only temporary.
+This feature is available in Postfix 2.3 and later.
%PARAM milter_connect_timeout 30s diff -ur --new-file /var/tmp/postfix-3.10.7/src/global/mail_params.h ./src/global/mail_params.h --- /var/tmp/postfix-3.10.7/src/global/mail_params.h 2025-10-24 10:41:15.000000000 -0400 +++ ./src/global/mail_params.h 2026-02-18 11:40:51.000000000 -0500 @@ -3516,7 +3516,7 @@ extern char *var_cleanup_milters; #define VAR_MILT_DEF_ACTION "milter_default_action" -#define DEF_MILT_DEF_ACTION "tempfail" +#define DEF_MILT_DEF_ACTION "shutdown" extern char *var_milt_def_action; #define VAR_MILT_CONN_MACROS "milter_connect_macros" @@ -3571,10 +3571,6 @@ #define DEF_MILT_PROTOCOL "6" extern char *var_milt_protocol; -#define VAR_MILT_DEF_ACTION "milter_default_action" -#define DEF_MILT_DEF_ACTION "tempfail" -extern char *var_milt_def_action; - #define VAR_MILT_DAEMON_NAME "milter_macro_daemon_name" #define DEF_MILT_DAEMON_NAME "$" VAR_MYHOSTNAME extern char *var_milt_daemon_name; diff -ur --new-file /var/tmp/postfix-3.10.7/src/milter/milter8.c ./src/milter/milter8.c --- /var/tmp/postfix-3.10.7/src/milter/milter8.c 2025-01-07 17:25:43.000000000 -0500 +++ ./src/milter/milter8.c 2026-02-18 11:40:51.000000000 -0500 @@ -523,6 +523,8 @@ } if (strcasecmp(milter->def_action, "accept") == 0) { reply = 0; + } else if (strcasecmp(milter->def_action, "shutdown") == 0) { + reply = "421 4.3.5 Server configuration problem - try again later"; } else if (strcasecmp(milter->def_action, "quarantine") == 0) { reply = "Hdefault_action"; } else { @@ -557,6 +559,8 @@ reply = "550 5.5.0 Service unavailable"; } else if (strcasecmp(milter->def_action, "tempfail") == 0) { reply = "451 4.7.1 Service unavailable - try again later"; + } else if (strcasecmp(milter->def_action, "shutdown") == 0) { + reply = "421 4.7.1 Service unavailable - try again later"; } else if (strcasecmp(milter->def_action, "quarantine") == 0) { reply = "Hdefault_action"; } else { diff -ur --new-file /var/tmp/postfix-3.10.7/src/util/msg_vstream.c ./src/util/msg_vstream.c --- /var/tmp/postfix-3.10.7/src/util/msg_vstream.c 2006-06-15 14:07:16.000000000 -0400 +++ ./src/util/msg_vstream.c 2026-02-18 11:52:29.000000000 -0500 @@ -80,6 +80,7 @@ msg_tag = name; msg_stream = vp; + vstream_no_debug(vp); if (first_call) { first_call = 0; msg_output(msg_vstream_print); diff -ur --new-file /var/tmp/postfix-3.10.7/src/util/vstream.c ./src/util/vstream.c --- /var/tmp/postfix-3.10.7/src/util/vstream.c 2023-05-16 10:12:59.000000000 -0400 +++ ./src/util/vstream.c 2026-02-18 11:52:29.000000000 -0500 @@ -166,6 +166,9 @@ /* int vstream_fstat(stream, flags) /* VSTREAM *stream; /* int flags; +/* +/* void vstream_no_debug(stream) +/* VSTREAM *stream; /* DESCRIPTION /* The \fIvstream\fR module implements light-weight buffered I/O /* similar to the standard I/O routines. @@ -494,6 +497,10 @@ /* .IP VSTREAM_FLAG_OWN_VSTRING /* The stream 'owns' the VSTRING buffer, and is responsible /* for cleaning up when the stream is closed. +/* +/* vstream_no_debug() disables 'spontaneous' logging of output +/* activity on the last specified VSTREAM, to prevent recursive +/* logging. /* DIAGNOSTICS /* Panics: interface violations. Fatal errors: out of memory. /* SEE ALSO @@ -674,6 +681,8 @@ } \ } while (0) +static VSTREAM *vstream_log_veto; + /* vstream_buf_init - initialize buffer */ static void vstream_buf_init(VBUF *bp, int flags) @@ -771,7 +780,7 @@ used = bp->len - bp->cnt; left_over = used - to_flush; - if (msg_verbose > 2 && stream != VSTREAM_ERR) + if (msg_verbose > 2 && stream != vstream_log_veto) msg_info("%s: fd %d flush %ld", myname, stream->fd, (long) to_flush); if (to_flush < 0 || left_over < 0) msg_panic("%s: bad to_flush %ld", myname, (long) to_flush); @@ -834,7 +843,7 @@ } } } - if (msg_verbose > 2 && stream != VSTREAM_ERR && n != to_flush) + if (msg_verbose > 2 && stream != vstream_log_veto && n != to_flush) msg_info("%s: %d flushed %ld/%ld", myname, stream->fd, (long) n, (long) to_flush); } @@ -1890,6 +1899,13 @@ return (stream); } +/* vstream_no_debug - debug logging lockout */ + +void vstream_no_debug(VSTREAM *stream) +{ + vstream_log_veto = stream; +} + #ifdef TEST static void copy_line(ssize_t bufsize) diff -ur --new-file /var/tmp/postfix-3.10.7/src/util/vstream.h ./src/util/vstream.h --- /var/tmp/postfix-3.10.7/src/util/vstream.h 2021-08-08 08:25:14.000000000 -0400 +++ ./src/util/vstream.h 2026-02-18 11:52:29.000000000 -0500 @@ -274,6 +274,11 @@ vstream_memreopen((VSTREAM *) 0, (string), (flags)) VSTREAM *vstream_memreopen(VSTREAM *, struct VSTRING *, int); + /* + * Debug logging lockout. + */ +extern void vstream_no_debug(VSTREAM *); + /* LICENSE /* .ad /* .fi