[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1003261: Debdiff for bullseye pu



Also, I meant to put the d/changelog in the bug and forgot:

postfix (3.5.13-0+deb11u1) bullseye; urgency=medium

  [Scott Kitterman]

  * Update debian/watch to track v3.5 versions for stable updates
  * Refresh patches
  * Include compatibility_level in addition to postifx version when
    determining default value for chroot in master.cf.  Closes: #995129
  * Fixup errors in postifx-add-* man pages.  Closes: #995031
  * Update main/master.cf.proto on upgrade if not modified.  Closes: #991513
  * Update d/p/70_postfix-check.diff to exclude makedefs.out from synlink
    check.  Closes: #926331
  * Test that nothing is reported by postfix check in autopkgtest
  * Do not override user set default_transport in postinst.  Closes: #988538
  * Remove left-over ca-certificates.crt file from postfix chroot. 
    Closes: #991609
  * Add information about keeping resolv.conf up to date in the chroot with
    the resolvconf package.  Closes: #964762

  [Sergio Gelato]

  * Correct if-up.d to not error out if postfix can't send mail yet. 
    Closes: #959864

  [Miriam España Acebal]

  * Removed LDFLAG -Bsymbolic-functions to fix issue where TLS is disabled
    when private/tlmsgr socket is not found.  lp: #1885403

  [Paride Legovini]

  * d/postfix.postinst: tolerate search domain with a leading dot. 
    Closes: #991950

  [Wietse Venema]

  * 3.5.7
    - Bugfix (introduced: Postfix 3.4, already fixed in Postfix
      3.6): tlsproxy(8) was using the wrong DANE macro for
      connections with DANE trust anchors or with non-DANE trust
      anchors (WTF: Thorsten Habich found this bug in the use
      case that has nothing to do with DANE). This resulted in a
      global certificate verify function pointer race, between
      TLS handshakes that use TLS trust achors and handshakes
      that use PKI. No memory was corrupted in the course of all
      this.  Viktor Dukhovni. File: tlsproxy/tlsproxy.c.

    - Cleanup: the posttls-finger '-X' option reported a false
      conflict with '-r'. File: posttls-finger/posttls-finger.c.

  * 3.5.8
    - Bugfix (introduced: Postfix 2.0): smtp_sasl_mechanism_filter
      ignored table lookup errors, treating them as 'not found'.
      Found during Postfix 3.6 development. File: smtp/smtp_sasl_proto.c.

    - Bugfix (introduced: Postfix 2.3): when deleting a recipient
      with a milter, delete the recipient from the duplicate
      filter, so that the recipient can be added back. Backported
      from Postfix 3.6. Files: global/been_here.[hc],
      cleanup/cleanup_milter.c.

    - Bugfix (introduced: before Postfix alpha): the code that
      looks for Delivered-To: headers ignored headers longer than
      $line_length_limit. Backported from Postfix 3.6. File:
      global/delivered_hdr.c.

    - Bugfix (introduced: Postfix 2.8): save a copy of the
      postscreen_dnsbl_reply_map lookup result. This has no effect
      when the recommended texthash: look table is used, but it
      may avoid stale data with other lookup tables. File:
      postscreen/postscreen_dnsbl.c.

    - Bugfix (introduced: Postfix 2.2): after processing an
      XCCLIENT command, the smtps service was waiting for a TLS
      handshake. Found by Aki Tuomi. File: smtpd/smtpd.c.

    - Bugfix (introduced: Postfix 2.3): static maps did not free
      their casefolding buffer. File: util/dict_static.c.

    - Bugfix (introduced: Postfix 3.5): the Postfix SMTP client
      broke message headers longer than $line_length_limit, causing
      subsequent header content to become message body content.
      Reported by Andreas Weigel, fix by Viktor Dukhovni. File:
      smtp/smtp_proto.c.

  * 3.5.9
    - Feature: when a Postfix program makes a DNS query that
      requests DNSSEC validation (usually for Postfix DANE support)
      but the DNS response is not DNSSEC validated, Postfix will
      send a DNS query configured with the "dnssec_probe" parameter
      to determine if DNSSEC support is available, and logs a
      warning if it is not. By default, the probe has type "ns"
      and domain name ".". The probe is sent once per process
      lifetime. Files: dns/dns.h, dns/dns_lookup.c, dns/dns_sec.c,
      test_dns_lookup.c, global/mail_params.[hc], mantools/postlink.

    - The default "smtp_tls_dane_insecure_mx_policy = dane" was
       causing unnecessary dnssec_probe activity. The default is now
       "dane" when smtp_tls_security_level is "dane", otherwise it is
       "may". File: global/mail_params.h.

  * 3.5.10
    - Missing null pointer checks (introduced: Postfix 3.4) after
      an internal I/O error during the smtp(8) to tlsproxy(8)
      handshake. Found by Coverity, reported by Jaroslav Skarvada.
      Based on fix by Viktor Dukhovni. File: tls/tls_proxy_client_scan.c.

    - Null pointer bug (introduced: Postfix 3.0) and memory leak
      (introduced: Postfix 3.4) after an inline: table syntax
      error in main.cf or master.cf. Found by Coverity, reported
      by Jaroslav Skarvada. Based on fix by Viktor Dukhovni. File:
      util/dict_inline.c.

    - Incomplete null pointer check (introduced: Postfix 2.10)
      after truncated HaProxy version 1 handshake message. Found
      by Coverity, reported by Jaroslav Skarvada. Fix by Viktor
      Dukhovni. File: global/haproxy_srvr.c.

    - Missing null pointer check (introduced: Postfix alpha) after
      null argv[0] value. File: global/mail_task.c.

  * 3.5.11
    - Bugfix (introduced: Postfix 2.11): the command "postmap
      lmdb:/file/name" handled duplicate keys ungracefully,
      discarding entries stored up to and including the duplicate
      key, and causing a double free() call with lmdb versions
      0.9.17 and later. Reported by Adi Prasaja; double free()
      root cause analysis by Howard Chu. File: util/slmdb.c.

    - Typo (introduced: Postfix 3.4): silent_discard should be
      silent-discard. File: proto/BDAT_README.html.

    - Support for Postfix 3.6 compatibility_level syntax, to avoid
      fatal runtime errors when rolling back from Postfix 3.6 to
      an earlier supported version, or when sharing Postfix 3.6
      configuration files with an earlier supported Postfix
      version. File: global/mail_params.c.

  * 3.5.12
    - Bugfix (introduced: Postfix 3.4): the texthash: map
      implementation did not support "postmap -F" behavior.
      Reported by Christopher Gurnee, who also found the missing
      code in the postmap source. File: util/dict_thash.c.

    - Bugfix (introduced: 1999, Postfix 2.11) latent false "Result too
      large" (ERANGE) errors because an strtol() call had no 'errno
      = 0' statement before the call. Back-ported from Postfix 3.6.
      Files: postscreen/postscreen_tests.c, util/mac_expand.c.

    - Bugfix (introduced: Postfix 3.3): "null pointer read" error
      in the cleanup daemon when "header_from_format = standard"
      (the default as of Postfix 3.3) and email was submitted
      with /usr/sbin/sendmail without From: header, and an all-space
      full name was specified in 1) the password file, 2) with
      "sendmail -F", or 3) with the NAME environment variable.
      Found by Renaud Metrich. File: cleanup/cleanup_message.c.

    - Bugfix (introduced: 1999): the Postfix SMTP server was
      sending all session transcripts to the error_notice_recipient,
      instead of sending transcripts of bounced mail to the
      bounce_notice_recipient. File: smtpd/smtpd_chat.c.

    - Bugfix (introduced: Postfix 2.4): false "too many reverse
      jump" warnings in the showq daemon. The loop detection code
      was comparing memory addresses instead of queue file names.
      It now properly compares strings. Reported by Mehmet Avcioglu.
      File: global/record.c.

  * 3.5.13
    - Bitrot: OpenSSL 3.x requires const. File: tls/tls_misc.c.

    - Bugfix (bug introduced: Postfix 2.10): postconf -x produced
      incorrect output, because different functions were implicitly
      sharing a buffer for intermediate results. Reported
      by raf, root cause analysis by Viktor Dukhovni. File:
      postconf/postconf_builtin.c.

    - Bugfix (problem introduced: Postfix 2.11): check_ccert_access
      worked as expected, but produced a spurious warning when
      Postfix was built without SASL support. Fix by Brad Barden.
      File: smtpd/smtpd_check.c.

    - Bugfix (introduced: Postfix 2.4): queue file corruption
      after a Milter (for example, MIMEDefang) made a request to
      replace the message body with a copy of that message body
      plus additional text (for example, a SpamAssassin report).

      The most likely impacts were a) the queue manager reporting
      a fatal error resulting in email delivery delays, or b) the
      queue manager reporting the corruption and moving the message
      to the corrupt queue for damaged messages.

      However, a determined adversary could craft an email message
      that would trigger the bug, and insert a content filter
      destination or a redirect email address into its queue file.
      Postfix would then deliver the message headers there, in
      most cases without delivering the message body. With enough
      experimentation, an attacker could make Postfix deliver
      both the message headers and body.

      The details of a successful attack depend on the Milter
      implementation, and on the Postfix and Milter configuration
      details; these can be determined remotely through
      experimentation.  Failed experiments may be detected when
      the queue manager terminates with a fatal error, or when
      the queue manager moves damaged files to the "corrupt" queue
      as evidence.

      Technical details: when Postfix executes a "replace body"
      Milter request it will reuse queue file storage that was
      used by the existing email message body. If the new body
      is larger, Postfix will append body content to the end of
      the queue file. The corruption happened when a Milter (for
      example, MIMEDefang) made a request to replace the body of
      a message with a new body that contained a copy of the
      original body plus some new text, and the original body
      contained a line longer than $line_length_limit bytes (for
      example, an image encoded in base64 without hard or soft
      line breaks). In queue files, Postfix stores a long text
      line as multiple records with up to $line_length_limit bytes
      each. Unfortunately, Postfix's "replace body" support did
      not account for the additional queue file space needed to
      store the second etc.  record headers. And thus, the last
      record(s) of a long text line could overwrite one or more
      queue file records immediately after the space that was
      previously occupied by the original message body.

      Problem report by Benoît Panizzon.

  * Fix duplicate bounce_notice_recipient entries in postconf output. 
    Closes: #999694

Scott K
diff -Nru postfix-3.5.6/debian/changelog postfix-3.5.13/debian/changelog
--- postfix-3.5.6/debian/changelog	2020-08-02 17:11:04.000000000 -0400
+++ postfix-3.5.13/debian/changelog	2022-01-07 00:14:16.000000000 -0500
@@ -1,3 +1,238 @@
+postfix (3.5.13-0+deb11u1) bullseye; urgency=medium
+
+  [Scott Kitterman]
+
+  * Update debian/watch to track v3.5 versions for stable updates
+  * Refresh patches
+  * Include compatibility_level in addition to postifx version when
+    determining default value for chroot in master.cf.  Closes: #995129
+  * Fixup errors in postifx-add-* man pages.  Closes: #995031
+  * Update main/master.cf.proto on upgrade if not modified.  Closes: #991513
+  * Update d/p/70_postfix-check.diff to exclude makedefs.out from synlink
+    check.  Closes: #926331
+  * Test that nothing is reported by postfix check in autopkgtest
+  * Do not override user set default_transport in postinst.  Closes: #988538
+  * Remove left-over ca-certificates.crt file from postfix chroot. 
+    Closes: #991609
+  * Add information about keeping resolv.conf up to date in the chroot with
+    the resolvconf package.  Closes: #964762
+
+  [Sergio Gelato]
+
+  * Correct if-up.d to not error out if postfix can't send mail yet. 
+    Closes: #959864
+
+  [Miriam España Acebal]
+
+  * Removed LDFLAG -Bsymbolic-functions to fix issue where TLS is disabled
+    when private/tlmsgr socket is not found.  lp: #1885403
+
+  [Paride Legovini]
+
+  * d/postfix.postinst: tolerate search domain with a leading dot. 
+    Closes: #991950
+
+  [Wietse Venema]
+
+  * 3.5.7
+    - Bugfix (introduced: Postfix 3.4, already fixed in Postfix
+      3.6): tlsproxy(8) was using the wrong DANE macro for
+      connections with DANE trust anchors or with non-DANE trust
+      anchors (WTF: Thorsten Habich found this bug in the use
+      case that has nothing to do with DANE). This resulted in a
+      global certificate verify function pointer race, between
+      TLS handshakes that use TLS trust achors and handshakes
+      that use PKI. No memory was corrupted in the course of all
+      this.  Viktor Dukhovni. File: tlsproxy/tlsproxy.c.
+
+    - Cleanup: the posttls-finger '-X' option reported a false
+      conflict with '-r'. File: posttls-finger/posttls-finger.c.
+
+  * 3.5.8
+    - Bugfix (introduced: Postfix 2.0): smtp_sasl_mechanism_filter
+      ignored table lookup errors, treating them as 'not found'.
+      Found during Postfix 3.6 development. File: smtp/smtp_sasl_proto.c.
+
+    - Bugfix (introduced: Postfix 2.3): when deleting a recipient
+      with a milter, delete the recipient from the duplicate
+      filter, so that the recipient can be added back. Backported
+      from Postfix 3.6. Files: global/been_here.[hc],
+      cleanup/cleanup_milter.c.
+
+    - Bugfix (introduced: before Postfix alpha): the code that
+      looks for Delivered-To: headers ignored headers longer than
+      $line_length_limit. Backported from Postfix 3.6. File:
+      global/delivered_hdr.c.
+
+    - Bugfix (introduced: Postfix 2.8): save a copy of the
+      postscreen_dnsbl_reply_map lookup result. This has no effect
+      when the recommended texthash: look table is used, but it
+      may avoid stale data with other lookup tables. File:
+      postscreen/postscreen_dnsbl.c.
+
+    - Bugfix (introduced: Postfix 2.2): after processing an
+      XCCLIENT command, the smtps service was waiting for a TLS
+      handshake. Found by Aki Tuomi. File: smtpd/smtpd.c.
+
+    - Bugfix (introduced: Postfix 2.3): static maps did not free
+      their casefolding buffer. File: util/dict_static.c.
+
+    - Bugfix (introduced: Postfix 3.5): the Postfix SMTP client
+      broke message headers longer than $line_length_limit, causing
+      subsequent header content to become message body content.
+      Reported by Andreas Weigel, fix by Viktor Dukhovni. File:
+      smtp/smtp_proto.c.
+
+  * 3.5.9
+    - Feature: when a Postfix program makes a DNS query that
+      requests DNSSEC validation (usually for Postfix DANE support)
+      but the DNS response is not DNSSEC validated, Postfix will
+      send a DNS query configured with the "dnssec_probe" parameter
+      to determine if DNSSEC support is available, and logs a
+      warning if it is not. By default, the probe has type "ns"
+      and domain name ".". The probe is sent once per process
+      lifetime. Files: dns/dns.h, dns/dns_lookup.c, dns/dns_sec.c,
+      test_dns_lookup.c, global/mail_params.[hc], mantools/postlink.
+
+    - The default "smtp_tls_dane_insecure_mx_policy = dane" was
+       causing unnecessary dnssec_probe activity. The default is now
+       "dane" when smtp_tls_security_level is "dane", otherwise it is
+       "may". File: global/mail_params.h.
+
+  * 3.5.10
+    - Missing null pointer checks (introduced: Postfix 3.4) after
+      an internal I/O error during the smtp(8) to tlsproxy(8)
+      handshake. Found by Coverity, reported by Jaroslav Skarvada.
+      Based on fix by Viktor Dukhovni. File: tls/tls_proxy_client_scan.c.
+
+    - Null pointer bug (introduced: Postfix 3.0) and memory leak
+      (introduced: Postfix 3.4) after an inline: table syntax
+      error in main.cf or master.cf. Found by Coverity, reported
+      by Jaroslav Skarvada. Based on fix by Viktor Dukhovni. File:
+      util/dict_inline.c.
+
+    - Incomplete null pointer check (introduced: Postfix 2.10)
+      after truncated HaProxy version 1 handshake message. Found
+      by Coverity, reported by Jaroslav Skarvada. Fix by Viktor
+      Dukhovni. File: global/haproxy_srvr.c.
+
+    - Missing null pointer check (introduced: Postfix alpha) after
+      null argv[0] value. File: global/mail_task.c.
+
+  * 3.5.11
+    - Bugfix (introduced: Postfix 2.11): the command "postmap
+      lmdb:/file/name" handled duplicate keys ungracefully,
+      discarding entries stored up to and including the duplicate
+      key, and causing a double free() call with lmdb versions
+      0.9.17 and later. Reported by Adi Prasaja; double free()
+      root cause analysis by Howard Chu. File: util/slmdb.c.
+
+    - Typo (introduced: Postfix 3.4): silent_discard should be
+      silent-discard. File: proto/BDAT_README.html.
+
+    - Support for Postfix 3.6 compatibility_level syntax, to avoid
+      fatal runtime errors when rolling back from Postfix 3.6 to
+      an earlier supported version, or when sharing Postfix 3.6
+      configuration files with an earlier supported Postfix
+      version. File: global/mail_params.c.
+
+  * 3.5.12
+    - Bugfix (introduced: Postfix 3.4): the texthash: map
+      implementation did not support "postmap -F" behavior.
+      Reported by Christopher Gurnee, who also found the missing
+      code in the postmap source. File: util/dict_thash.c.
+
+    - Bugfix (introduced: 1999, Postfix 2.11) latent false "Result too
+      large" (ERANGE) errors because an strtol() call had no 'errno
+      = 0' statement before the call. Back-ported from Postfix 3.6.
+      Files: postscreen/postscreen_tests.c, util/mac_expand.c.
+
+    - Bugfix (introduced: Postfix 3.3): "null pointer read" error
+      in the cleanup daemon when "header_from_format = standard"
+      (the default as of Postfix 3.3) and email was submitted
+      with /usr/sbin/sendmail without From: header, and an all-space
+      full name was specified in 1) the password file, 2) with
+      "sendmail -F", or 3) with the NAME environment variable.
+      Found by Renaud Metrich. File: cleanup/cleanup_message.c.
+      (Closes: #968057)
+
+    - Bugfix (introduced: 1999): the Postfix SMTP server was
+      sending all session transcripts to the error_notice_recipient,
+      instead of sending transcripts of bounced mail to the
+      bounce_notice_recipient. File: smtpd/smtpd_chat.c.
+
+    - Bugfix (introduced: Postfix 2.4): false "too many reverse
+      jump" warnings in the showq daemon. The loop detection code
+      was comparing memory addresses instead of queue file names.
+      It now properly compares strings. Reported by Mehmet Avcioglu.
+      File: global/record.c.
+
+  * 3.5.13
+    - Bitrot: OpenSSL 3.x requires const. File: tls/tls_misc.c.
+
+    - Bugfix (bug introduced: Postfix 2.10): postconf -x produced
+      incorrect output, because different functions were implicitly
+      sharing a buffer for intermediate results. Reported
+      by raf, root cause analysis by Viktor Dukhovni. File:
+      postconf/postconf_builtin.c.
+
+    - Bugfix (problem introduced: Postfix 2.11): check_ccert_access
+      worked as expected, but produced a spurious warning when
+      Postfix was built without SASL support. Fix by Brad Barden.
+      File: smtpd/smtpd_check.c.
+
+    - Bugfix (introduced: Postfix 2.4): queue file corruption
+      after a Milter (for example, MIMEDefang) made a request to
+      replace the message body with a copy of that message body
+      plus additional text (for example, a SpamAssassin report).
+
+      The most likely impacts were a) the queue manager reporting
+      a fatal error resulting in email delivery delays, or b) the
+      queue manager reporting the corruption and moving the message
+      to the corrupt queue for damaged messages.
+
+      However, a determined adversary could craft an email message
+      that would trigger the bug, and insert a content filter
+      destination or a redirect email address into its queue file.
+      Postfix would then deliver the message headers there, in
+      most cases without delivering the message body. With enough
+      experimentation, an attacker could make Postfix deliver
+      both the message headers and body.
+
+      The details of a successful attack depend on the Milter
+      implementation, and on the Postfix and Milter configuration
+      details; these can be determined remotely through
+      experimentation.  Failed experiments may be detected when
+      the queue manager terminates with a fatal error, or when
+      the queue manager moves damaged files to the "corrupt" queue
+      as evidence.
+
+      Technical details: when Postfix executes a "replace body"
+      Milter request it will reuse queue file storage that was
+      used by the existing email message body. If the new body
+      is larger, Postfix will append body content to the end of
+      the queue file. The corruption happened when a Milter (for
+      example, MIMEDefang) made a request to replace the body of
+      a message with a new body that contained a copy of the
+      original body plus some new text, and the original body
+      contained a line longer than $line_length_limit bytes (for
+      example, an image encoded in base64 without hard or soft
+      line breaks). In queue files, Postfix stores a long text
+      line as multiple records with up to $line_length_limit bytes
+      each. Unfortunately, Postfix's "replace body" support did
+      not account for the additional queue file space needed to
+      store the second etc.  record headers. And thus, the last
+      record(s) of a long text line could overwrite one or more
+      queue file records immediately after the space that was
+      previously occupied by the original message body.
+
+      Problem report by Benoît Panizzon.
+
+  * Fix duplicate bounce_notice_recipient entries in postconf output. 
+    Closes: #999694
+
+ -- Scott Kitterman <scott@kitterman.com>  Fri, 07 Jan 2022 00:14:16 -0500
+
 postfix (3.5.6-1) unstable; urgency=medium
 
   [Dominic Raferd]
diff -Nru postfix-3.5.6/debian/configure-instance.sh postfix-3.5.13/debian/configure-instance.sh
--- postfix-3.5.6/debian/configure-instance.sh	2020-08-02 17:05:47.000000000 -0400
+++ postfix-3.5.13/debian/configure-instance.sh	2022-01-07 00:07:24.000000000 -0500
@@ -36,7 +36,8 @@
 
 config_dir=$($POSTCONF -hx config_directory)
 MAJOR_VER=$($POSTCONF -hx mail_version|cut -d. -f1)
-[ $MAJOR_VER -ge 3 ] && CHROOT_TEST="[yY]" || CHROOT_TEST="[-yY]"
+COMPAT=$($POSTCONF -xh compatibility_level|cut -d. -f1)
+[ $MAJOR_VER -ge 3 ] && [ $COMPAT -ge 1 ] && CHROOT_TEST="[yY]" || CHROOT_TEST="[-yY]"
 # see if anything is running chrooted.
 NEED_CHROOT=$(awk '/^[0-9a-z]/ && ($5 ~ "'"$CHROOT_TEST"'") { print "y"; exit}' ${config_dir}/master.cf)
 
diff -Nru postfix-3.5.6/debian/ip-up.d postfix-3.5.13/debian/ip-up.d
--- postfix-3.5.6/debian/ip-up.d	2020-08-02 16:36:19.000000000 -0400
+++ postfix-3.5.13/debian/ip-up.d	2022-01-07 00:07:24.000000000 -0500
@@ -38,6 +38,7 @@
 # hanging around.  Yes, sendmail is a symlink...
 if [ -n "$RUNNING" ]; then
 	if [ -x /usr/sbin/sendmail ]; then
-		/usr/sbin/sendmail -q >/dev/null 2>&1
+		# Don't propagate the exit code on failure; cf. #959864
+		/usr/sbin/sendmail -q >/dev/null 2>&1 || true
 	fi
 fi
diff -Nru postfix-3.5.6/debian/patches/02_kfreebsd_support.diff postfix-3.5.13/debian/patches/02_kfreebsd_support.diff
--- postfix-3.5.6/debian/patches/02_kfreebsd_support.diff	2020-08-02 16:36:19.000000000 -0400
+++ postfix-3.5.13/debian/patches/02_kfreebsd_support.diff	2022-01-07 00:07:24.000000000 -0500
@@ -2,7 +2,7 @@
 ===================================================================
 --- postfix.orig/makedefs
 +++ postfix/makedefs
-@@ -608,7 +608,7 @@ EOF
+@@ -595,7 +595,7 @@ EOF
  		: ${SHLIB_ENV="LD_LIBRARY_PATH=`pwd`/lib"}
  		: ${PLUGIN_LD="${CC-gcc} -shared"}
  		;;
diff -Nru postfix-3.5.6/debian/patches/06_debian_paths.diff postfix-3.5.13/debian/patches/06_debian_paths.diff
--- postfix-3.5.6/debian/patches/06_debian_paths.diff	2020-08-02 16:36:19.000000000 -0400
+++ postfix-3.5.13/debian/patches/06_debian_paths.diff	2022-01-07 00:07:24.000000000 -0500
@@ -48,7 +48,7 @@
 ===================================================================
 --- postfix.orig/makedefs
 +++ postfix/makedefs
-@@ -509,11 +509,18 @@ case "$SYSTEM.$RELEASE" in
+@@ -496,11 +496,18 @@ case "$SYSTEM.$RELEASE" in
  			exit 1
  		    fi
  		    SYSLIBS="-ldb"
@@ -68,7 +68,7 @@
  		    do
  			test -e $lib/lib$name.a -o -e $lib/lib$name.so && {
  			    SYSLIBS="$SYSLIBS -l$name"
-@@ -588,11 +595,18 @@ EOF
+@@ -575,11 +582,18 @@ EOF
  			exit 1
  		    fi
  		    SYSLIBS="-ldb"
@@ -88,7 +88,7 @@
  		    do
  			test -e $lib/lib$name.a -o -e $lib/lib$name.so && {
  			    SYSLIBS="$SYSLIBS -l$name"
-@@ -626,11 +640,18 @@ EOF
+@@ -613,11 +627,18 @@ EOF
  			exit 1
  		    fi
  		    SYSLIBS="-ldb"
diff -Nru postfix-3.5.6/debian/patches/12_add_bind_now_and_relro_to_pie.diff postfix-3.5.13/debian/patches/12_add_bind_now_and_relro_to_pie.diff
--- postfix-3.5.6/debian/patches/12_add_bind_now_and_relro_to_pie.diff	2020-08-02 16:36:19.000000000 -0400
+++ postfix-3.5.13/debian/patches/12_add_bind_now_and_relro_to_pie.diff	2022-01-07 00:07:24.000000000 -0500
@@ -15,7 +15,7 @@
 ===================================================================
 --- postfix.orig/makedefs
 +++ postfix/makedefs
-@@ -1226,7 +1226,7 @@ case "$pie" in
+@@ -1213,7 +1213,7 @@ case "$pie" in
         case " $CCARGS " in
           *" $CCARGS_PIE "*) CCARGS_PIE=;;
         esac
diff -Nru postfix-3.5.6/debian/patches/70_postfix-check.diff postfix-3.5.13/debian/patches/70_postfix-check.diff
--- postfix-3.5.6/debian/patches/70_postfix-check.diff	2020-08-02 16:36:19.000000000 -0400
+++ postfix-3.5.13/debian/patches/70_postfix-check.diff	2022-01-07 00:07:24.000000000 -0500
@@ -1,8 +1,8 @@
-Index: postfix-dev/conf/postfix-script
+Index: postfix/conf/postfix-script
 ===================================================================
---- postfix-dev.orig/conf/postfix-script	2019-03-01 11:47:22.941749233 -0500
-+++ postfix-dev/conf/postfix-script	2019-03-01 11:47:22.937749233 -0500
-@@ -341,9 +341,14 @@
+--- postfix.orig/conf/postfix-script
++++ postfix/conf/postfix-script
+@@ -341,9 +341,17 @@ check-warn)
  	find $todo ! -user root \
  	    -exec $WARN not owned by root: {} \;
  
@@ -12,7 +12,10 @@
  	    -exec $WARN group or other writable: {} \;
  
 +	find $todo -type l | while read f; do \
-+	    readlink "$f" | grep -q / && $WARN symlink leaves directory: "$f"; \
++	    # makedefs out known to be a symlink and OK
++	    if [ "$f" != "/etc/postfix/./makedefs.out" ]; then \
++	      readlink "$f" | grep -q / && $WARN symlink leaves directory: "$f"; \
++	    fi \
 +	done; \
 +
  	# Check Postfix mail_owner-owned directory tree owner/permissions.
diff -Nru postfix-3.5.6/debian/patches/postfix-dup-postconf.patch postfix-3.5.13/debian/patches/postfix-dup-postconf.patch
--- postfix-3.5.6/debian/patches/postfix-dup-postconf.patch	1969-12-31 19:00:00.000000000 -0500
+++ postfix-3.5.13/debian/patches/postfix-dup-postconf.patch	2022-01-07 00:07:24.000000000 -0500
@@ -0,0 +1,20 @@
+Description: Fix duplicate bounce_notice_recipient entries in postconf output.
+ Bug introduced on 2021-07-08. Reported by Vincent Lefevre.
+ https://marc.info/?l=postfix-users&m=163698504624352&w=2
+Bug-Debian: https://bugs.debian.org/999694
+Author: Wietse Venema <wietse@porcupine.org>
+Last-Update: 2021-11-15
+
+Index: postfix/src/smtpd/smtpd.c
+===================================================================
+--- postfix.orig/src/smtpd/smtpd.c
++++ postfix/src/smtpd/smtpd.c
+@@ -6419,7 +6419,7 @@ int     main(int argc, char **argv)
+ 	VAR_EOD_CHECKS, DEF_EOD_CHECKS, &var_eod_checks, 0, 0,
+ 	VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains, 0, 0,
+ 	VAR_RBL_REPLY_MAPS, DEF_RBL_REPLY_MAPS, &var_rbl_reply_maps, 0, 0,
+-	VAR_BOUNCE_RCPT, DEF_ERROR_RCPT, &var_bounce_rcpt, 1, 0,
++	VAR_BOUNCE_RCPT, DEF_BOUNCE_RCPT, &var_bounce_rcpt, 1, 0,
+ 	VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
+ 	VAR_REST_CLASSES, DEF_REST_CLASSES, &var_rest_classes, 0, 0,
+ 	VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, 0, 0,
diff -Nru postfix-3.5.6/debian/patches/series postfix-3.5.13/debian/patches/series
--- postfix-3.5.6/debian/patches/series	2020-08-02 16:49:01.000000000 -0400
+++ postfix-3.5.13/debian/patches/series	2022-01-07 00:07:24.000000000 -0500
@@ -1,3 +1,4 @@
+postfix-dup-postconf.patch
 02_kfreebsd_support.diff
 03_ldap3_by_default.diff
 04_remove_gdbm_support.diff
diff -Nru postfix-3.5.6/debian/postfix-add-filter.8 postfix-3.5.13/debian/postfix-add-filter.8
--- postfix-3.5.6/debian/postfix-add-filter.8	2020-08-02 16:36:19.000000000 -0400
+++ postfix-3.5.13/debian/postfix-add-filter.8	2022-01-07 00:07:24.000000000 -0500
@@ -13,8 +13,8 @@
 .ad
 .fi
 The \fBpostfix-add-filter\fR(8) command adds an smtp service named
-\fIsmtp service name\fR and and smtpd server listening on \fIsmtpd port\fR to
-\/etc/postfix/master.cf to facilitate integration of SMTP filters such as
+\fIsmtp service name\fR and an smtpd server listening on \fIsmtpd port\fR to
+/etc/postfix/master.cf to facilitate integration of SMTP filters such as
 amavisd-new or clamsmtp.  The configuration is based on the upstream
 recommendations for amavisd-new 2.6.0.  Administrators should verify it is
 appropriate for their requirements.
diff -Nru postfix-3.5.6/debian/postfix-add-policy.8 postfix-3.5.13/debian/postfix-add-policy.8
--- postfix-3.5.6/debian/postfix-add-policy.8	2020-08-02 16:36:19.000000000 -0400
+++ postfix-3.5.13/debian/postfix-add-policy.8	2022-01-07 00:07:24.000000000 -0500
@@ -14,7 +14,7 @@
 .fi
 The \fBpostfix-add-policy\fR(8) command adds an smtp policy server named
 \fIpolicy name\fR running using \fIusername\fR and called as \fIargv\fR to
-\/etc/postfix/master.cf to facilitate integration of SMTP policy servers such as
+/etc/postfix/master.cf to facilitate integration of SMTP policy servers such as
 postgrey or postfix-policyd-spf-perl.  The configuration is based on the Postfix
 SMTPD_POLICY_README.  Administrators should verify it is appropriate for their
 requirements.
diff -Nru postfix-3.5.6/debian/postfix.postinst postfix-3.5.13/debian/postfix.postinst
--- postfix-3.5.6/debian/postfix.postinst	2020-08-02 16:36:19.000000000 -0400
+++ postfix-3.5.13/debian/postfix.postinst	2022-01-07 00:07:24.000000000 -0500
@@ -49,7 +49,7 @@
 	if [ $myhostname = ${myhostname%.*} ]; then
 	    if [ -f /etc/resolv.conf ]; then
 		# The resolver uses the last one found, and ignores the rest
-		mydom=$(sed -n 's/^search[[:space:]]*\([^[:space:]]*\).*/\1/p;s/^domain[[:space:]]*\([^[:space:]]*\).*/\1/p' /etc/resolv.conf | tail -1)
+		mydom=$(sed -n 's/^search[[:space:]]*\.*\([^[:space:]]*\).*/\1/p;s/^domain[[:space:]]*\.*\([^[:space:]]*\).*/\1/p' /etc/resolv.conf | tail -1)
 		myhostname="$myhostname${mydom:+.$mydom}"
 	    else
 		myhostname="$myhostname.UNKNOWN"
@@ -293,6 +293,14 @@
     rmdir /etc/postfix/maildrop 2>/dev/null
 fi
 
+# cleanup old ca-certificates.crt that should never have been in chroot #991609
+# can be removed after bookworm release
+ca_bundle=/var/spool/postfix/etc/ssl/certs/ca-certificates.crt
+if [ -f $ca_bundle ]; then
+    echo Removing unneeded chroot file $ca_bundle
+    rm -f $ca_bundle
+fi
+
 set_maildrop_perms postdrop
 
 if [ "$mailer" != "No configuration" ]; then	# [
@@ -429,7 +437,11 @@
 
     db_fget postfix/main_mailer_type changed
     if [ "$RET" = "true" ]; then
-	dtrans=smtp
+	# If the user has picked something other than sntp, keep it
+	dtrans=$(postconf -hx default_transport)
+	if [ $(postconf -hx default_transport) = error ]; then
+	    dtrans=smtp
+	fi
 	# already have mailer
 	case "$mailer" in
 	    "Local only")	val=loopback-only; dtrans=error;;
@@ -578,9 +590,11 @@
 # Make sure we have main/master.cf.proto for multi-inst (#838528)
 if [ ! -f /etc/postfix/main.cf.proto ]; then
     cp /usr/share/postfix/main.cf.dist /etc/postfix/main.cf.proto
+    rm -rf /etc/postfix/main.cf.proto.old
 fi
 if [ ! -f /etc/postfix/master.cf.proto ]; then
     cp /usr/share/postfix/master.cf.dist /etc/postfix/master.cf.proto
+    rm -rf /etc/postfix/master.cf.proto.old
 fi
 
 if [ "$mailer" != "No configuration" ] || [ -f /etc/postfix/main.cf ]; then
diff -Nru postfix-3.5.6/debian/postfix.preinst postfix-3.5.13/debian/postfix.preinst
--- postfix-3.5.6/debian/postfix.preinst	2020-08-02 16:36:19.000000000 -0400
+++ postfix-3.5.13/debian/postfix.preinst	2022-01-07 00:07:24.000000000 -0500
@@ -269,6 +269,15 @@
 		rm -f /etc/postfix/postfix-script
 	fi
 
+	# If user has not modified master/main.proto, move aside so new version
+	# is installed (#991513)
+        cmp -s /usr/share/postfix/main.cf.dist /etc/postfix/main.cf.proto && \
+	    mv /etc/postfix/main.cf.proto /etc/postfix/main.cf.proto.old \
+	    || echo "/etc/postfix/main.cf.proto modified, not updating."
+        cmp -s /usr/share/postfix/master.cf.dist /etc/postfix/master.cf.proto && \
+	    mv /etc/postfix/master.cf.proto /etc/postfix/master.cf.proto.old \
+	    || echo "/etc/postfix/master.cf.proto modified, not updating."
+
 	if grep -q '^tlsmgr[[:space:]]*fifo' $MASTER; then
 	  tlsmgr_warning
 	fi
@@ -335,6 +344,14 @@
 	;;
 
     abort-upgrade)
+	if [ -f /etc/postfix/main.cf.proto.old ]; then
+	  mv /etc/postfix/main.cf.proto.old /etc/postfix/main.cf.proto
+	  echo "Restoring old /etc/postfix/main.cf.proto on failed upgrade."
+	fi
+	if [ -f /etc/postfix/master.cf.proto.old ]; then
+	  mv /etc/postfix/master.cf.proto.old /etc/postfix/master.cf.proto
+	  echo "Restoring old /etc/postfix/master.cf.proto on failed upgrade."
+	fi
 	;;
 
     *)
diff -Nru postfix-3.5.6/debian/README.Debian postfix-3.5.13/debian/README.Debian
--- postfix-3.5.6/debian/README.Debian	2020-08-02 16:36:19.000000000 -0400
+++ postfix-3.5.13/debian/README.Debian	2022-01-07 00:07:24.000000000 -0500
@@ -32,6 +32,10 @@
     described in the upstream documentation is order to problem integrate with
     Debian features such as using the system CA certificate bundle and proper
     chroot configuration with system libraries and services.
+2A. In the standard Debian networking configuration, postfix is not notified
+    if /etc/resolv.conf is updated, so the copy in the postfix chroot may
+    become stale.  Installation of the resolvconf package should prevent this
+    problem for networking configurations where it is an issue.
 3.  For policy reasons:
   a. SASL configuration goes in /etc/postfix/sasl
   b. myhostname=/path/to/file is supported (and used) in main.cf
diff -Nru postfix-3.5.6/debian/rules postfix-3.5.13/debian/rules
--- postfix-3.5.6/debian/rules	2020-08-02 16:36:19.000000000 -0400
+++ postfix-3.5.13/debian/rules	2022-01-07 00:07:24.000000000 -0500
@@ -15,6 +15,7 @@
 DISTRO:=$(shell (lsb_release -is 2>/dev/null || echo Debian) | sed s:Debian:Debian/GNU:)
 
 export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+export DEB_LDFLAGS_MAINT_STRIP = -Wl,-Bsymbolic-functions
 DPKG_EXPORT_BUILDFLAGS = 1
 include /usr/share/dpkg/buildflags.mk
 
diff -Nru postfix-3.5.6/debian/tests/test-postfix.py postfix-3.5.13/debian/tests/test-postfix.py
--- postfix-3.5.6/debian/tests/test-postfix.py	2020-08-02 16:36:19.000000000 -0400
+++ postfix-3.5.13/debian/tests/test-postfix.py	2022-01-07 00:07:24.000000000 -0500
@@ -41,6 +41,19 @@
 import unittest, subprocess, re, pexpect, smtplib, socket, os, time, tempfile
 import testlib
 
+import sys
+''' Test for postfix check output'''
+result = subprocess.run(['postconf', 'maillog_file = /dev/stdout'], capture_output=True, text=True)
+result = subprocess.run(['postfix', 'check'], capture_output=True, text=True)
+if result.returncode != 0:
+    print('postfix check failed with error code: {0}.'.format(result.returncode))
+    sys.exit(1)
+if result.stdout:
+    print('postfix check warning/error: {0}'.format(result.stdout[26:]))
+    subprocess.run(['postconf', 'maillog_file ='], capture_output=True, text=True)
+    sys.exit(1)
+subprocess.run(['postconf', 'maillog_file ='], capture_output=True, text=True)
+
 class PostfixTest(testlib.TestlibCase):
     '''Test Postfix MTA.'''
 
@@ -96,6 +109,7 @@
         subprocess.call(['mkdir','-p','/var/run/saslauthd'])
         subprocess.call(['/usr/sbin/service', 'saslauthd', 'stop'], stdout=subprocess.PIPE)
         subprocess.call(['/usr/sbin/service', 'saslauthd', 'start'], stdout=subprocess.PIPE)
+        subprocess.call(['cp', '/etc/sasldb2', '/var/spool/postfix/etc/sasldb2'])
 
     def tearDown(self):
         '''Clean up after each test_* function'''
diff -Nru postfix-3.5.6/debian/watch postfix-3.5.13/debian/watch
--- postfix-3.5.6/debian/watch	2020-08-02 16:36:19.000000000 -0400
+++ postfix-3.5.13/debian/watch	2022-01-07 00:07:24.000000000 -0500
@@ -1,3 +1,3 @@
 version=3
 
-opts=pasv,pgpsigurlmangle=s/$/.gpg2/ ftp://ftp.porcupine.org/mirrors/postfix-release/official/postfix-([\d+\.]+)\.tar\.gz
+opts=pasv,pgpsigurlmangle=s/$/.gpg2/ ftp://ftp.porcupine.org/mirrors/postfix-release/official/postfix-(3.5.[\d+\.]+)\.tar\.gz
diff -Nru postfix-3.5.6/HISTORY postfix-3.5.13/HISTORY
--- postfix-3.5.6/HISTORY	2020-07-26 14:28:09.000000000 -0400
+++ postfix-3.5.13/HISTORY	2021-11-07 18:09:38.000000000 -0500
@@ -24819,3 +24819,239 @@
 	the system-wide OpenSSL configuration of allowed TLS protocol
 	versions, for sessions where the remote SMTP client sends
 	SNI. It's better to be safe than sorry. File: tls/tls_server.c.
+
+20200821
+
+	Bugfix (introduced: Postfix 3.4, already fixed in Postfix
+	3.6): tlsproxy(8) was using the wrong DANE macro for
+	connections with DANE trust anchors or with non-DANE trust
+	anchors (WTF: Thorsten Habich found this bug in the use
+	case that has nothing to do with DANE). This resulted in a
+	global certificate verify function pointer race, between
+	TLS handshakes that use TLS trust achors and handshakes
+	that use PKI. No memory was corrupted in the course of all
+	this.  Viktor Dukhovni. File: tlsproxy/tlsproxy.c.
+
+	Cleanup: the posttls-finger '-X' option reported a false
+	conflict with '-r'. File: posttls-finger/posttls-finger.c.
+
+20200830
+
+	Bugfix (introduced: Postfix 2.0): smtp_sasl_mechanism_filter
+	ignored table lookup errors, treating them as 'not found'.
+	Found during Postfix 3.6 development. File: smtp/smtp_sasl_proto.c.
+
+202000920
+
+	Bugfix (introduced: Postfix 2.3): when deleting a recipient
+	with a milter, delete the recipient from the duplicate
+	filter, so that the recipient can be added back. Backported
+	from Postfix 3.6. Files: global/been_here.[hc],
+	cleanup/cleanup_milter.c.
+
+20200925
+
+	Bugfix (introduced: before Postfix alpha): the code that
+	looks for Delivered-To: headers ignored headers longer than
+	$line_length_limit. Backported from Postfix 3.6. File:
+	global/delivered_hdr.c.
+
+20201011
+
+	Bugfix (introduced: Postfix 2.8): save a copy of the
+	postscreen_dnsbl_reply_map lookup result. This has no effect
+	when the recommended texthash: look table is used, but it
+	may avoid stale data with other lookup tables. File:
+	postscreen/postscreen_dnsbl.c.
+
+20201022
+
+	Bugfix (introduced: Postfix 2.2): after processing an
+	XCCLIENT command, the smtps service was waiting for a TLS
+	handshake. Found by Aki Tuomi. File: smtpd/smtpd.c.
+
+20201025
+
+	Bugfix (introduced: Postfix 2.3): static maps did not free
+	their casefolding buffer. File: util/dict_static.c.
+
+20201104
+
+	Bugfix (introduced: Postfix 3.5): the Postfix SMTP client
+	broke message headers longer than $line_length_limit, causing
+	subsequent header content to become message body content.
+	Reported by Andreas Weigel, fix by Viktor Dukhovni. File:
+	smtp/smtp_proto.c.
+
+20210116
+
+        Feature: when a Postfix program makes a DNS query that
+        requests DNSSEC validation (usually for Postfix DANE support)
+        but the DNS response is not DNSSEC validated, Postfix will
+        send a DNS query configured with the "dnssec_probe" parameter
+        to determine if DNSSEC support is available, and logs a
+        warning if it is not. By default, the probe has type "ns"
+        and domain name ".". The probe is sent once per process
+        lifetime. Files: dns/dns.h, dns/dns_lookup.c, dns/dns_sec.c,
+        test_dns_lookup.c, global/mail_params.[hc], mantools/postlink.
+
+        The makedefs script no longer disables DNSSEC when Postfix
+        is built with libc-musl. Instead Postfix will rely on the
+        new dnssec_probe feature, and will log a warning when Postfix
+        requests DNSSEC validation, but the infrastructure does not
+        validate DNSSEC signatures. File: makedefs.
+
+        The default "smtp_tls_dane_insecure_mx_policy = dane" was
+        causing unnecessary dnssec_probe activity. The default is now
+        "dane" when smtp_tls_security_level is "dane", otherwise it is
+        "may". File: global/mail_params.h.
+
+20210411
+
+	Missing null pointer checks (introduced: Postfix 3.4) after
+	an internal I/O error during the smtp(8) to tlsproxy(8)
+	handshake. Found by Coverity, reported by Jaroslav Skarvada.
+	Based on fix by Viktor Dukhovni. File: tls/tls_proxy_client_scan.c.
+
+	Null pointer bug (introduced: Postfix 3.0) and memory leak
+	(introduced: Postfix 3.4) after an inline: table syntax
+	error in main.cf or master.cf. Found by Coverity, reported
+	by Jaroslav Skarvada. Based on fix by Viktor Dukhovni. File:
+	util/dict_inline.c.
+
+	Incomplete null pointer check (introduced: Postfix 2.10)
+	after truncated HaProxy version 1 handshake message. Found
+	by Coverity, reported by Jaroslav Skarvada. Fix by Viktor
+	Dukhovni. File: global/haproxy_srvr.c.
+
+	Missing null pointer check (introduced: Postfix alpha) after
+	null argv[0] value. File: global/mail_task.c.
+
+20210601
+
+	Bugfix (introduced: Postfix 2.11): the command "postmap
+	lmdb:/file/name" handled duplicate keys ungracefully,
+	discarding entries stored up to and including the duplicate
+	key, and causing a double free() call with lmdb versions
+	0.9.17 and later. Reported by Adi Prasaja; double free()
+	root cause analysis by Howard Chu. File: util/slmdb.c.
+
+20210609
+
+	Typo (introduced: Postfix 3.4): silent_discard should be
+	silent-discard. File: proto/BDAT_README.html.
+
+20210612
+
+	Support for Postfix 3.6 compatibility_level syntax, to avoid
+	fatal runtime errors when rolling back from Postfix 3.6 to
+	an earlier supported version, or when sharing Postfix 3.6
+	configuration files with an earlier supported Postfix
+	version. File: global/mail_params.c.
+
+20210615
+
+	Bugfix (introduced: Postfix 3.4): the texthash: map
+	implementation did not support "postmap -F" behavior.
+	Reported by Christopher Gurnee, who also found the missing
+	code in the postmap source. File: util/dict_thash.c.
+
+20210623
+
+	Bugfix (introduced: 1999, Postfix 2.11) latent false "Result too
+	large" (ERANGE) errors because an strtol() call had no 'errno
+	= 0' statement before the call. Back-ported from Postfix 3.6.
+	Files: postscreen/postscreen_tests.c, util/mac_expand.c.
+
+20210705
+
+	Bugfix (introduced: Postfix 3.3): "null pointer read" error
+	in the cleanup daemon when "header_from_format = standard"
+	(the default as of Postfix 3.3) and email was submitted
+	with /usr/sbin/sendmail without From: header, and an all-space
+	full name was specified in 1) the password file, 2) with
+	"sendmail -F", or 3) with the NAME environment variable.
+	Found by Renaud Metrich. File: cleanup/cleanup_message.c.
+
+20210708
+
+	Bugfix (introduced: 1999): the Postfix SMTP server was
+	sending all session transcripts to the error_notice_recipient,
+	instead of sending transcripts of bounced mail to the
+	bounce_notice_recipient. File: smtpd/smtpd_chat.c.
+
+20210713
+
+	Bugfix (introduced: Postfix 2.4): false "too many reverse
+	jump" warnings in the showq daemon. The loop detection code
+	was comparing memory addresses instead of queue file names.
+	It now properly compares strings. Reported by Mehmet Avcioglu.
+	File: global/record.c.
+
+20210811
+
+	Bitrot: OpenSSL 3.x requires const. File: tls/tls_misc.c.
+
+20210925
+
+	Bugfix (bug introduced: Postfix 2.10): postconf -x produced
+	incorrect output, because different functions were implicitly
+	sharing a buffer for intermediate results. Reported
+	by raf, root cause analysis by Viktor Dukhovni. File:
+	postconf/postconf_builtin.c.
+
+20211030
+
+	Bugfix (problem introduced: Postfix 2.11): check_ccert_access
+	worked as expected, but produced a spurious warning when
+	Postfix was built without SASL support. Fix by Brad Barden.
+	File: smtpd/smtpd_check.c.
+
+20211105
+
+	Bugfix (introduced: Postfix 2.4): queue file corruption
+	after a Milter (for example, MIMEDefang) made a request to
+	replace the message body with a copy of that message body
+	plus additional text (for example, a SpamAssassin report).
+
+	The most likely impacts were a) the queue manager reporting
+	a fatal error resulting in email delivery delays, or b) the
+	queue manager reporting the corruption and moving the message
+	to the corrupt queue for damaged messages.
+
+	However, a determined adversary could craft an email message
+	that would trigger the bug, and insert a content filter
+	destination or a redirect email address into its queue file.
+	Postfix would then deliver the message headers there, in
+	most cases without delivering the message body. With enough
+	experimentation, an attacker could make Postfix deliver
+	both the message headers and body.
+
+	The details of a successful attack depend on the Milter
+	implementation, and on the Postfix and Milter configuration
+	details; these can be determined remotely through
+	experimentation.  Failed experiments may be detected when
+	the queue manager terminates with a fatal error, or when
+	the queue manager moves damaged files to the "corrupt" queue
+	as evidence.
+
+	Technical details: when Postfix executes a "replace body"
+	Milter request it will reuse queue file storage that was
+	used by the existing email message body. If the new body
+	is larger, Postfix will append body content to the end of
+	the queue file. The corruption happened when a Milter (for
+	example, MIMEDefang) made a request to replace the body of
+	a message with a new body that contained a copy of the
+	original body plus some new text, and the original body
+	contained a line longer than $line_length_limit bytes (for
+	example, an image encoded in base64 without hard or soft
+	line breaks). In queue files, Postfix stores a long text
+	line as multiple records with up to $line_length_limit bytes
+	each. Unfortunately, Postfix's "replace body" support did
+	not account for the additional queue file space needed to
+	store the second etc.  record headers. And thus, the last
+	record(s) of a long text line could overwrite one or more
+	queue file records immediately after the space that was
+	previously occupied by the original message body.
+
+	Problem report by Benoît Panizzon.
diff -Nru postfix-3.5.6/html/BDAT_README.html postfix-3.5.13/html/BDAT_README.html
--- postfix-3.5.6/html/BDAT_README.html	2019-02-10 17:47:44.000000000 -0500
+++ postfix-3.5.13/html/BDAT_README.html	2021-06-13 15:02:04.000000000 -0400
@@ -51,7 +51,7 @@
     # The logging alternative:
     <a href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords</a> = chunking
     # The non-logging alternative:
-    <a href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords</a> = chunking, silent_discard
+    <a href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords</a> = chunking, silent-discard
 </pre>
 </blockquote>
 
diff -Nru postfix-3.5.6/html/lmtp.8.html postfix-3.5.13/html/lmtp.8.html
--- postfix-3.5.6/html/lmtp.8.html	2020-03-08 11:09:09.000000000 -0400
+++ postfix-3.5.13/html/lmtp.8.html	2021-01-16 18:19:54.000000000 -0500
@@ -365,6 +365,13 @@
               The  email  address  form that will be used in non-debug logging
               (info, warning, etc.).
 
+       Available in Postfix 3.5.9 and later:
+
+       <b><a href="postconf.5.html#dnssec_probe">dnssec_probe</a> (ns:.)</b>
+              The DNS query type (default: "ns") and DNS query name  (default:
+              ".") that Postfix may use to determine whether DNSSEC validation
+              is available.
+
 <b>MIME PROCESSING CONTROLS</b>
        Available in Postfix version 2.0 and later:
 
diff -Nru postfix-3.5.6/html/postconf.5.html postfix-3.5.13/html/postconf.5.html
--- postfix-3.5.6/html/postconf.5.html	2020-05-09 11:51:27.000000000 -0400
+++ postfix-3.5.13/html/postconf.5.html	2021-01-17 10:10:20.000000000 -0500
@@ -3031,6 +3031,66 @@
 
 </DD>
 
+<DT><b><a name="dnssec_probe">dnssec_probe</a>
+(default: ns:.)</b></DT><DD>
+
+<p> The DNS query type (default: "ns") and DNS query name (default:
+".") that Postfix may use to determine whether DNSSEC validation
+is available.
+</p>
+
+<p> Background: DNSSEC validation is needed for Postfix DANE support;
+this ensures that Postfix receives TLSA records with secure TLS
+server certificate info. When DNSSEC validation is unavailable,
+mail deliveries using <i>opportunistic</i> DANE will not be protected
+by server certificate info in TLSA records, and mail deliveries
+using <i>mandatory</i> DANE will not be made at all. </p>
+
+<p> By default, a Postfix process will send a DNSSEC probe after
+1) the process made a DNS query that requested DNSSEC validation,
+2) the process did not receive a DNSSEC validated response to this
+query or to an earlier query, and 3) the process did not already
+send a DNSSEC probe. <p>
+
+<p> When the DNSSEC probe has no response, or when the response is
+not DNSSEC validated, Postfix logs a warning that DNSSEC validation
+may be unavailable. </p>
+
+<p> Example: </p>
+
+<pre>
+warning: DNSSEC validation may be unavailable
+warning: reason: <a href="postconf.5.html#dnssec_probe">dnssec_probe</a> 'ns:.' received a response that is not DNSSEC validated
+warning: reason: <a href="postconf.5.html#dnssec_probe">dnssec_probe</a> 'ns:.' received no response: Server failure
+</pre>
+
+<p> Possible reasons why DNSSEC validation may be unavailable: </p>
+
+<ul>
+
+<li> The local /etc/resolv.conf file specifies a DNS resolver that
+does not validate DNSSEC signatures (that's
+$<a href="postconf.5.html#queue_directory">queue_directory</a>/etc/resolv.conf when a Postfix daemon runs in a
+chroot jail).
+
+<li> The local system library does not pass on the "DNSSEC validated"
+bit to Postfix, or Postfix does not know how to ask the library to
+do that.
+
+</ul>
+
+<p> By default, the DNSSEC probe asks for the DNS root zone NS
+records, because resolvers should always have that information
+cached. If Postfix runs on a network where the DNS root zone is not
+reachable, specify a different probe, or specify an empty <a href="postconf.5.html#dnssec_probe">dnssec_probe</a>
+value to disable the feature. </p>
+
+<p> This feature was backported from Postfix 3.6 to Postfix versions
+3.5.9, 3.4.19, 3.3.16. 3.2.21. </p>
+
+
+</DD>
+
 <DT><b><a name="dont_remove">dont_remove</a>
 (default: 0)</b></DT><DD>
 
@@ -12377,7 +12437,7 @@
 </DD>
 
 <DT><b><a name="smtp_tls_dane_insecure_mx_policy">smtp_tls_dane_insecure_mx_policy</a>
-(default: dane)</b></DT><DD>
+(default: see "postconf -d" output)</b></DT><DD>
 
 <p> The TLS policy for MX hosts with "secure" TLSA records when the
 nexthop destination security level is <b>dane</b>, but the MX
@@ -12401,6 +12461,12 @@
 "Verified", because the MX host name could have been forged.  </dd>
 </dl>
 
+<p> The default setting for Postfix &ge; 3.6 is "dane" with
+"<a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> = dane", otherwise "may". This behavior
+was backported to Postfix versions 3.5.9, 3.4.19, 3.3.16. 3.2.21.
+With earlier
+Postfix versions the default setting was always "dane". </p>
+
 <p> Though with "insecure" MX records an active attacker can
 compromise SMTP transport security by returning forged MX records,
 such attacks are "tamper-evident" since any forged MX hostnames
diff -Nru postfix-3.5.6/html/smtp.8.html postfix-3.5.13/html/smtp.8.html
--- postfix-3.5.6/html/smtp.8.html	2020-03-08 11:09:09.000000000 -0400
+++ postfix-3.5.13/html/smtp.8.html	2021-01-16 18:19:54.000000000 -0500
@@ -365,6 +365,13 @@
               The  email  address  form that will be used in non-debug logging
               (info, warning, etc.).
 
+       Available in Postfix 3.5.9 and later:
+
+       <b><a href="postconf.5.html#dnssec_probe">dnssec_probe</a> (ns:.)</b>
+              The DNS query type (default: "ns") and DNS query name  (default:
+              ".") that Postfix may use to determine whether DNSSEC validation
+              is available.
+
 <b>MIME PROCESSING CONTROLS</b>
        Available in Postfix version 2.0 and later:
 
diff -Nru postfix-3.5.6/makedefs postfix-3.5.13/makedefs
--- postfix-3.5.6/makedefs	2020-05-06 10:10:47.000000000 -0400
+++ postfix-3.5.13/makedefs	2021-01-16 10:10:00.000000000 -0500
@@ -228,19 +228,6 @@
  *) echo usage: $0 [system release] 1>&2; exit 1;;
 esac
 
-case "$SYSTEM" in
- Linux)
-    case "`PATH=/bin:/usr/bin ldd /bin/sh`" in
-     *-musl-*)
-	case "$CCARGS" in
-	 *-DNO_DNSSEC*) ;;
-	 *) echo Warning: libc-musl breaks DANE/TLSA security. 1>&2
-	    echo This build will not support DANE/TLSA. 1>&2
-	    CCARGS="$CCARGS -DNO_DNSSEC";;
-	esac;;
-    esac;;
-esac
-
 case "$SYSTEM.$RELEASE" in
    SCO_SV.3.2)	SYSTYPE=SCO5
 		# Use the native compiler by default
diff -Nru postfix-3.5.6/man/man5/postconf.5 postfix-3.5.13/man/man5/postconf.5
--- postfix-3.5.6/man/man5/postconf.5	2020-05-09 11:52:30.000000000 -0400
+++ postfix-3.5.13/man/man5/postconf.5	2021-01-17 10:10:20.000000000 -0500
@@ -1897,6 +1897,60 @@
 service performs DNS white/blacklist lookups.
 .PP
 This feature is available in Postfix 2.8 and later.
+.SH dnssec_probe (default: ns:.)
+The DNS query type (default: "ns") and DNS query name (default:
+".") that Postfix may use to determine whether DNSSEC validation
+is available.
+.PP
+Background: DNSSEC validation is needed for Postfix DANE support;
+this ensures that Postfix receives TLSA records with secure TLS
+server certificate info. When DNSSEC validation is unavailable,
+mail deliveries using \fIopportunistic\fR DANE will not be protected
+by server certificate info in TLSA records, and mail deliveries
+using \fImandatory\fR DANE will not be made at all.
+.PP
+By default, a Postfix process will send a DNSSEC probe after
+1) the process made a DNS query that requested DNSSEC validation,
+2) the process did not receive a DNSSEC validated response to this
+query or to an earlier query, and 3) the process did not already
+send a DNSSEC probe.
+.PP
+When the DNSSEC probe has no response, or when the response is
+not DNSSEC validated, Postfix logs a warning that DNSSEC validation
+may be unavailable.
+.PP
+Example:
+.PP
+.nf
+.na
+.ft C
+warning: DNSSEC validation may be unavailable
+warning: reason: dnssec_probe 'ns:.' received a response that is not DNSSEC validated
+warning: reason: dnssec_probe 'ns:.' received no response: Server failure
+.fi
+.ad
+.ft R
+.PP
+Possible reasons why DNSSEC validation may be unavailable:
+.IP \(bu
+The local /etc/resolv.conf file specifies a DNS resolver that
+does not validate DNSSEC signatures (that's
+$queue_directory/etc/resolv.conf when a Postfix daemon runs in a
+chroot jail).
+.IP \(bu
+The local system library does not pass on the "DNSSEC validated"
+bit to Postfix, or Postfix does not know how to ask the library to
+do that.
+.br
+.PP
+By default, the DNSSEC probe asks for the DNS root zone NS
+records, because resolvers should always have that information
+cached. If Postfix runs on a network where the DNS root zone is not
+reachable, specify a different probe, or specify an empty dnssec_probe
+value to disable the feature.
+.PP
+This feature was backported from Postfix 3.6 to Postfix versions
+3.5.9, 3.4.19, 3.3.16. 3.2.21.
 .SH dont_remove (default: 0)
 Don't remove queue files and save them to the "saved" mail queue.
 This is a debugging aid.  To inspect the envelope information and
@@ -7921,7 +7975,7 @@
 TLS connection reuse" for background details.
 .PP
 This feature is available in Postfix 3.4 and later.
-.SH smtp_tls_dane_insecure_mx_policy (default: dane)
+.SH smtp_tls_dane_insecure_mx_policy (default: see "postconf \-d" output)
 The TLS policy for MX hosts with "secure" TLSA records when the
 nexthop destination security level is \fBdane\fR, but the MX
 record was found via an "insecure" MX lookup.  The choices are:
@@ -7942,6 +7996,12 @@
 "Verified", because the MX host name could have been forged.
 .br
 .br
+The default setting for Postfix >= 3.6 is "dane" with
+"smtp_tls_security_level = dane", otherwise "may". This behavior
+was backported to Postfix versions 3.5.9, 3.4.19, 3.3.16. 3.2.21.
+With earlier
+Postfix versions the default setting was always "dane".
+.PP
 Though with "insecure" MX records an active attacker can
 compromise SMTP transport security by returning forged MX records,
 such attacks are "tamper\-evident" since any forged MX hostnames
diff -Nru postfix-3.5.6/man/man8/smtp.8 postfix-3.5.13/man/man8/smtp.8
--- postfix-3.5.6/man/man8/smtp.8	2020-03-08 11:09:08.000000000 -0400
+++ postfix-3.5.13/man/man8/smtp.8	2021-01-16 18:19:54.000000000 -0500
@@ -356,6 +356,12 @@
 .IP "\fBinfo_log_address_format (external)\fR"
 The email address form that will be used in non\-debug logging
 (info, warning, etc.).
+.PP
+Available in Postfix 3.5.9 and later:
+.IP "\fBdnssec_probe (ns:.)\fR"
+The DNS query type (default: "ns") and DNS query name (default:
+".") that Postfix may use to determine whether DNSSEC validation
+is available.
 .SH "MIME PROCESSING CONTROLS"
 .na
 .nf
diff -Nru postfix-3.5.6/mantools/postlink postfix-3.5.13/mantools/postlink
--- postfix-3.5.6/mantools/postlink	2020-01-26 12:34:39.000000000 -0500
+++ postfix-3.5.13/mantools/postlink	2021-01-16 17:31:12.000000000 -0500
@@ -695,6 +695,7 @@
     s;\bsmtp_per_record_deadline\b;<a href="postconf.5.html#smtp_per_record_deadline">$&</a>;g;
     s;\bsmtp_send_dummy_mail_auth\b;<a href="postconf.5.html#smtp_send_dummy_mail_auth">$&</a>;g;
     s;\bsmtp_balance_inet_protocols\b;<a href="postconf.5.html#smtp_balance_inet_protocols">$&</a>;g;
+    s;\bdnssec_probe\b;<a href="postconf.5.html#dnssec_probe">$&</a>;g;
     s;\bsmtp_tls_connection_reuse\b;<a href="postconf.5.html#smtp_tls_connection_reuse">$&</a>;g;
     s;\blmtp_tls_connection_reuse\b;<a href="postconf.5.html#lmtp_tls_connection_reuse">$&</a>;g;
     s;\bsmtpd_enforce_tls\b;<a href="postconf.5.html#smtpd_enforce_tls">$&</a>;g;
diff -Nru postfix-3.5.6/proto/BDAT_README.html postfix-3.5.13/proto/BDAT_README.html
--- postfix-3.5.6/proto/BDAT_README.html	2019-02-10 17:47:33.000000000 -0500
+++ postfix-3.5.13/proto/BDAT_README.html	2021-06-09 08:47:01.000000000 -0400
@@ -51,7 +51,7 @@
     # The logging alternative:
     smtpd_discard_ehlo_keywords = chunking
     # The non-logging alternative:
-    smtpd_discard_ehlo_keywords = chunking, silent_discard
+    smtpd_discard_ehlo_keywords = chunking, silent-discard
 </pre>
 </blockquote>
 
diff -Nru postfix-3.5.6/proto/postconf.proto postfix-3.5.13/proto/postconf.proto
--- postfix-3.5.6/proto/postconf.proto	2020-05-09 11:51:27.000000000 -0400
+++ postfix-3.5.13/proto/postconf.proto	2021-01-17 10:10:15.000000000 -0500
@@ -16815,7 +16815,7 @@
 This feature is available in Postfix 3.1 and later.
 </p>
 
-%PARAM smtp_tls_dane_insecure_mx_policy dane
+%PARAM smtp_tls_dane_insecure_mx_policy see "postconf -d" output
 
 <p> The TLS policy for MX hosts with "secure" TLSA records when the
 nexthop destination security level is <b>dane</b>, but the MX
@@ -16839,6 +16839,12 @@
 "Verified", because the MX host name could have been forged.  </dd>
 </dl>
 
+<p> The default setting for Postfix &ge; 3.6 is "dane" with
+"smtp_tls_security_level = dane", otherwise "may". This behavior
+was backported to Postfix versions 3.5.9, 3.4.19, 3.3.16. 3.2.21.
+With earlier
+Postfix versions the default setting was always "dane". </p>
+
 <p> Though with "insecure" MX records an active attacker can
 compromise SMTP transport security by returning forged MX records,
 such attacks are "tamper-evident" since any forged MX hostnames
@@ -17698,3 +17704,59 @@
 such games to circumvent Postfix access policies. </p>
 
 <p> This feature is available in Postfix 3.5 and later. </p>
+
+%PARAM dnssec_probe ns:.
+
+<p> The DNS query type (default: "ns") and DNS query name (default:
+".") that Postfix may use to determine whether DNSSEC validation
+is available.
+</p>
+
+<p> Background: DNSSEC validation is needed for Postfix DANE support;
+this ensures that Postfix receives TLSA records with secure TLS
+server certificate info. When DNSSEC validation is unavailable,
+mail deliveries using <i>opportunistic</i> DANE will not be protected
+by server certificate info in TLSA records, and mail deliveries
+using <i>mandatory</i> DANE will not be made at all. </p>
+
+<p> By default, a Postfix process will send a DNSSEC probe after
+1) the process made a DNS query that requested DNSSEC validation,
+2) the process did not receive a DNSSEC validated response to this
+query or to an earlier query, and 3) the process did not already
+send a DNSSEC probe. <p>
+
+<p> When the DNSSEC probe has no response, or when the response is
+not DNSSEC validated, Postfix logs a warning that DNSSEC validation
+may be unavailable. </p>
+
+<p> Example: </p>
+
+<pre>
+warning: DNSSEC validation may be unavailable
+warning: reason: dnssec_probe 'ns:.' received a response that is not DNSSEC validated
+warning: reason: dnssec_probe 'ns:.' received no response: Server failure
+</pre>
+
+<p> Possible reasons why DNSSEC validation may be unavailable: </p>
+
+<ul>
+
+<li> The local /etc/resolv.conf file specifies a DNS resolver that
+does not validate DNSSEC signatures (that's
+$queue_directory/etc/resolv.conf when a Postfix daemon runs in a
+chroot jail).
+
+<li> The local system library does not pass on the "DNSSEC validated"
+bit to Postfix, or Postfix does not know how to ask the library to
+do that.
+
+</ul>
+
+<p> By default, the DNSSEC probe asks for the DNS root zone NS
+records, because resolvers should always have that information
+cached. If Postfix runs on a network where the DNS root zone is not
+reachable, specify a different probe, or specify an empty dnssec_probe
+value to disable the feature. </p>
+
+<p> This feature was backported from Postfix 3.6 to Postfix versions
+3.5.9, 3.4.19, 3.3.16. 3.2.21. </p>
diff -Nru postfix-3.5.6/README_FILES/BDAT_README postfix-3.5.13/README_FILES/BDAT_README
--- postfix-3.5.6/README_FILES/BDAT_README	2019-02-10 17:47:44.000000000 -0500
+++ postfix-3.5.13/README_FILES/BDAT_README	2021-06-13 15:02:04.000000000 -0400
@@ -23,7 +23,7 @@
         # The logging alternative:
         smtpd_discard_ehlo_keywords = chunking
         # The non-logging alternative:
-        smtpd_discard_ehlo_keywords = chunking, silent_discard
+        smtpd_discard_ehlo_keywords = chunking, silent-discard
 
 Specify '-o smtpd_discard_ehlo_keywords=' in master.cf for the submission and
 smtps services, if you have clients that benefit from CHUNKING support.
diff -Nru postfix-3.5.6/README_FILES/RELEASE_NOTES postfix-3.5.13/README_FILES/RELEASE_NOTES
--- postfix-3.5.6/README_FILES/RELEASE_NOTES	2020-05-16 17:20:59.000000000 -0400
+++ postfix-3.5.13/README_FILES/RELEASE_NOTES	2021-01-16 17:24:24.000000000 -0500
@@ -25,9 +25,50 @@
 the software under the license of their choice. Those who are more
 comfortable with the IPL can continue with that license.
 
+Runtime detection of DNSSEC support
+-----------------------------------
+
+The Postfix build system will no longer automatically disable DNSSEC
+support when it determines that Postfix will use libc-musl. This removes
+the earlier libc-musl workaround for Postfix 3.2.15, 3.3.10, 3.4.12,
+and 3.5.2.
+
+Now, when a Postfix process requests DNSSEC support (typically, for
+Postfix DANE support), the process may do a runtime test to determine if
+DNSSEC validation is available. DNSSEC support may be broken because of
+local configuration, libc incompatibility, or other infrastructure issues.
+
+Background: DNSSEC validation is needed for Postfix DANE support;
+this ensures that Postfix receives TLSA records with secure TLS
+server certificate info. When DNSSEC validation is unavailable,
+mail deliveries using opportunistic DANE will not be protected by
+server certificate info in TLSA records, and mail deliveries using
+mandatory DANE will not be made at all.
+
+The dnssec_probe parameter specifies the DNS query type (default:
+"ns") and DNS query name (default: ".") that Postfix may use to
+determine whether DNSSEC validation is available. Specify an empty
+value to disable this feature.
+
+By default, a Postfix process will send a DNSSEC probe after 1) the
+process made a DNS query that requested DNSSEC validation, 2) the
+process did not receive a DNSSEC validated response to this query
+or to an earlier query, and 3) the process did not already send a
+DNSSEC probe.
+
+When the DNSSEC probe has no response, or when the response is not
+DNSSEC validated, Postfix logs a warning that DNSSEC validation may
+be unavailable. Examples:
+
+warning: DNSSEC validation may be unavailable
+warning: reason: dnssec_probe 'ns:.' received a response that is not DNSSEC validated
+warning: reason: dnssec_probe 'ns:.' received no response: Server failure
+
+This feature was backported from Postfix 3.6.
+
 libc-musl workaround for Postfix 3.2.15, 3.3.10, 3.4.12, and 3.5.2
 ------------------------------------------------------------------
-
+ 
 Security: this release disables DANE support on Linux systems with
 libc-musl, because libc-musl provides no indication whether DNS
 responses are authentic. This broke DANE support without a clear
diff -Nru postfix-3.5.6/RELEASE_NOTES postfix-3.5.13/RELEASE_NOTES
--- postfix-3.5.6/RELEASE_NOTES	2020-05-16 17:20:59.000000000 -0400
+++ postfix-3.5.13/RELEASE_NOTES	2021-01-16 17:24:24.000000000 -0500
@@ -25,9 +25,50 @@
 the software under the license of their choice. Those who are more
 comfortable with the IPL can continue with that license.
 
+Runtime detection of DNSSEC support
+-----------------------------------
+
+The Postfix build system will no longer automatically disable DNSSEC
+support when it determines that Postfix will use libc-musl. This removes
+the earlier libc-musl workaround for Postfix 3.2.15, 3.3.10, 3.4.12,
+and 3.5.2.
+
+Now, when a Postfix process requests DNSSEC support (typically, for
+Postfix DANE support), the process may do a runtime test to determine if
+DNSSEC validation is available. DNSSEC support may be broken because of
+local configuration, libc incompatibility, or other infrastructure issues.
+
+Background: DNSSEC validation is needed for Postfix DANE support;
+this ensures that Postfix receives TLSA records with secure TLS
+server certificate info. When DNSSEC validation is unavailable,
+mail deliveries using opportunistic DANE will not be protected by
+server certificate info in TLSA records, and mail deliveries using
+mandatory DANE will not be made at all.
+
+The dnssec_probe parameter specifies the DNS query type (default:
+"ns") and DNS query name (default: ".") that Postfix may use to
+determine whether DNSSEC validation is available. Specify an empty
+value to disable this feature.
+
+By default, a Postfix process will send a DNSSEC probe after 1) the
+process made a DNS query that requested DNSSEC validation, 2) the
+process did not receive a DNSSEC validated response to this query
+or to an earlier query, and 3) the process did not already send a
+DNSSEC probe.
+
+When the DNSSEC probe has no response, or when the response is not
+DNSSEC validated, Postfix logs a warning that DNSSEC validation may
+be unavailable. Examples:
+
+warning: DNSSEC validation may be unavailable
+warning: reason: dnssec_probe 'ns:.' received a response that is not DNSSEC validated
+warning: reason: dnssec_probe 'ns:.' received no response: Server failure
+
+This feature was backported from Postfix 3.6.
+
 libc-musl workaround for Postfix 3.2.15, 3.3.10, 3.4.12, and 3.5.2
 ------------------------------------------------------------------
-
+ 
 Security: this release disables DANE support on Linux systems with
 libc-musl, because libc-musl provides no indication whether DNS
 responses are authentic. This broke DANE support without a clear
diff -Nru postfix-3.5.6/src/cleanup/cleanup_body_edit.c postfix-3.5.13/src/cleanup/cleanup_body_edit.c
--- postfix-3.5.6/src/cleanup/cleanup_body_edit.c	2017-12-27 17:29:44.000000000 -0500
+++ postfix-3.5.13/src/cleanup/cleanup_body_edit.c	2021-11-05 18:39:27.000000000 -0400
@@ -207,7 +207,7 @@
     /*
      * Finally, output the queue file record.
      */
-    CLEANUP_OUT_BUF(state, REC_TYPE_NORM, buf);
+    CLEANUP_OUT_BUF(state, rec_type, buf);
     curr_rp->write_offs = vstream_ftell(state->dst);
 
     return (0);
diff -Nru postfix-3.5.6/src/cleanup/cleanup_message.c postfix-3.5.13/src/cleanup/cleanup_message.c
--- postfix-3.5.6/src/cleanup/cleanup_message.c	2019-11-09 18:23:23.000000000 -0500
+++ postfix-3.5.13/src/cleanup/cleanup_message.c	2021-07-24 18:20:43.000000000 -0400
@@ -776,9 +776,12 @@
 		} else {
 		    token = tok822_alloc(TOK822_QSTRING, state->fullname);
 		}
-		tok822_externalize(state->temp2, token, TOK822_STR_NONE);
-		tok822_free(token);
-		vstring_sprintf_append(state->temp2, " <%s>",
+		if (token) {
+		    tok822_externalize(state->temp2, token, TOK822_STR_NONE);
+		    tok822_free(token);
+		    vstring_strcat(state->temp2, " ");
+		}
+		vstring_sprintf_append(state->temp2, "<%s>",
 				       vstring_str(state->temp1));
 		break;
 
diff -Nru postfix-3.5.6/src/cleanup/cleanup_milter.c postfix-3.5.13/src/cleanup/cleanup_milter.c
--- postfix-3.5.6/src/cleanup/cleanup_milter.c	2020-03-08 11:42:19.000000000 -0400
+++ postfix-3.5.13/src/cleanup/cleanup_milter.c	2021-11-05 18:39:27.000000000 -0400
@@ -1803,6 +1803,10 @@
 		}
 		count++;
 	    }
+	    if (var_enable_orcpt)
+		been_here_drop(state->dups, "%s\n%d\n%s\n%s",
+			       dsn_orcpt ? dsn_orcpt : "", dsn_notify,
+			     orig_rcpt ? orig_rcpt : "", STR(int_rcpt_buf));
 	    /* FALLTHROUGH */
 	case REC_TYPE_DRCP:			/* canceled recipient */
 	case REC_TYPE_DONE:			/* can't happen */
@@ -1818,6 +1822,8 @@
 	    break;
 	}
     }
+    if (var_enable_orcpt == 0 && count > 0)
+	been_here_drop_fixed(state->dups, STR(int_rcpt_buf));
 
     if (msg_verbose)
 	msg_info("%s: deleted %d records for recipient \"%s\"",
@@ -1828,7 +1834,8 @@
 
 /* cleanup_repl_body - replace message body */
 
-static const char *cleanup_repl_body(void *context, int cmd, VSTRING *buf)
+static const char *cleanup_repl_body(void *context, int cmd, int rec_type,
+				             VSTRING *buf)
 {
     const char *myname = "cleanup_repl_body";
     CLEANUP_STATE *state = (CLEANUP_STATE *) context;
@@ -1840,7 +1847,7 @@
      */
     switch (cmd) {
     case MILTER_BODY_LINE:
-	if (cleanup_body_edit_write(state, REC_TYPE_NORM, buf) < 0)
+	if (cleanup_body_edit_write(state, rec_type, buf) < 0)
 	    return (cleanup_milter_error(state, errno));
 	break;
     case MILTER_BODY_START:
diff -Nru postfix-3.5.6/src/dns/dns.h postfix-3.5.13/src/dns/dns.h
--- postfix-3.5.6/src/dns/dns.h	2020-04-16 13:07:58.000000000 -0400
+++ postfix-3.5.13/src/dns/dns.h	2021-01-16 17:37:12.000000000 -0500
@@ -244,7 +244,12 @@
 	(lflags), (ltype))
 
  /*
-  * Request flags.
+  * The dns_lookup() rflag that requests DNSSEC validation.
+  */
+#define DNS_WANT_DNSSEC_VALIDATION(rflags)	((rflags) & RES_USE_DNSSEC)
+
+ /*
+  * lflags.
   */
 #define DNS_REQ_FLAG_STOP_OK	(1<<0)
 #define DNS_REQ_FLAG_STOP_INVAL	(1<<1)
@@ -309,6 +314,18 @@
   */
 const char *dns_str_resflags(unsigned long);
 
+ /*
+  * dns_sec.c.
+  */
+#define DNS_SEC_FLAG_AVAILABLE	(1<<0)	/* got some DNSSEC validated reply */
+#define DNS_SEC_FLAG_DONT_PROBE	(1<<1)	/* probe already sent, or disabled */
+
+#define DNS_SEC_STATS_SET(flags) (dns_sec_stats |= (flags))
+#define DNS_SEC_STATS_TEST(flags) (dns_sec_stats & (flags))
+
+extern int dns_sec_stats;		/* See DNS_SEC_FLAG_XXX above */
+extern void dns_sec_probe(int);
+
 /* LICENSE
 /* .ad
 /* .fi
diff -Nru postfix-3.5.6/src/dns/dns_lookup.c postfix-3.5.13/src/dns/dns_lookup.c
--- postfix-3.5.6/src/dns/dns_lookup.c	2020-04-16 13:07:58.000000000 -0400
+++ postfix-3.5.13/src/dns/dns_lookup.c	2021-01-16 11:24:08.000000000 -0500
@@ -171,6 +171,12 @@
 /*	Pointer to storage for the reply RCODE value. This gives
 /*	more detailed information than DNS_FAIL, DNS_RETRY, etc.
 /* DIAGNOSTICS
+/*	If DNSSEC validation is requested but the response is not
+/*	DNSSEC validated, dns_lookup() will send a one-time probe
+/*	query as configured with the \fBdnssec_probe\fR configuration
+/*	parameter, and will log a warning when the probe response
+/*	was not DNSSEC validated.
+/* .PP
 /*	dns_lookup() returns one of the following codes and sets the
 /*	\fIwhy\fR argument accordingly:
 /* .IP DNS_OK
@@ -463,7 +469,7 @@
      */
 #define XTRA_FLAGS (RES_USE_EDNS0 | RES_TRUSTAD)
 
-    if (flags & RES_USE_DNSSEC)
+    if (DNS_WANT_DNSSEC_VALIDATION(flags))
 	flags |= (RES_USE_EDNS0 | RES_TRUSTAD);
 
     /*
@@ -510,6 +516,8 @@
 	_res.options |= saved_options;
 	reply_header = (HEADER *) reply->buf;
 	reply->rcode = reply_header->rcode;
+	if ((reply->dnssec_ad = !!reply_header->ad) != 0)
+	    DNS_SEC_STATS_SET(DNS_SEC_FLAG_AVAILABLE);
 	if (h_errno != 0) {
 	    if (why)
 		vstring_sprintf(why, "Host or domain name not found. "
@@ -561,13 +569,8 @@
 
     /*
      * Initialize the reply structure. Some structure members are filled on
-     * the fly while the reply is being parsed.  Coerce AD bit to boolean.
+     * the fly while the reply is being parsed.
      */
-#if RES_USE_DNSSEC != 0
-    reply->dnssec_ad = (flags & RES_USE_DNSSEC) ? !!reply_header->ad : 0;
-#else
-    reply->dnssec_ad = 0;
-#endif
     SET_HAVE_DNS_REPLY_PACKET(reply, len);
     reply->query_start = reply->buf + sizeof(HEADER);
     reply->answer_start = 0;
@@ -885,7 +888,9 @@
 	    CORRUPT(DNS_RETRY);
 	if ((status = dns_get_fixed(pos, &fixed)) != DNS_OK)
 	    CORRUPT(status);
-	if (!valid_rr_name(rr_name, "resource name", fixed.type, reply))
+	if (strcmp(orig_name, ".") == 0 && *rr_name == 0)
+	     /* Allow empty response name for root queries. */ ;
+	else if (!valid_rr_name(rr_name, "resource name", fixed.type, reply))
 	    CORRUPT(DNS_INVAL);
 	if (fqdn)
 	    vstring_strcpy(fqdn, rr_name);
@@ -973,7 +978,7 @@
     /*
      * The Linux resolver misbehaves when given an invalid domain name.
      */
-    if (!valid_hostname(name, DONT_GRIPE)) {
+    if (strcmp(name, ".") && !valid_hostname(name, DONT_GRIPE)) {
 	if (why)
 	    vstring_sprintf(why,
 		   "Name service error for %s: invalid host or domain name",
@@ -1010,6 +1015,10 @@
 		(void) dns_get_answer(orig_name, &reply, T_SOA, rrlist, fqdn,
 				      cname, c_len, &maybe_secure);
 	    }
+	    if (DNS_WANT_DNSSEC_VALIDATION(flags)
+		&& !DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE | \
+				       DNS_SEC_FLAG_DONT_PROBE))
+		dns_sec_probe(flags);		/* XXX Clobbers 'reply' */
 	    return (status);
 	}
 
@@ -1019,6 +1028,10 @@
 	 */
 	status = dns_get_answer(orig_name, &reply, type, rrlist, fqdn,
 				cname, c_len, &maybe_secure);
+	if (DNS_WANT_DNSSEC_VALIDATION(flags)
+	    && !DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE | \
+				   DNS_SEC_FLAG_DONT_PROBE))
+	    dns_sec_probe(flags);		/* XXX Clobbers 'reply' */
 	switch (status) {
 	default:
 	    if (why)
diff -Nru postfix-3.5.6/src/dns/dns_sec.c postfix-3.5.13/src/dns/dns_sec.c
--- postfix-3.5.6/src/dns/dns_sec.c	1969-12-31 19:00:00.000000000 -0500
+++ postfix-3.5.13/src/dns/dns_sec.c	2021-01-11 18:32:06.000000000 -0500
@@ -0,0 +1,144 @@
+/*++
+/* NAME
+/*	dns_sec 3
+/* SUMMARY
+/*	DNSSEC validation availability
+/* SYNOPSIS
+/*	#include <dns.h>
+/*
+/*	DNS_SEC_STATS_SET(
+/*	int	flags)
+/*
+/*	DNS_SEC_STATS_TEST(
+/*	int	flags)
+/*
+/*	void	dns_sec_probe(
+/*	int	rflags)
+/* DESCRIPTION
+/*	This module maintains information about the availability of
+/*	DNSSEC validation, in global flags that summarize
+/*	process-lifetime history.
+/* .IP DNS_SEC_FLAG_AVAILABLE
+/*	The process has received at least one DNSSEC validated
+/*	response to a query that requested DNSSEC validation.
+/* .IP DNS_SEC_FLAG_DONT_PROBE
+/*	The process has sent a DNSSEC probe (see below), or DNSSEC
+/*	probing is disabled by configuration.
+/* .PP
+/*	DNS_SEC_STATS_SET() sets one or more DNS_SEC_FLAG_* flags,
+/*	and DNS_SEC_STATS_TEST() returns non-zero if any of the
+/*	specified flags is set.
+/*
+/*	dns_sec_probe() generates a query to the target specified
+/*	with the \fBdnssec_probe\fR configuration parameter. It
+/*	sets the DNS_SEC_FLAG_DONT_PROBE flag, and it calls
+/*	dns_lookup() which sets DNS_SEC_FLAG_AVAILABLE if it receives
+/*	a DNSSEC validated response. Preconditions:
+/* .IP \(bu
+/*	The rflags argument must request DNSSEC validation (in the
+/*	same manner as dns_lookup() rflags argument).
+/* .IP \(bu
+/*	The DNS_SEC_FLAG_AVAILABLE and DNS_SEC_FLAG_DONT_PROBE
+/*	flags must be false.
+/* LICENSE
+/* .ad
+/* .fi
+/*	The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*	Wietse Venema
+/*	Google, Inc.
+/*	111 8th Avenue
+/*	New York, NY 10011, USA
+/*--*/
+
+#include <sys_defs.h>
+
+ /*
+  * Utility library.
+  */
+#include <msg.h>
+#include <mymalloc.h>
+#include <split_at.h>
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+
+ /*
+  * DNS library.
+  */
+#include <dns.h>
+
+int     dns_sec_stats;
+
+/* dns_sec_probe - send a probe to establish DNSSEC viability */
+
+void    dns_sec_probe(int rflags)
+{
+    const char myname[] = "dns_sec_probe";
+    char   *saved_dnssec_probe;
+    char   *qname;
+    int     qtype;
+    DNS_RR *rrlist = 0;
+    int     dns_status;
+    VSTRING *why;
+
+    /*
+     * Sanity checks.
+     */
+    if (!DNS_WANT_DNSSEC_VALIDATION(rflags))
+	msg_panic("%s: DNSSEC is not requested", myname);
+    if (DNS_SEC_STATS_TEST(DNS_SEC_FLAG_DONT_PROBE))
+	msg_panic("%s: DNSSEC probe was already sent, or probing is disabled",
+		  myname);
+    if (DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE))
+	msg_panic("%s: already have validated DNS response", myname);
+
+    /*
+     * Don't recurse.
+     */
+    DNS_SEC_STATS_SET(DNS_SEC_FLAG_DONT_PROBE);
+
+    /*
+     * Don't probe.
+     */
+    if (*var_dnssec_probe == 0)
+	return;
+
+    /*
+     * Parse the probe spec. Format is type:resource.
+     */
+    saved_dnssec_probe = mystrdup(var_dnssec_probe);
+    if ((qname = split_at(saved_dnssec_probe, ':')) == 0 || *qname == 0
+	|| (qtype = dns_type(saved_dnssec_probe)) == 0)
+	msg_fatal("malformed %s value: %s format is qtype:qname",
+		  VAR_DNSSEC_PROBE, var_dnssec_probe);
+
+    why = vstring_alloc(100);
+    dns_status = dns_lookup(qname, qtype, rflags, &rrlist, (VSTRING *) 0, why);
+    if (!DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE))
+	msg_warn("DNSSEC validation may be unavailable");
+    else if (msg_verbose)
+	msg_info(VAR_DNSSEC_PROBE
+		 " '%s' received a response that is DNSSEC validated",
+		 var_dnssec_probe);
+    switch (dns_status) {
+    default:
+	if (!DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE))
+	    msg_warn("reason: " VAR_DNSSEC_PROBE
+		     " '%s' received a response that is not DNSSEC validated",
+		     var_dnssec_probe);
+	if (rrlist)
+	    dns_rr_free(rrlist);
+	break;
+    case DNS_RETRY:
+    case DNS_FAIL:
+	msg_warn("reason: " VAR_DNSSEC_PROBE " '%s' received no response: %s",
+		 var_dnssec_probe, vstring_str(why));
+	break;
+    }
+    myfree(saved_dnssec_probe);
+    vstring_free(why);
+}
diff -Nru postfix-3.5.6/src/dns/Makefile.in postfix-3.5.13/src/dns/Makefile.in
--- postfix-3.5.6/src/dns/Makefile.in	2019-12-14 19:01:17.000000000 -0500
+++ postfix-3.5.13/src/dns/Makefile.in	2021-01-08 20:23:37.000000000 -0500
@@ -1,10 +1,10 @@
 SHELL	= /bin/sh
 SRCS	= dns_lookup.c dns_rr.c dns_strerror.c dns_strtype.c dns_rr_to_pa.c \
 	dns_sa_to_rr.c dns_rr_eq_sa.c dns_rr_to_sa.c dns_strrecord.c \
-	dns_rr_filter.c dns_str_resflags.c
+	dns_rr_filter.c dns_str_resflags.c dns_sec.c
 OBJS	= dns_lookup.o dns_rr.o dns_strerror.o dns_strtype.o dns_rr_to_pa.o \
 	dns_sa_to_rr.o dns_rr_eq_sa.o dns_rr_to_sa.o dns_strrecord.o \
-	dns_rr_filter.o dns_str_resflags.o
+	dns_rr_filter.o dns_str_resflags.o dns_sec.o
 HDRS	= dns.h
 TESTSRC	= test_dns_lookup.c test_alias_token.c
 DEFS	= -I. -I$(INC_DIR) -D$(SYSTYPE)
@@ -76,7 +76,7 @@
 	done
 	cd $(INC_DIR); chmod 644 $(HDRS)
 
-test_dns_lookup: test_dns_lookup.c $(LIB) $(LIBS)
+test_dns_lookup: test_dns_lookup.c all $(LIB) $(LIBS)
 	$(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
 
 dns_rr_to_pa: $(LIB) $(LIBS)
@@ -346,6 +346,18 @@
 dns_sa_to_rr.o: ../../include/vstring.h
 dns_sa_to_rr.o: dns.h
 dns_sa_to_rr.o: dns_sa_to_rr.c
+dns_sec.o: ../../include/check_arg.h
+dns_sec.o: ../../include/mail_params.h
+dns_sec.o: ../../include/msg.h
+dns_sec.o: ../../include/myaddrinfo.h
+dns_sec.o: ../../include/mymalloc.h
+dns_sec.o: ../../include/sock_addr.h
+dns_sec.o: ../../include/split_at.h
+dns_sec.o: ../../include/sys_defs.h
+dns_sec.o: ../../include/vbuf.h
+dns_sec.o: ../../include/vstring.h
+dns_sec.o: dns.h
+dns_sec.o: dns_sec.c
 dns_str_resflags.o: ../../include/check_arg.h
 dns_str_resflags.o: ../../include/myaddrinfo.h
 dns_str_resflags.o: ../../include/name_mask.h
diff -Nru postfix-3.5.6/src/dns/test_dns_lookup.c postfix-3.5.13/src/dns/test_dns_lookup.c
--- postfix-3.5.6/src/dns/test_dns_lookup.c	2016-02-21 18:06:59.000000000 -0500
+++ postfix-3.5.13/src/dns/test_dns_lookup.c	2021-01-16 11:24:08.000000000 -0500
@@ -77,6 +77,9 @@
     int     ch;
     int     lflags = DNS_REQ_FLAG_NONE;
 
+    if (var_dnssec_probe == 0)
+	var_dnssec_probe = mystrdup(DEF_DNSSEC_PROBE);
+
     msg_vstream_init(argv[0], VSTREAM_ERR);
     while ((ch = GETOPT(argc, argv, "f:npv")) > 0) {
 	switch (ch) {
diff -Nru postfix-3.5.6/src/global/been_here.c postfix-3.5.13/src/global/been_here.c
--- postfix-3.5.6/src/global/been_here.c	2019-02-09 18:26:28.000000000 -0500
+++ postfix-3.5.13/src/global/been_here.c	2020-11-04 16:06:12.000000000 -0500
@@ -26,6 +26,14 @@
 /*	BH_TABLE *dup_filter;
 /*	char	*format;
 /*
+/*	int	been_here_drop_fixed(dup_filter, string)
+/*	BH_TABLE *dup_filter;
+/*	char	*string;
+/*
+/*	int	been_here_drop(dup_filter, format, ...)
+/*	BH_TABLE *dup_filter;
+/*	char	*format;
+/*
 /*	void	been_here_free(dup_filter)
 /*	BH_TABLE *dup_filter;
 /* DESCRIPTION
@@ -46,6 +54,16 @@
 /*	been_here_check_fixed() and been_here_check() are similar
 /*	but do not update the duplicate filter.
 /*
+/*	been_here_drop_fixed() looks up a fixed string in the given
+/*	table, and deletes the entry if the string was found. The
+/*	result is non-zero (true) if the string was found, zero
+/*	(false) otherwise.
+/*
+/*	been_here_drop() formats its arguments, looks up the result
+/*	in the given table, and removes the entry if the formatted
+/*	result was found. The result is non-zero (true) if the
+/*	formatted result was found, zero (false) otherwise.
+/*
 /*	been_here_free() releases storage for a duplicate filter.
 /*
 /*	Arguments:
@@ -243,6 +261,67 @@
 
     /*
      * Cleanup.
+     */
+    if (folded_string)
+	vstring_free(folded_string);
+
+    return (status);
+}
+
+/* been_here_drop - remove filter entry with finer control */
+
+int     been_here_drop(BH_TABLE *dup_filter, const char *fmt,...)
+{
+    VSTRING *buf = vstring_alloc(100);
+    int     status;
+    va_list ap;
+
+    /*
+     * Construct the string to be dropped.
+     */
+    va_start(ap, fmt);
+    vstring_vsprintf(buf, fmt, ap);
+    va_end(ap);
+
+    /*
+     * Drop the filter entry.
+     */
+    status = been_here_drop_fixed(dup_filter, vstring_str(buf));
+
+    /*
+     * Cleanup.
+     */
+    vstring_free(buf);
+    return (status);
+}
+
+/* been_here_drop_fixed - remove filter entry */
+
+int     been_here_drop_fixed(BH_TABLE *dup_filter, const char *string)
+{
+    VSTRING *folded_string;
+    const char *lookup_key;
+    int     status;
+
+    /*
+     * Special processing: case insensitive lookup.
+     */
+    if (dup_filter->flags & BH_FLAG_FOLD) {
+	folded_string = vstring_alloc(100);
+	lookup_key = casefold(folded_string, string);
+    } else {
+	folded_string = 0;
+	lookup_key = string;
+    }
+
+    /*
+     * Drop the filter entry.
+     */
+    if ((status = been_here_check_fixed(dup_filter, lookup_key)) != 0)
+	htable_delete(dup_filter->table, lookup_key, (void (*) (void *)) 0);
+
+    /*
+     * Cleanup.
      */
     if (folded_string)
 	vstring_free(folded_string);
diff -Nru postfix-3.5.6/src/global/been_here.h postfix-3.5.13/src/global/been_here.h
--- postfix-3.5.6/src/global/been_here.h	2019-02-09 18:26:58.000000000 -0500
+++ postfix-3.5.13/src/global/been_here.h	2020-11-04 16:06:12.000000000 -0500
@@ -35,6 +35,8 @@
 extern int PRINTFLIKE(2, 3) been_here(BH_TABLE *, const char *,...);
 extern int been_here_check_fixed(BH_TABLE *, const char *);
 extern int PRINTFLIKE(2, 3) been_here_check(BH_TABLE *, const char *,...);
+extern int been_here_drop_fixed(BH_TABLE *, const char *);
+extern int PRINTFLIKE(2, 3) been_here_drop(BH_TABLE *, const char *,...);
 
 /* LICENSE
 /* .ad
diff -Nru postfix-3.5.6/src/global/delivered_hdr.c postfix-3.5.13/src/global/delivered_hdr.c
--- postfix-3.5.6/src/global/delivered_hdr.c	2015-01-27 10:22:33.000000000 -0500
+++ postfix-3.5.13/src/global/delivered_hdr.c	2020-11-04 16:10:00.000000000 -0500
@@ -115,6 +115,8 @@
     char   *cp;
     DELIVERED_HDR_INFO *info;
     const HEADER_OPTS *hdr;
+    int     curr_type;
+    int     prev_type;
 
     /*
      * Sanity check.
@@ -130,15 +132,20 @@
 
     /*
      * XXX Assume that mail_copy() produces delivered-to headers that fit in
-     * a REC_TYPE_NORM record. Lowercase the delivered-to addresses for
-     * consistency.
+     * a REC_TYPE_NORM or REC_TYPE_CONT record. Lowercase the delivered-to
+     * addresses for consistency.
      * 
      * XXX Don't get bogged down by gazillions of delivered-to headers.
      */
 #define DELIVERED_HDR_LIMIT	1000
 
-    while (rec_get(fp, info->buf, 0) == REC_TYPE_NORM
-	   && info->table->used < DELIVERED_HDR_LIMIT) {
+    for (prev_type = REC_TYPE_NORM;
+	 info->table->used < DELIVERED_HDR_LIMIT
+	 && ((curr_type = rec_get(fp, info->buf, 0)) == REC_TYPE_NORM
+	     || curr_type == REC_TYPE_CONT);
+	 prev_type = curr_type) {
+	if (prev_type != REC_TYPE_NORM)
+	    continue;
 	if (is_header(STR(info->buf))) {
 	    if ((hdr = header_opts_find(STR(info->buf))) != 0
 		&& hdr->type == HDR_DELIVERED_TO) {
diff -Nru postfix-3.5.6/src/global/haproxy_srvr.c postfix-3.5.13/src/global/haproxy_srvr.c
--- postfix-3.5.6/src/global/haproxy_srvr.c	2020-03-08 10:50:26.000000000 -0400
+++ postfix-3.5.13/src/global/haproxy_srvr.c	2021-04-03 19:46:12.000000000 -0400
@@ -201,6 +201,8 @@
     if (msg_verbose)
 	msg_info("haproxy_srvr_parse: proto=%s", STR_OR_NULL(str));
 
+    if (str == 0)
+	return (-1);
 #ifdef AF_INET6
     if (strcasecmp(str, "TCP6") == 0) {
 	if (strchr((char *) proto_info->sa_family_list, AF_INET6) != 0) {
diff -Nru postfix-3.5.6/src/global/mail_params.c postfix-3.5.13/src/global/mail_params.c
--- postfix-3.5.6/src/global/mail_params.c	2020-05-12 19:32:37.000000000 -0400
+++ postfix-3.5.13/src/global/mail_params.c	2021-06-13 15:20:12.000000000 -0400
@@ -152,6 +152,8 @@
 /*	char	*var_maillog_file_comp;
 /*	char	*var_maillog_file_stamp;
 /*	char	*var_postlog_service;
+/*
+/*	char	*var_dnssec_probe;
 /* DESCRIPTION
 /*	This module (actually the associated include file) defines
 /*	the names and defaults of all mail configuration parameters.
@@ -362,6 +364,8 @@
 char	*var_maillog_file_stamp;
 char	*var_postlog_service;
 
+char   *var_dnssec_probe;
+
 const char null_format_string[1] = "";
 
  /*
@@ -689,6 +693,7 @@
 	VAR_MAILLOG_FILE_COMP, DEF_MAILLOG_FILE_COMP, &var_maillog_file_comp, 1, 0,
 	VAR_MAILLOG_FILE_STAMP, DEF_MAILLOG_FILE_STAMP, &var_maillog_file_stamp, 1, 0,
 	VAR_POSTLOG_SERVICE, DEF_POSTLOG_SERVICE, &var_postlog_service, 1, 0,
+	VAR_DNSSEC_PROBE, DEF_DNSSEC_PROBE, &var_dnssec_probe, 0, 0,
 	0,
     };
     static const CONFIG_BOOL_TABLE first_bool_defaults[] = {
@@ -830,6 +835,17 @@
     const char *cp;
 
     /*
+     * Ignore the Postfix >= 3.6 compatibility_level's minor and patch
+     * fields, to allow rollback from Postfix >= 3.6, and to allow
+     * configuration sharing with Postfix >= 3.6.
+     */
+    const char *compat_level_str;
+
+    if ((compat_level_str = mail_conf_lookup(VAR_COMPAT_LEVEL)) != 0
+      && ISDIGIT(compat_level_str[0]) && strchr(compat_level_str, '.') != 0)
+	set_mail_conf_int(VAR_COMPAT_LEVEL, atoi(compat_level_str));
+
+    /*
      * Extract compatibility level first, so that we can determine what
      * parameters of interest are left at their legacy defaults.
      */
diff -Nru postfix-3.5.6/src/global/mail_params.h postfix-3.5.13/src/global/mail_params.h
--- postfix-3.5.6/src/global/mail_params.h	2020-05-09 11:51:27.000000000 -0400
+++ postfix-3.5.13/src/global/mail_params.h	2021-01-17 08:11:47.000000000 -0500
@@ -1617,7 +1617,7 @@
 
  /* SMTP only */
 #define VAR_SMTP_TLS_INSECURE_MX_POLICY "smtp_tls_dane_insecure_mx_policy"
-#define DEF_SMTP_TLS_INSECURE_MX_POLICY "dane"
+#define DEF_SMTP_TLS_INSECURE_MX_POLICY "${{$smtp_tls_security_level} == {dane} ? {dane} : {may}}"
 extern char *var_smtp_tls_insecure_mx_policy;
 
  /*
@@ -4202,6 +4202,13 @@
 #define DEF_INFO_LOG_ADDR_FORM	INFO_LOG_ADDR_FORM_NAME_EXTERNAL
 extern char *var_info_log_addr_form;
 
+ /*
+  * DNSSEC probing, to find out if DNSSEC validation is available.
+  */
+#define VAR_DNSSEC_PROBE	"dnssec_probe"
+#define DEF_DNSSEC_PROBE	"ns:."
+extern char *var_dnssec_probe;
+
 /* LICENSE
 /* .ad
 /* .fi
diff -Nru postfix-3.5.6/src/global/mail_task.c postfix-3.5.13/src/global/mail_task.c
--- postfix-3.5.6/src/global/mail_task.c	2019-01-29 17:24:42.000000000 -0500
+++ postfix-3.5.13/src/global/mail_task.c	2021-04-04 16:18:38.000000000 -0400
@@ -17,8 +17,8 @@
 /*
 /*	The result is overwritten with each call.
 /*
-/*	A null argv0 argument requests that the current
-/*	result is returned.
+/*	A null argv0 argument requests that the current result is
+/*	returned, or "unknown" when no current result exists.
 /* LICENSE
 /* .ad
 /* .fi
@@ -59,6 +59,8 @@
     const char *slash;
     const char *tag;
 
+    if (argv0 == 0 && canon_name == 0)
+	argv0 = "unknown";
     if (argv0) {
 	if (canon_name == 0)
 	    canon_name = vstring_alloc(10);
diff -Nru postfix-3.5.6/src/global/mail_version.h postfix-3.5.13/src/global/mail_version.h
--- postfix-3.5.6/src/global/mail_version.h	2020-07-26 14:14:48.000000000 -0400
+++ postfix-3.5.13/src/global/mail_version.h	2021-11-07 17:35:31.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	"20200726"
-#define MAIL_VERSION_NUMBER	"3.5.6"
+#define MAIL_RELEASE_DATE	"20211107"
+#define MAIL_VERSION_NUMBER	"3.5.13"
 
 #ifdef SNAPSHOT
 #define MAIL_VERSION_DATE	"-" MAIL_RELEASE_DATE
diff -Nru postfix-3.5.6/src/global/record.c postfix-3.5.13/src/global/record.c
--- postfix-3.5.6/src/global/record.c	2018-11-27 17:39:42.000000000 -0500
+++ postfix-3.5.13/src/global/record.c	2021-07-24 19:07:44.000000000 -0400
@@ -323,7 +323,7 @@
 int     rec_goto(VSTREAM *stream, const char *buf)
 {
     off_t   offset;
-    static const char *saved_path;
+    static char *saved_path;
     static off_t saved_offset;
     static int reverse_count;
 
@@ -336,11 +336,12 @@
      * is likely to insert 10000 message headers, but someone might append
      * 10000 recipients.
      */
-#define STREQ(x,y) ((x) == (y) && strcmp((x), (y)) == 0)
 #define REVERSE_JUMP_LIMIT	10000
 
-    if (!STREQ(saved_path, VSTREAM_PATH(stream))) {
-	saved_path = VSTREAM_PATH(stream);
+    if (saved_path == 0 || strcmp(saved_path, VSTREAM_PATH(stream)) != 0) {
+	if (saved_path)
+	    myfree(saved_path);
+	saved_path = mystrdup(VSTREAM_PATH(stream));
 	reverse_count = 0;
 	saved_offset = 0;
     }
diff -Nru postfix-3.5.6/src/milter/milter8.c postfix-3.5.13/src/milter/milter8.c
--- postfix-3.5.6/src/milter/milter8.c	2020-02-02 15:49:15.000000000 -0500
+++ postfix-3.5.13/src/milter/milter8.c	2021-11-05 18:39:27.000000000 -0400
@@ -1147,10 +1147,12 @@
 	    if (edit_resp == 0 && LEN(body_line_buf) > 0)
 		edit_resp = parent->repl_body(parent->chg_context,
 					      MILTER_BODY_LINE,
+					      REC_TYPE_NORM,
 					      body_line_buf);
 	    if (edit_resp == 0)
 		edit_resp = parent->repl_body(parent->chg_context,
 					      MILTER_BODY_END,
+					      /* unused*/ 0,
 					      (VSTRING *) 0);
 	    body_edit_lockout = 1;
 	    vstring_free(body_line_buf);
@@ -1546,6 +1548,7 @@
 			body_line_buf = vstring_alloc(var_line_limit);
 			edit_resp = parent->repl_body(parent->chg_context,
 						      MILTER_BODY_START,
+						      /* unused */ 0,
 						      (VSTRING *) 0);
 		    }
 		    /* Extract lines from the on-the-wire CRLF format. */
@@ -1559,9 +1562,18 @@
 						 LEN(body_line_buf) - 1);
 			    edit_resp = parent->repl_body(parent->chg_context,
 							  MILTER_BODY_LINE,
+							  REC_TYPE_NORM,
 							  body_line_buf);
 			    VSTRING_RESET(body_line_buf);
 			} else {
+			    /* Preserves \r if not followed by \n. */
+			    if (LEN(body_line_buf) == var_line_limit) {
+				edit_resp = parent->repl_body(parent->chg_context,
+							   MILTER_BODY_LINE,
+							      REC_TYPE_CONT,
+							      body_line_buf);
+				VSTRING_RESET(body_line_buf);
+			    }
 			    VSTRING_ADDCH(body_line_buf, ch);
 			}
 		    }
diff -Nru postfix-3.5.6/src/milter/milter.h postfix-3.5.13/src/milter/milter.h
--- postfix-3.5.6/src/milter/milter.h	2020-02-02 15:49:15.000000000 -0500
+++ postfix-3.5.13/src/milter/milter.h	2021-11-05 18:39:27.000000000 -0400
@@ -100,7 +100,7 @@
 typedef const char *(*MILTER_EDIT_FROM_FN) (void *, const char *, const char *);
 typedef const char *(*MILTER_EDIT_RCPT_FN) (void *, const char *);
 typedef const char *(*MILTER_EDIT_RCPT_PAR_FN) (void *, const char *, const char *);
-typedef const char *(*MILTER_EDIT_BODY_FN) (void *, int, VSTRING *);
+typedef const char *(*MILTER_EDIT_BODY_FN) (void *, int, int, VSTRING *);
 
 typedef struct MILTERS {
     MILTER *milter_list;		/* linked list of Milters */
diff -Nru postfix-3.5.6/src/postconf/postconf_builtin.c postfix-3.5.13/src/postconf/postconf_builtin.c
--- postfix-3.5.6/src/postconf/postconf_builtin.c	2018-01-14 20:30:12.000000000 -0500
+++ postfix-3.5.13/src/postconf/postconf_builtin.c	2021-09-25 19:01:43.000000000 -0400
@@ -244,6 +244,7 @@
 static const char *pcf_mynetworks(void)
 {
     static const char *networks;
+    VSTRING *exp_buf;
     const char *junk;
 
     /*
@@ -252,10 +253,12 @@
     if (networks)
 	return (networks);
 
+    exp_buf = vstring_alloc(100);
+
     if (var_inet_interfaces == 0) {
 	if ((pcf_cmd_mode & PCF_SHOW_DEFS)
 	    || (junk = mail_conf_lookup_eval(VAR_INET_INTERFACES)) == 0)
-	    junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode,
+	    junk = pcf_expand_parameter_value(exp_buf, pcf_cmd_mode,
 					      DEF_INET_INTERFACES,
 					      (PCF_MASTER_ENT *) 0);
 	var_inet_interfaces = mystrdup(junk);
@@ -263,7 +266,7 @@
     if (var_mynetworks_style == 0) {
 	if ((pcf_cmd_mode & PCF_SHOW_DEFS)
 	    || (junk = mail_conf_lookup_eval(VAR_MYNETWORKS_STYLE)) == 0)
-	    junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode,
+	    junk = pcf_expand_parameter_value(exp_buf, pcf_cmd_mode,
 					      DEF_MYNETWORKS_STYLE,
 					      (PCF_MASTER_ENT *) 0);
 	var_mynetworks_style = mystrdup(junk);
@@ -271,12 +274,13 @@
     if (var_inet_protocols == 0) {
 	if ((pcf_cmd_mode & PCF_SHOW_DEFS)
 	    || (junk = mail_conf_lookup_eval(VAR_INET_PROTOCOLS)) == 0)
-	    junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode,
+	    junk = pcf_expand_parameter_value(exp_buf, pcf_cmd_mode,
 					      DEF_INET_PROTOCOLS,
 					      (PCF_MASTER_ENT *) 0);
 	var_inet_protocols = mystrdup(junk);
 	(void) inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols);
     }
+    vstring_free(exp_buf);
     return (networks = mystrdup(mynetworks()));
 }
 
diff -Nru postfix-3.5.6/src/postscreen/postscreen_dnsbl.c postfix-3.5.13/src/postscreen/postscreen_dnsbl.c
--- postfix-3.5.6/src/postscreen/postscreen_dnsbl.c	2017-02-18 20:58:20.000000000 -0500
+++ postfix-3.5.13/src/postscreen/postscreen_dnsbl.c	2020-11-04 16:16:47.000000000 -0500
@@ -231,6 +231,7 @@
     int     weight;
     HTABLE_INFO *ht;
     char   *parse_err;
+    const char  *safe_dnsbl;
 
     /*
      * Parse the required DNSBL domain name, the optional reply filter and
@@ -271,8 +272,9 @@
 	ht = htable_enter(dnsbl_site_cache, saved_site, (void *) head);
 	/* Translate the DNSBL name into a safe name if available. */
 	if (psc_dnsbl_reply == 0
-	 || (head->safe_dnsbl = dict_get(psc_dnsbl_reply, saved_site)) == 0)
-	    head->safe_dnsbl = ht->key;
+	    || (safe_dnsbl = dict_get(psc_dnsbl_reply, saved_site)) == 0)
+	    safe_dnsbl = ht->key;
+	head->safe_dnsbl = mystrdup(safe_dnsbl);
 	if (psc_dnsbl_reply && psc_dnsbl_reply->error)
 	    msg_fatal("%s:%s lookup error", psc_dnsbl_reply->type,
 		      psc_dnsbl_reply->name);
diff -Nru postfix-3.5.6/src/postscreen/postscreen_tests.c postfix-3.5.13/src/postscreen/postscreen_tests.c
--- postfix-3.5.6/src/postscreen/postscreen_tests.c	2017-12-27 17:29:45.000000000 -0500
+++ postfix-3.5.13/src/postscreen/postscreen_tests.c	2021-07-24 18:20:43.000000000 -0400
@@ -175,6 +175,7 @@
      * at the time that the cache entry was written.
      */
     for (sp = time_stamps; sp < time_stamps + PSC_TINDX_COUNT; sp++) {
+	errno = 0;
 	*sp = strtoul(start, &cp, 10);
 	if (*start == 0 || (*cp != '\0' && *cp != ';') || errno == ERANGE)
 	    *sp = PSC_TIME_STAMP_DISABLED;
diff -Nru postfix-3.5.6/src/posttls-finger/posttls-finger.c postfix-3.5.13/src/posttls-finger/posttls-finger.c
--- postfix-3.5.6/src/posttls-finger/posttls-finger.c	2019-02-12 08:17:45.000000000 -0500
+++ postfix-3.5.13/src/posttls-finger/posttls-finger.c	2020-08-21 19:17:03.000000000 -0400
@@ -1988,7 +1988,7 @@
 	msg_fatal("bad '-a' option value: %s", state->options.addr_pref);
 
 #ifdef USE_TLS
-    if (state->tlsproxy_mode && state->reconnect)
+    if (state->tlsproxy_mode && state->reconnect >= 0)
 	msg_fatal("The -X and -r options are mutually exclusive");
 #endif
 
diff -Nru postfix-3.5.6/src/smtp/smtp.c postfix-3.5.13/src/smtp/smtp.c
--- postfix-3.5.6/src/smtp/smtp.c	2020-03-08 10:53:22.000000000 -0400
+++ postfix-3.5.13/src/smtp/smtp.c	2021-01-16 11:30:07.000000000 -0500
@@ -330,6 +330,12 @@
 /* .IP "\fBinfo_log_address_format (external)\fR"
 /*	The email address form that will be used in non-debug logging
 /*	(info, warning, etc.).
+/* .PP
+/*	Available in Postfix 3.5.9 and later:
+/* .IP "\fBdnssec_probe (ns:.)\fR"
+/*	The DNS query type (default: "ns") and DNS query name (default:
+/*	".") that Postfix may use to determine whether DNSSEC validation
+/*	is available.
 /* MIME PROCESSING CONTROLS
 /* .ad
 /* .fi
diff -Nru postfix-3.5.6/src/smtp/smtp_proto.c postfix-3.5.13/src/smtp/smtp_proto.c
--- postfix-3.5.6/src/smtp/smtp_proto.c	2019-06-13 17:08:33.000000000 -0400
+++ postfix-3.5.13/src/smtp/smtp_proto.c	2020-11-04 16:26:11.000000000 -0500
@@ -1389,17 +1389,17 @@
 
 /* smtp_out_raw_or_mime - output buffer, raw output or MIME-aware */
 
-static int smtp_out_raw_or_mime(SMTP_STATE *state, VSTRING *buf)
+static int smtp_out_raw_or_mime(SMTP_STATE *state, int rec_type, VSTRING *buf)
 {
     SMTP_SESSION *session = state->session;
     int     mime_errs;
 
     if (session->mime_state == 0) {
-	smtp_text_out((void *) state, REC_TYPE_NORM, vstring_str(buf),
+	smtp_text_out((void *) state, rec_type, vstring_str(buf),
 		      VSTRING_LEN(buf), (off_t) 0);
     } else {
 	mime_errs =
-	    mime_state_update(session->mime_state, REC_TYPE_NORM,
+	    mime_state_update(session->mime_state, rec_type,
 			      vstring_str(buf), VSTRING_LEN(buf));
 	if (mime_errs) {
 	    smtp_mime_fail(state, mime_errs);
@@ -1423,7 +1423,7 @@
 				 vstring_str(session->scratch2),
 				 QUOTE_FLAG_DEFAULT | QUOTE_FLAG_APPEND);
     vstring_strcat(session->scratch, gt);
-    return (smtp_out_raw_or_mime(state, session->scratch));
+    return (smtp_out_raw_or_mime(state, REC_TYPE_NORM, session->scratch));
 }
 
 /* smtp_out_add_headers - output additional headers, uses session->scratch* */
@@ -2307,7 +2307,8 @@
 		while ((rec_type = rec_get(state->src, session->scratch, 0)) > 0) {
 		    if (rec_type != REC_TYPE_NORM && rec_type != REC_TYPE_CONT)
 			break;
-		    if (smtp_out_raw_or_mime(state, session->scratch) < 0)
+		    if (smtp_out_raw_or_mime(state, rec_type,
+					     session->scratch) < 0)
 			RETURN(0);
 		    prev_type = rec_type;
 		}
diff -Nru postfix-3.5.6/src/smtp/smtp_sasl_proto.c postfix-3.5.13/src/smtp/smtp_sasl_proto.c
--- postfix-3.5.6/src/smtp/smtp_sasl_proto.c	2014-12-12 14:33:27.000000000 -0500
+++ postfix-3.5.13/src/smtp/smtp_sasl_proto.c	2020-11-04 18:33:50.000000000 -0500
@@ -102,6 +102,8 @@
 	    if (VSTRING_LEN(buf) > 0)
 		VSTRING_ADDCH(buf, ' ');
 	    vstring_strcat(buf, mech);
+	} else if (smtp_sasl_mechs->error) {
+	    msg_fatal("SASL mechanism filter failed for: '%s'", mech);
 	}
     }
     myfree(save_mech);
diff -Nru postfix-3.5.6/src/smtpd/smtpd.c postfix-3.5.13/src/smtpd/smtpd.c
--- postfix-3.5.6/src/smtpd/smtpd.c	2020-03-12 11:15:34.000000000 -0400
+++ postfix-3.5.13/src/smtpd/smtpd.c	2021-07-24 18:20:43.000000000 -0400
@@ -1291,6 +1291,7 @@
 int     var_defer_code;
 int     var_smtpd_err_sleep;
 int     var_non_fqdn_code;
+char   *var_bounce_rcpt;
 char   *var_error_rcpt;
 int     var_smtpd_delay_reject;
 char   *var_rest_classes;
@@ -5458,7 +5459,8 @@
 	 * obsolete, so we don't have to provide perfect support.
 	 */
 #ifdef USE_TLS
-	if (SMTPD_STAND_ALONE(state) == 0 && var_smtpd_tls_wrappermode) {
+	if (SMTPD_STAND_ALONE(state) == 0 && var_smtpd_tls_wrappermode
+	    && state->tls_context == 0) {
 #ifdef USE_TLSPROXY
 	    /* We garbage-collect the VSTREAM in smtpd_state_reset() */
 	    state->tlsproxy =
@@ -6417,6 +6419,7 @@
 	VAR_EOD_CHECKS, DEF_EOD_CHECKS, &var_eod_checks, 0, 0,
 	VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains, 0, 0,
 	VAR_RBL_REPLY_MAPS, DEF_RBL_REPLY_MAPS, &var_rbl_reply_maps, 0, 0,
+	VAR_BOUNCE_RCPT, DEF_ERROR_RCPT, &var_bounce_rcpt, 1, 0,
 	VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
 	VAR_REST_CLASSES, DEF_REST_CLASSES, &var_rest_classes, 0, 0,
 	VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, 0, 0,
diff -Nru postfix-3.5.6/src/smtpd/smtpd_chat.c postfix-3.5.13/src/smtpd/smtpd_chat.c
--- postfix-3.5.6/src/smtpd/smtpd_chat.c	2018-08-27 17:54:59.000000000 -0400
+++ postfix-3.5.13/src/smtpd/smtpd_chat.c	2021-07-24 18:20:43.000000000 -0400
@@ -316,7 +316,8 @@
 #define INDENT	4
 
     notice = post_mail_fopen_nowait(mail_addr_double_bounce(),
-				    var_error_rcpt,
+				    (state->error_mask & MAIL_ERROR_BOUNCE) ?
+				    var_bounce_rcpt : var_error_rcpt,
 				    MAIL_SRC_MASK_NOTIFY, NULL_TRACE_FLAGS,
 				    SMTPUTF8_FLAG_NONE, NO_QUEUE_ID);
     if (notice == 0) {
diff -Nru postfix-3.5.6/src/smtpd/smtpd_check.c postfix-3.5.13/src/smtpd/smtpd_check.c
--- postfix-3.5.6/src/smtpd/smtpd_check.c	2020-05-05 18:33:34.000000000 -0400
+++ postfix-3.5.13/src/smtpd/smtpd_check.c	2021-11-06 19:44:46.000000000 -0400
@@ -4338,8 +4338,8 @@
 	    }
 	} else if (is_map_command(state, name, CHECK_CCERT_ACL, &cpp)) {
 	    status = check_ccert_access(state, *cpp, def_acl);
-#ifdef USE_SASL_AUTH
 	} else if (is_map_command(state, name, CHECK_SASL_ACL, &cpp)) {
+#ifdef USE_SASL_AUTH
 	    if (var_smtpd_sasl_enable) {
 		if (state->sasl_username && state->sasl_username[0])
 		    status = check_sasl_access(state, *cpp, def_acl);
diff -Nru postfix-3.5.6/src/tls/tls_misc.c postfix-3.5.13/src/tls/tls_misc.c
--- postfix-3.5.6/src/tls/tls_misc.c	2020-07-26 13:03:13.000000000 -0400
+++ postfix-3.5.13/src/tls/tls_misc.c	2021-08-11 15:10:00.000000000 -0400
@@ -838,7 +838,7 @@
     EVP_PKEY *pkey = 0;
 
 #ifndef OPENSSL_NO_EC
-    EC_KEY *eckey;
+    const EC_KEY *eckey;
 
 #endif
 
diff -Nru postfix-3.5.6/src/tls/tls_proxy_client_scan.c postfix-3.5.13/src/tls/tls_proxy_client_scan.c
--- postfix-3.5.6/src/tls/tls_proxy_client_scan.c	2019-02-11 08:32:27.000000000 -0500
+++ postfix-3.5.13/src/tls/tls_proxy_client_scan.c	2021-04-03 12:13:35.000000000 -0400
@@ -430,7 +430,8 @@
     if (buf)
 	vstring_free(buf);
     if (ret != 1) {
-	tls_proxy_client_certs_free(head);
+	if (head)
+	    tls_proxy_client_certs_free(head);
 	head = 0;
     }
     *(TLS_CERTS **) ptr = head;
@@ -489,7 +490,8 @@
     if (buf)
 	vstring_free(buf);
     if (ret != 1) {
-	tls_proxy_client_pkeys_free(head);
+	if (head)
+	    tls_proxy_client_pkeys_free(head);
 	head = 0;
     }
     *(TLS_PKEYS **) ptr = head;
@@ -538,7 +540,8 @@
 	ret = (ret == 3 ? 1 : -1);
     }
     if (ret != 1) {
-	tls_proxy_client_tlsa_free(head);
+	if (head)
+	    tls_proxy_client_tlsa_free(head);
 	head = 0;
     }
     *(TLS_TLSA **) ptr = head;
diff -Nru postfix-3.5.6/src/tlsproxy/tlsproxy.c postfix-3.5.13/src/tlsproxy/tlsproxy.c
--- postfix-3.5.6/src/tlsproxy/tlsproxy.c	2020-06-20 14:55:59.000000000 -0400
+++ postfix-3.5.13/src/tlsproxy/tlsproxy.c	2020-08-21 19:37:21.000000000 -0400
@@ -998,8 +998,17 @@
     state->client_start_props->fd = state->ciphertext_fd;
     /* These predicates and warning belong inside tls_client_start(). */
     if (!tls_dane_avail()			/* mandatory side effects!! */
-	&&TLS_DANE_BASED(state->client_start_props->tls_level))
-	msg_warn("%s: DANE requested, but not available",
+
+    /*
+     * Why not test for TLS_DANE_BASED()? Because the tlsproxy(8) client has
+     * already converted its DANE TLSA records into trust anchors, and
+     * therefore TLS_DANE_HASTA() will be true instead. That exercises the
+     * code path that updates the shared SSL_CTX with custom X.509
+     * verification callbacks for trust anchors.
+     */
+	&&TLS_DANE_HASTA(state->client_start_props->dane))
+	msg_warn("%s: DANE or local trust anchor based chain"
+		 " verification requested, but not available",
 		 state->client_start_props->namaddr);
     else
 	state->tls_context = tls_client_start(state->client_start_props);
@@ -1427,7 +1436,15 @@
 	}
 	state->appl_state = tlsp_client_init(state->tls_params,
 					     state->client_init_props,
-		      TLS_DANE_BASED(state->client_start_props->tls_level));
+
+	/*
+	 * Why not test for TLS_DANE_BASED()? Because the tlsproxy(8) client
+	 * has already converted its DANE TLSA records into trust anchors,
+	 * and therefore TLS_DANE_HASTA() will be true instead. That
+	 * exercises the code path that updates the shared SSL_CTX with
+	 * custom X.509 verification callbacks for trust anchors.
+	 */
+		      TLS_DANE_HASTA(state->client_start_props->dane) != 0);
 	ready = state->appl_state != 0;
 	break;
     case TLS_PROXY_FLAG_ROLE_SERVER:
diff -Nru postfix-3.5.6/src/util/dict_inline.c postfix-3.5.13/src/util/dict_inline.c
--- postfix-3.5.6/src/util/dict_inline.c	2018-11-05 19:25:30.000000000 -0500
+++ postfix-3.5.13/src/util/dict_inline.c	2021-04-03 19:46:12.000000000 -0400
@@ -113,9 +113,9 @@
     dict = dict_open3(DICT_TYPE_HT, name, open_flags, dict_flags);
     dict_type_override(dict, DICT_TYPE_INLINE);
     while ((nameval = mystrtokq(&cp, CHARS_COMMA_SP, CHARS_BRACE)) != 0) {
-	if ((nameval[0] != CHARS_BRACE[0]
-	     || (err = free_me = extpar(&nameval, CHARS_BRACE, EXTPAR_FLAG_STRIP)) == 0)
-	    && (err = split_qnameval(nameval, &vname, &value)) != 0)
+	if (nameval[0] == CHARS_BRACE[0])
+	    err = free_me = extpar(&nameval, CHARS_BRACE, EXTPAR_FLAG_STRIP);
+	if (err != 0 || (err = split_qnameval(nameval, &vname, &value)) != 0)
 	    break;
 
 	if ((dict->flags & DICT_FLAG_SRC_RHS_IS_FILE) != 0) {
diff -Nru postfix-3.5.6/src/util/dict_static.c postfix-3.5.13/src/util/dict_static.c
--- postfix-3.5.6/src/util/dict_static.c	2018-11-05 19:25:30.000000000 -0500
+++ postfix-3.5.13/src/util/dict_static.c	2020-11-04 16:37:34.000000000 -0500
@@ -73,6 +73,8 @@
 
     if (dict_static->value)
 	myfree(dict_static->value);
+    if (dict->fold_buf)
+	vstring_free(dict->fold_buf);
     dict_free(dict);
 }
 
diff -Nru postfix-3.5.6/src/util/dict_thash.c postfix-3.5.13/src/util/dict_thash.c
--- postfix-3.5.6/src/util/dict_thash.c	2017-12-27 17:29:45.000000000 -0500
+++ postfix-3.5.13/src/util/dict_thash.c	2021-06-14 16:20:18.000000000 -0400
@@ -46,6 +46,7 @@
 /* Utility library. */
 
 #include <msg.h>
+#include <mymalloc.h>
 #include <iostuff.h>
 #include <vstring.h>
 #include <stringops.h>
@@ -180,6 +181,24 @@
 			 " is this an alias file?", path, lineno);
 
 	    /*
+	     * Optionally treat the value as a filename, and replace the value
+	     * with the BASE64-encoded content of the named file.
+	     */
+	    if (dict_flags & DICT_FLAG_SRC_RHS_IS_FILE) {
+		VSTRING *base64_buf;
+		char   *err;
+
+		if ((base64_buf = dict_file_to_b64(dict, value)) == 0) {
+		    err = dict_file_get_error(dict);
+		    msg_warn("%s, line %d: %s: skipping this entry",
+			     VSTREAM_PATH(fp), lineno, err);
+		    myfree(err);
+		    continue;
+		}
+		value = vstring_str(base64_buf);
+	    }
+
+	    /*
 	     * Store the value under the key. Handle duplicates
 	     * appropriately. XXX Move this into dict_ht, but 1) that map
 	     * ignores duplicates by default and we would have to check that
diff -Nru postfix-3.5.6/src/util/mac_expand.c postfix-3.5.13/src/util/mac_expand.c
--- postfix-3.5.6/src/util/mac_expand.c	2018-01-21 13:13:34.000000000 -0500
+++ postfix-3.5.13/src/util/mac_expand.c	2021-07-24 18:20:43.000000000 -0400
@@ -226,6 +226,7 @@
     long    result;
     char   *remainder;
 
+    errno = 0;
     result = strtol(strval, &remainder, 10);
     if (*strval == 0 /* can't happen */ || *remainder != 0 || errno == ERANGE)
 	msg_fatal("mac_exp_eval: bad conversion: %s", strval);
diff -Nru postfix-3.5.6/src/util/slmdb.c postfix-3.5.13/src/util/slmdb.c
--- postfix-3.5.6/src/util/slmdb.c	2017-02-18 20:58:21.000000000 -0500
+++ postfix-3.5.13/src/util/slmdb.c	2021-06-01 17:02:52.000000000 -0400
@@ -386,12 +386,16 @@
      * - With a bulk-mode transaction we commit when the database is closed.
      */
     if (slmdb->open_flags & O_TRUNC) {
-	if ((status = mdb_drop(slmdb->txn, slmdb->dbi, 0)) != 0)
+	if ((status = mdb_drop(slmdb->txn, slmdb->dbi, 0)) != 0) {
+	    mdb_txn_abort(slmdb->txn);
+	    slmdb->txn = 0;
 	    return (status);
+	}
 	if ((slmdb->slmdb_flags & SLMDB_FLAG_BULK) == 0) {
-	    if ((status = mdb_txn_commit(slmdb->txn)) != 0)
-		return (status);
+	    status = mdb_txn_commit(slmdb->txn);
 	    slmdb->txn = 0;
+	    if (status != 0)
+		return (status);
 	}
     } else if ((slmdb->lmdb_flags & MDB_RDONLY) != 0
 	       || (slmdb->slmdb_flags & SLMDB_FLAG_BULK) == 0) {
@@ -582,11 +586,15 @@
      * Do the update.
      */
     if ((status = mdb_put(txn, slmdb->dbi, mdb_key, mdb_value, flags)) != 0) {
-	mdb_txn_abort(txn);
 	if (status != MDB_KEYEXIST) {
+	    mdb_txn_abort(txn);
 	    if ((status = slmdb_recover(slmdb, status)) == 0)
 		status = slmdb_put(slmdb, mdb_key, mdb_value, flags);
 	    SLMDB_API_RETURN(slmdb, status);
+	} else {
+	    /* Abort non-bulk transaction only. */
+	    if (slmdb->txn == 0)
+		mdb_txn_abort(txn);
 	}
     }
 

Attachment: signature.asc
Description: This is a digitally signed message part.


Reply to: