]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.8-20220407
authorWietse Venema <wietse@porcupine.org>
Thu, 7 Apr 2022 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Sat, 16 Apr 2022 20:48:06 +0000 (16:48 -0400)
21 files changed:
postfix/HISTORY
postfix/README_FILES/STANDARD_CONFIGURATION_README
postfix/WISHLIST
postfix/html/STANDARD_CONFIGURATION_README.html
postfix/html/postconf.5.html
postfix/man/man5/postconf.5
postfix/proto/STANDARD_CONFIGURATION_README.html
postfix/proto/postconf.proto
postfix/proto/stop.double-cc
postfix/proto/stop.spell-cc
postfix/src/cleanup/cleanup.h
postfix/src/cleanup/cleanup_init.c
postfix/src/cleanup/cleanup_milter.c
postfix/src/cleanup/cleanup_state.c
postfix/src/global/header_body_checks.c
postfix/src/global/header_body_checks.h
postfix/src/global/mail_version.h
postfix/src/global/maps.c
postfix/src/global/maps.h
postfix/src/smtp/smtp.c
postfix/src/util/inet_connect.c

index 4447ce573a144c30a26183fec5fb15b64837b848..c59bc05729ddaa7a1128f103a9ca2e132ebc324c 100644 (file)
@@ -26337,8 +26337,33 @@ Apologies for any names omitted.
 
 20220403
 
+       (Rolled back because there was too much collateral damage)
        Cleanup: milter_hader_checks maps are now opened before the
        cleanup server enters the chroot jail. Files: cleanup/cleanup.h,
        cleanup/cleanup_init.c, cleanup/cleanup_milter.c,
        global/header_body_checks.c, global/header_body_checks.h,
        global/maps.c, global/maps.h, smtp/smtp.c.
+
+20220404
+
+       Bugfix: in an internal client module, "host or service not
+       found" was a fatal error, causing the milter_default_action
+       setting to be ignored. It is now a non-fatal error. The
+       same client is used by many Postfix clients (smtpd_proxy,
+       dovecot auth, tcp_table, memcache, socketmap, and so on).
+       File: util/inet_connect.c.
+
+20220407
+
+       Documentation: updated the firewall/gateway example to use
+       the "relay" transport to forward inbound messages. File:
+       proto/STANDARD_CONFIGURATION_README.html
+
+       Documentation: updated smtp_fallback_relay description.
+       The text was based on an early Postfix implementation.
+       File: proto/postconf.proto.
+
+       Cleanup: milter_hader_checks maps are now opened before the
+       cleanup server enters the chroot jail. Files: cleanup/cleanup.h,
+       cleanup/cleanup_init.c, cleanup/cleanup_milter.c,
+       cleanup/cleanup_state.c.
index ca188fe2b0e6699c3542fa136221f94f1c1f8589..f3cdb587bb0521e142707a88195be06331887d6a 100644 (file)
@@ -270,7 +270,7 @@ purpose of the firewall email function.
     17      . . .
     18
     19 /etc/postfix/transport:
-    20     example.com   smtp:[inside-gateway.example.com]
+    20     example.com   relay:[inside-gateway.example.com]
 
 Translation:
 
@@ -286,7 +286,12 @@ Translation:
     "@example.com x" wild-card in the relay_recipients table.
 
   * Lines 12, 19-20: Route mail for "example.com" to the inside gateway
-    machine. The [] forces Postfix to do no MX lookup.
+    machine. The [] forces Postfix to do no MX lookup. This uses the "relay"
+    delivery transport (a copy of the default "smtp" delivery transport) to
+    forward inbound mail. This can improve performance of deliveries to
+    internal domains because they will compete for SMTP clients from the
+    "relay" delivery transport, instead of competing with other SMTP deliveries
+    for SMTP clients from the default "smtp" delivery transport.
 
 Specify d\bdb\bbm\bm instead of h\bha\bas\bsh\bh if your system uses d\bdb\bbm\bm files instead of d\bdb\bb files.
 To find out what lookup tables Postfix supports, use the command "p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-m\bm".
index b60afff2676b3fd62affc3f7d59cf1e9314fe6aa..808d5e09d07a9149f9834264e28ad78db0403db6 100644 (file)
@@ -6,6 +6,17 @@ Wish list:
 
        Disable -DSNAPSHOT and -DNONPROD in makedefs.
 
+       Can tests use LD_PRELOAD to inject fake modules such
+       as fake_dns(3), fake_msg(3), fake_myaddrinfo() and so on?
+       One limitation is that functions etc. in a preloaded object
+       always take precedence.
+
+       '%l' support. ef7c661c-d86a-2366-6a73-ec8d51d75012@dev.snart.me
+
+       WARN_IF_REJECT like prefix that disables the error counter increment.
+
+       Send the Postfix version in a policy server request.
+
        postscreen_dnsbl_sites is evaluated in the reverse order, breaking
        expectations when different reply patterns have different weights.
        We need a compatibility_level feature to correct this.
index ee076f61fca93f614a4fd7244f655678163a7749..fa401cc07cdda2771e8ee3e9ef09afb0903b0038 100644 (file)
@@ -377,7 +377,7 @@ is the real purpose of the firewall email function. </p>
 17      . . .
 18 
 19 /etc/postfix/transport:
-20     example.com   <a href="smtp.8.html">smtp</a>:[inside-gateway.example.com]
+20     example.com   relay:[inside-gateway.example.com]
 </pre>
 </blockquote>
 
@@ -399,7 +399,12 @@ wild-card in the relay_recipients table. </p>
 
 <li> <p> Lines 12, 19-20: Route mail for "example.com" to the inside
 gateway machine. The <tt>[]</tt> forces Postfix to do no MX lookup.
-</p>
+This uses the "relay" delivery transport (a copy of the default
+"smtp" delivery transport) to forward inbound mail. This can improve
+performance of deliveries to internal domains because they will
+compete for SMTP clients from the "relay" delivery transport, instead
+of competing with other SMTP deliveries for SMTP clients from the
+default "smtp" delivery transport. </p>
 
 </ul>
 
index 0810dd85892573d828fa11b892bd2d6e95dcac67..837a5d38a2f01c9e3a33c3c744951001f6d41712 100644 (file)
@@ -11505,15 +11505,14 @@ Postfix 2.3 and later use <a href="postconf.5.html#smtp_tls_security_level">smtp
 <DT><b><a name="smtp_fallback_relay">smtp_fallback_relay</a>
 (default: $<a href="postconf.5.html#fallback_relay">fallback_relay</a>)</b></DT><DD>
 
-<p>
-Optional list of relay hosts for SMTP destinations that can't be
-found or that are unreachable. With Postfix 2.2 and earlier this
-parameter is called <a href="postconf.5.html#fallback_relay">fallback_relay</a>.  </p>
-
-<p>
-By default, mail is returned to the sender when a destination is
-not found, and delivery is deferred when a destination is unreachable.
-</p>
+<p> Optional list of relay destinations that will be used when an
+SMTP destination is not found, or when delivery fails due to a
+non-permanent error. With Postfix 2.2 and earlier this parameter
+is called <a href="postconf.5.html#fallback_relay">fallback_relay</a>. </p>
+
+<p> By default, <a href="postconf.5.html#smtp_fallback_relay">smtp_fallback_relay</a> is empty, mail is returned to
+the sender when a destination is not found, and delivery is deferred
+after it fails due to a non-permanent error. </p>
 
 <p> With bulk email deliveries, it can be beneficial to run the
 fallback relay MTA on the same host, so that it can reuse the sender
index 58cfe36486eb085d2d0a8593313126f10c024bc1..4ad946652bc2a7be3e24443a8a98b0c8c9387800 100644 (file)
@@ -7382,12 +7382,14 @@ send all their email to a dedicated mailhub.
 This feature is available in Postfix 2.2 and later. With
 Postfix 2.3 and later use smtp_tls_security_level instead.
 .SH smtp_fallback_relay (default: $fallback_relay)
-Optional list of relay hosts for SMTP destinations that can't be
-found or that are unreachable. With Postfix 2.2 and earlier this
-parameter is called fallback_relay.
-.PP
-By default, mail is returned to the sender when a destination is
-not found, and delivery is deferred when a destination is unreachable.
+Optional list of relay destinations that will be used when an
+SMTP destination is not found, or when delivery fails due to a
+non\-permanent error. With Postfix 2.2 and earlier this parameter
+is called fallback_relay.
+.PP
+By default, smtp_fallback_relay is empty, mail is returned to
+the sender when a destination is not found, and delivery is deferred
+after it fails due to a non\-permanent error.
 .PP
 With bulk email deliveries, it can be beneficial to run the
 fallback relay MTA on the same host, so that it can reuse the sender
index b4f4efcf5a988c97cfd3d420dd6fb217ef06cc2a..3008cfda69497e564b112b51996dd8266d26156f 100644 (file)
@@ -377,7 +377,7 @@ is the real purpose of the firewall email function. </p>
 17      . . .
 18 
 19 /etc/postfix/transport:
-20     example.com   smtp:[inside-gateway.example.com]
+20     example.com   relay:[inside-gateway.example.com]
 </pre>
 </blockquote>
 
@@ -399,7 +399,12 @@ wild-card in the relay_recipients table. </p>
 
 <li> <p> Lines 12, 19-20: Route mail for "example.com" to the inside
 gateway machine. The <tt>[]</tt> forces Postfix to do no MX lookup.
-</p>
+This uses the "relay" delivery transport (a copy of the default
+"smtp" delivery transport) to forward inbound mail. This can improve
+performance of deliveries to internal domains because they will
+compete for SMTP clients from the "relay" delivery transport, instead
+of competing with other SMTP deliveries for SMTP clients from the
+default "smtp" delivery transport. </p>
 
 </ul>
 
index 9b5a550d4e9c5a389b6b7c30c581c8810841af1c..7dfb60548e03f7229185f79ade9006b7b00241c4 100644 (file)
@@ -1482,15 +1482,14 @@ export_environment = TZ PATH=/bin:/usr/bin
 
 %PARAM smtp_fallback_relay $fallback_relay
 
-<p>
-Optional list of relay hosts for SMTP destinations that can't be
-found or that are unreachable. With Postfix 2.2 and earlier this
-parameter is called fallback_relay.  </p>
-
-<p>
-By default, mail is returned to the sender when a destination is
-not found, and delivery is deferred when a destination is unreachable.
-</p>
+<p> Optional list of relay destinations that will be used when an
+SMTP destination is not found, or when delivery fails due to a
+non-permanent error. With Postfix 2.2 and earlier this parameter
+is called fallback_relay. </p>
+
+<p> By default, smtp_fallback_relay is empty, mail is returned to
+the sender when a destination is not found, and delivery is deferred
+after it fails due to a non-permanent error. </p>
 
 <p> With bulk email deliveries, it can be beneficial to run the
 fallback relay MTA on the same host, so that it can reuse the sender
index 1e9b3de22b0c85f5897e3af47cd15e35e43da4fe..6bdd97f3a3f909c105fe356d0ccfdd0ffd3535df 100644 (file)
@@ -328,3 +328,4 @@ more  more useful and more consistent
 XXX  XXX 
  int compar DNS_RR DNS_RR 
 USE_FNV_32BIT  USE_FNV_32BIT 
+void  void cleanup_milter_receive state count 
index 9166298536a870fad19ed77c9070015d37c56d1c..10f22509a1acf153568a74ec9e7ab25582f12df3 100644 (file)
@@ -1782,3 +1782,5 @@ softwareengineering
 stackexchange
 stdint
 Noll
+deinit
+reinit
index 9c557119f02b86f9f8a6fcb64a51eb34d20ebed9..baecaadb71acfc25308cfb0fc4b763ddabd7c477 100644 (file)
@@ -117,8 +117,6 @@ typedef struct CLEANUP_STATE {
     VSTRING *milter_ext_from;          /* externalized sender */
     VSTRING *milter_ext_rcpt;          /* externalized recipient */
     VSTRING *milter_err_text;          /* milter call-back reply */
-    HBC_CHECKS *milter_hbc_checks;     /* Milter header checks */
-    VSTRING *milter_hbc_reply;         /* Milter header checks reply */
     VSTRING *milter_dsn_buf;           /* Milter DSN parsing buffer */
 
     /*
@@ -170,7 +168,6 @@ extern VSTRING *cleanup_strip_chars;
  /*
   * Milters.
   */
-extern MAPS *cleanup_milt_head_checks;
 extern MILTERS *cleanup_milters;
 
  /*
@@ -319,6 +316,7 @@ extern int cleanup_bounce(CLEANUP_STATE *);
  /*
   * cleanup_milter.c.
   */
+extern void cleanup_milter_header_checks_init(void);
 extern void cleanup_milter_receive(CLEANUP_STATE *, int);
 extern void cleanup_milter_inspect(CLEANUP_STATE *, MILTERS *);
 extern void cleanup_milter_emul_mail(CLEANUP_STATE *, MILTERS *, const char *);
index ffe40ba1625abd38ab8d27c3573c7c1133cacbb6..8c43a021205f09bc8b37713a70daaa1376fefe59 100644 (file)
@@ -278,7 +278,6 @@ int     cleanup_ext_prop_mask;
  /*
   * Milter support.
   */
-MAPS   *cleanup_milt_head_checks;
 MILTERS *cleanup_milters;
 
  /*
@@ -412,10 +411,6 @@ void    cleanup_pre_jail(char *unused_name, char **unused_argv)
            maps_create(VAR_RCPT_BCC_MAPS, var_rcpt_bcc_maps,
                        DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX
                        | DICT_FLAG_UTF8_REQUEST);
-    if (*var_milt_head_checks)
-       cleanup_milt_head_checks =
-           maps_create(VAR_MILT_HEAD_CHECKS, var_milt_head_checks,
-                       DICT_FLAG_LOCK);
     if (*var_cleanup_milters)
        cleanup_milters = milter_create(var_cleanup_milters,
                                        var_milt_conn_time,
@@ -432,6 +427,8 @@ void    cleanup_pre_jail(char *unused_name, char **unused_argv)
                                        var_milt_eod_macros,
                                        var_milt_unk_macros,
                                        var_milt_macro_deflts);
+    if (*var_milt_head_checks)
+       cleanup_milter_header_checks_init();
 
     flush_init();
 }
index 6da61575cbfe0167433636ca4717a3149d61ac2f..673b59c3cca66d812b0577bbdd2bc29d899d9e9e 100644 (file)
@@ -6,6 +6,8 @@
 /* SYNOPSIS
 /*     #include <cleanup.h>
 /*
+/*     void    cleanup_milter_header_checks_init(void)
+/*
 /*     void    cleanup_milter_receive(state, count)
 /*     CLEANUP_STATE *state;
 /*     int     count;
@@ -32,6 +34,9 @@
 /*     filter (milter) applications, including in-place queue file
 /*     modification.
 /*
+/*     cleanup_milter_header_checks_init() does pre-jail
+/*     initializations.
+/*
 /*     cleanup_milter_receive() receives mail filter definitions,
 /*     typically from an smtpd(8) server process, and registers
 /*     local call-back functions for macro expansion and for queue
 
 /*#define msg_verbose  2*/
 
+static HBC_CHECKS *cleanup_milter_hbc_checks;
+static VSTRING *cleanup_milter_hbc_reply;
 static void cleanup_milter_set_error(CLEANUP_STATE *, int);
 static const char *cleanup_add_rcpt_par(void *, const char *, const char *);
 
@@ -345,9 +352,9 @@ static char *cleanup_milter_hbc_extend(void *context, const char *command,
            state->errs |= CLEANUP_STAT_CONT;
        state->flags &= ~CLEANUP_FLAG_FILTER_ALL;
        cleanup_milter_hbc_log(context, "reject", where, buf, state->reason);
-       vstring_sprintf(state->milter_hbc_reply, "%d %s",
+       vstring_sprintf(cleanup_milter_hbc_reply, "%d %s",
                        detail->smtp, state->reason);
-       STR(state->milter_hbc_reply)[0] = *state->reason;
+       STR(cleanup_milter_hbc_reply)[0] = *state->reason;
        return ((char *) buf);
     }
     if (STREQUAL(command, "FILTER", cmd_len)) {
@@ -368,7 +375,7 @@ static char *cleanup_milter_hbc_extend(void *context, const char *command,
     }
     if (STREQUAL(command, "DISCARD", cmd_len)) {
        cleanup_milter_hbc_log(context, "discard", where, buf, optional_text);
-       vstring_strcpy(state->milter_hbc_reply, "D");
+       vstring_strcpy(cleanup_milter_hbc_reply, "D");
        state->flags |= CLEANUP_FLAG_DISCARD;
        state->flags &= ~CLEANUP_FLAG_FILTER_ALL;
        return ((char *) buf);
@@ -409,7 +416,7 @@ static int cleanup_milter_header_checks(CLEANUP_STATE *state, VSTRING *buf)
      * end-of-message stage, therefore all the header operations are relative
      * to the primary message header.
      */
-    ret = hbc_header_checks((void *) state, state->milter_hbc_checks,
+    ret = hbc_header_checks((void *) state, cleanup_milter_hbc_checks,
                            MIME_HDR_PRIMARY, (HEADER_OPTS *) 0,
                            buf, (off_t) 0);
     if (ret == 0) {
@@ -504,10 +511,14 @@ static void cleanup_milter_hbc_add_meta_records(CLEANUP_STATE *state)
 
 /* cleanup_milter_header_checks_init - initialize post-Milter header checks */
 
-static void cleanup_milter_header_checks_init(CLEANUP_STATE *state)
+void    cleanup_milter_header_checks_init(void)
 {
-#define NO_NESTED_HDR_MAPS     ((MAPS *) 0)
-#define NO_MIME_HDR_MAPS       ((MAPS *) 0)
+    static const char myname[] = "cleanup_milter_header_checks_init";
+
+#define NO_NESTED_HDR_NAME     ""
+#define NO_NESTED_HDR_VALUE    ""
+#define NO_MIME_HDR_NAME       ""
+#define NO_MIME_HDR_VALUE      ""
 
     static /* XXX not const */ HBC_CALL_BACKS call_backs = {
        cleanup_milter_hbc_log,
@@ -515,12 +526,47 @@ static void cleanup_milter_header_checks_init(CLEANUP_STATE *state)
        cleanup_milter_hbc_extend,
     };
 
-    state->milter_hbc_checks =
-       hbc_header_checks_create(cleanup_milt_head_checks,
-                                NO_MIME_HDR_MAPS,
-                                NO_NESTED_HDR_MAPS,
+    if (*var_milt_head_checks == 0)
+       msg_panic("%s: %s is empty", myname, VAR_MILT_HEAD_CHECKS);
+
+    if (cleanup_milter_hbc_checks)
+       msg_panic("%s: cleanup_milter_hbc_checks is not null", myname);
+    cleanup_milter_hbc_checks =
+       hbc_header_checks_create(VAR_MILT_HEAD_CHECKS, var_milt_head_checks,
+                                NO_MIME_HDR_NAME, NO_MIME_HDR_VALUE,
+                                NO_NESTED_HDR_NAME, NO_NESTED_HDR_VALUE,
                                 &call_backs);
-    state->milter_hbc_reply = vstring_alloc(100);
+
+    if (cleanup_milter_hbc_reply)
+       msg_panic("%s: cleanup_milter_hbc_reply is not null", myname);
+    cleanup_milter_hbc_reply = vstring_alloc(100);
+}
+
+#ifdef TEST
+
+/* cleanup_milter_header_checks_deinit - undo cleanup_milter_header_checks_init */
+
+static void cleanup_milter_header_checks_deinit(void)
+{
+    static const char myname[] = "cleanup_milter_header_checks_deinit";
+
+    if (cleanup_milter_hbc_checks == 0)
+       msg_panic("%s: cleanup_milter_hbc_checks is null", myname);
+    hbc_header_checks_free(cleanup_milter_hbc_checks);
+    cleanup_milter_hbc_checks = 0;
+
+    if (cleanup_milter_hbc_reply == 0)
+       msg_panic("%s: cleanup_milter_hbc_reply is null", myname);
+    vstring_free(cleanup_milter_hbc_reply);
+    cleanup_milter_hbc_reply = 0;
+}
+
+#endif
+
+/* cleanup_milter_header_checks_reinit - re-init post-Milter header checks */
+
+static void cleanup_milter_header_checks_reinit(CLEANUP_STATE *state)
+{
     if (state->filter)
        myfree(state->filter);
     state->filter = 0;
@@ -533,12 +579,6 @@ static void cleanup_milter_header_checks_init(CLEANUP_STATE *state)
 
 static void cleanup_milter_hbc_finish(CLEANUP_STATE *state)
 {
-    if (state->milter_hbc_checks)
-       hbc_header_checks_free(state->milter_hbc_checks);
-    state->milter_hbc_checks = 0;
-    if (state->milter_hbc_reply)
-       vstring_free(state->milter_hbc_reply);
-    state->milter_hbc_reply = 0;
     if (CLEANUP_OUT_OK(state)
        && !CLEANUP_MILTER_REJECTING_OR_DISCARDING_MESSAGE(state)
        && (state->filter || state->redirect))
@@ -642,7 +682,7 @@ static const char *cleanup_add_header(void *context, const char *name,
      */
     buf = vstring_alloc(100);
     vstring_sprintf(buf, "%s:%s%s", name, space, value);
-    if (state->milter_hbc_checks) {
+    if (cleanup_milter_hbc_checks) {
        if (cleanup_milter_header_checks(state, buf) == 0
            || (state->flags & CLEANUP_FLAG_DISCARD)) {
            vstring_free(buf);
@@ -705,8 +745,8 @@ static const char *cleanup_add_header(void *context, const char *name,
      * In case of error while doing record output.
      */
     return (CLEANUP_OUT_OK(state) == 0 ? cleanup_milter_error(state, 0) :
-           state->milter_hbc_reply && LEN(state->milter_hbc_reply) ?
-           STR(state->milter_hbc_reply) : 0);
+           cleanup_milter_hbc_reply && LEN(cleanup_milter_hbc_reply) ?
+           STR(cleanup_milter_hbc_reply) : 0);
 
     /*
      * Note: state->append_hdr_pt_target never changes.
@@ -1030,7 +1070,7 @@ static const char *cleanup_patch_header(CLEANUP_STATE *state,
      * be dropped.
      */
     vstring_sprintf(buf, "%s:%s%s", new_hdr_name, hdr_space, new_hdr_value);
-    if (state->milter_hbc_checks
+    if (cleanup_milter_hbc_checks
        && cleanup_milter_header_checks(state, buf) == 0)
        CLEANUP_PATCH_HEADER_RETURN(0);
 
@@ -1099,8 +1139,8 @@ static const char *cleanup_patch_header(CLEANUP_STATE *state,
      */
     CLEANUP_PATCH_HEADER_RETURN(
               CLEANUP_OUT_OK(state) == 0 ? cleanup_milter_error(state, 0) :
-                  state->milter_hbc_reply && LEN(state->milter_hbc_reply) ?
-                               STR(state->milter_hbc_reply) : 0);
+                cleanup_milter_hbc_reply && LEN(cleanup_milter_hbc_reply) ?
+                               STR(cleanup_milter_hbc_reply) : 0);
 
     /*
      * Note: state->append_hdr_pt_target never changes.
@@ -1982,8 +2022,8 @@ static const char *cleanup_milter_apply(CLEANUP_STATE *state, const char *event,
      * Don't process our own milter_header/body checks replies. See comments
      * in cleanup_milter_hbc_extend().
      */
-    if (state->milter_hbc_reply &&
-       strcmp(resp, STR(state->milter_hbc_reply)) == 0)
+    if (cleanup_milter_hbc_reply &&
+       strcmp(resp, STR(cleanup_milter_hbc_reply)) == 0)
        return (0);
 
     /*
@@ -2148,8 +2188,8 @@ void    cleanup_milter_inspect(CLEANUP_STATE *state, MILTERS *milters)
     /*
      * Prologue: prepare for Milter header/body checks.
      */
-    if (cleanup_milt_head_checks)
-       cleanup_milter_header_checks_init(state);
+    if (*var_milt_head_checks)
+       cleanup_milter_header_checks_reinit(state);
 
     /*
      * Process mail filter replies. The reply format is verified by the mail
@@ -2162,7 +2202,7 @@ void    cleanup_milter_inspect(CLEANUP_STATE *state, MILTERS *milters)
     /*
      * Epilogue: finalize Milter header/body checks.
      */
-    if (cleanup_milt_head_checks)
+    if (*var_milt_head_checks)
        cleanup_milter_hbc_finish(state);
 
     if (msg_verbose)
@@ -2319,7 +2359,6 @@ char   *var_milt_daemon_name = "host.example.com";
 char   *var_milt_v = DEF_MILT_V;
 MILTERS *cleanup_milters = (MILTERS *) ((char *) sizeof(*cleanup_milters));
 char   *var_milt_head_checks = "";
-MAPS   *cleanup_milt_head_checks;
 
 /* Dummies to satisfy unused external references. */
 
@@ -2586,11 +2625,10 @@ int     main(int unused_argc, char **argv)
                cleanup_milter_hbc_finish(state);
                myfree(var_milt_head_checks);
                var_milt_head_checks = "";
-               maps_free(cleanup_milt_head_checks);
-               cleanup_milt_head_checks = 0;
+               cleanup_milter_header_checks_deinit();
            }
            close_queue_file(state);
-       } else if (state->milter_hbc_reply && LEN(state->milter_hbc_reply)) {
+       } else if (cleanup_milter_hbc_reply && LEN(cleanup_milter_hbc_reply)) {
            /* Postfix libmilter would skip further requests. */
            msg_info("ignoring: %s %s %s", argv->argv[0],
                     argv->argc > 1 ? argv->argv[1] : "",
@@ -2695,9 +2733,7 @@ int     main(int unused_argc, char **argv)
                msg_warn("can't change header checks");
            } else {
                var_milt_head_checks = mystrdup(argv->argv[1]);
-               cleanup_milt_head_checks = maps_create(VAR_MILT_HEAD_CHECKS,
-                                     var_milt_head_checks, DICT_FLAG_LOCK);
-               cleanup_milter_header_checks_init(state);
+               cleanup_milter_header_checks_init();
            }
        } else if (strcmp(argv->argv[0], "sender_bcc_maps") == 0) {
            if (argv->argc != 2) {
@@ -2729,10 +2765,8 @@ int     main(int unused_argc, char **argv)
            msg_info("errs = %s", cleanup_strerror(state->errs));
     }
     cleanup_state_free(state);
-    if (*var_milt_head_checks) 
+    if (*var_milt_head_checks)
        myfree(var_milt_head_checks);
-    if (cleanup_milt_head_checks)
-       maps_free(cleanup_milt_head_checks);
 
     return (0);
 }
index 7790f1b515dcb6eae72dd091b4489d1dc59d9f1d..99adf84b9863f9fd21c4a4a6a55997a8d79ea6a4 100644 (file)
@@ -107,8 +107,6 @@ CLEANUP_STATE *cleanup_state_alloc(VSTREAM *src)
     state->append_hdr_pt_target = -1;
     state->append_meta_pt_offset = -1;
     state->append_meta_pt_target = -1;
-    state->milter_hbc_checks = 0;
-    state->milter_hbc_reply = 0;
     state->rcpt_count = 0;
     state->reason = 0;
     state->smtp_reply = 0;
index 74a4f6f954e527ef581260f4566ee9417053eff8..0252dd1929ad9875218d161d1ac7dd4be019bf89 100644 (file)
 /*     } HBC_CALL_BACKS;
 /*
 /*     HBC_CHECKS *hbc_header_checks_create(
-/*                     header_checks_maps, mime_header_checks_maps,
-/*                     nested_header_checks_maps, call_backs)
-/*     MAPS    *header_checks_maps;
-/*     MAPS    *mime_header_checks_maps;
-/*     MAPS    *nested_header_checks_maps;
+/*                     header_checks_name, header_checks_value
+/*                     mime_header_checks_name, mime_header_checks_value,
+/*                     nested_header_checks_name, nested_header_checks_value,
+/*                     call_backs)
+/*     const char *header_checks_name;
+/*     const char *header_checks_value;
+/*     const char *mime_header_checks_name;
+/*     const char *mime_header_checks_value;
+/*     const char *nested_header_checks_name;
+/*     const char *nested_header_checks_value;
 /*     HBC_CALL_BACKS *call_backs;
 /*
-/*     HBC_CHECKS *hbc_body_checks_create(body_check_maps, call_backs)
-/*     MAPS    *body_check_maps;
+/*     HBC_CHECKS *hbc_body_checks_create(
+/*                     body_checks_name, body_checks_value,
+/*                     call_backs)
+/*     const char *body_checks_name;
+/*     const char *body_checks_value;
 /*     HBC_CALL_BACKS *call_backs;
 /*
 /*     char    *hbc_header_checks(context, hbc, header_class, hdr_opts, header)
 /*
 /*     hbc_header_checks_create() creates a context for header
 /*     inspection. This function is typically called once during
-/*     program initialization. The result is a null pointer when
-/*     all _maps arguments specify a null pointer; in this
+/*     program initialization.  The result is a null pointer when
+/*     all _value arguments specify zero-length strings; in this
 /*     case, hbc_header_checks() and hbc_header_checks_free() must
 /*     not be called.
 /*
-/*     Note: hbc_header_checks_create() does not take ownership
-/*     of its _maps arguments.
-/*
 /*     hbc_header_checks() inspects the specified logical header.
 /*     The result is either the original header, HBC_CHECKS_STAT_IGNORE
 /*     (meaning: discard the header), HBC_CHECKS_STAT_ERROR, or a
@@ -189,15 +194,27 @@ char    hbc_checks_error;
 const char hbc_checks_unknown;
 
  /*
-  * Header checks are stored as an array of MAPS pointers, one for each
-  * header class (MIME_HDR_PRIMARY, MIME_HDR_MULTIPART, or MIME_HDR_NESTED).
+  * Header checks are stored as an array of HBC_MAP_INFO structures, one
+  * structure for each header class (MIME_HDR_PRIMARY, MIME_HDR_MULTIPART, or
+  * MIME_HDR_NESTED).
   * 
-  * Body checks are stored as a single MAPS pointer, because we make no
-  * distinction between body segments.
+  * Body checks are stored as one single HBC_MAP_INFO structure, because we make
+  * no distinction between body segments.
   */
 #define HBC_HEADER_INDEX(class)        ((class) - MIME_HDR_FIRST)
 #define HBC_BODY_INDEX (0)
 
+#define HBC_INIT(hbc, index, name, value) do { \
+       HBC_MAP_INFO *_mp = (hbc)->map_info + (index); \
+       if (*(value) != 0) { \
+           _mp->map_class = (name); \
+           _mp->maps = maps_create((name), (value), DICT_FLAG_LOCK); \
+       } else { \
+           _mp->map_class = 0; \
+           _mp->maps = 0; \
+       } \
+    } while (0)
+
 /* How does the action routine know where we are? */
 
 #define        HBC_CTXT_HEADER "header"
@@ -278,7 +295,7 @@ static char *hbc_action(void *context, HBC_CALL_BACKS *cb,
     if (STREQUAL(cmd, "IGNORE", cmd_len))
        /* XXX Not logged for compatibility with cleanup(8). */
        return (HBC_CHECKS_STAT_IGNORE);
-
     if (STREQUAL(cmd, "DUNNO", cmd_len)                /* preferred */
        ||STREQUAL(cmd, "OK", cmd_len))         /* compatibility */
        return ((char *) line);
@@ -295,7 +312,7 @@ char   *hbc_header_checks(void *context, HBC_CHECKS *hbc, int header_class,
 {
     const char *myname = "hbc_header_checks";
     const char *action;
-    MAPS   *mp;
+    HBC_MAP_INFO *mp;
 
     if (msg_verbose)
        msg_info("%s: '%.30s'", myname, STR(header));
@@ -306,13 +323,13 @@ char   *hbc_header_checks(void *context, HBC_CHECKS *hbc, int header_class,
     if (hdr_opts && (hdr_opts->flags & HDR_OPT_MIME))
        header_class = MIME_HDR_MULTIPART;
 
-    mp = hbc->map_info[HBC_HEADER_INDEX(header_class)];
+    mp = hbc->map_info + HBC_HEADER_INDEX(header_class);
 
-    if (mp != 0 && (action = maps_find(mp, STR(header), 0)) != 0) {
+    if (mp->maps != 0 && (action = maps_find(mp->maps, STR(header), 0)) != 0) {
        return (hbc_action(context, hbc->call_backs,
-                          maps_title(mp), HBC_CTXT_HEADER, action,
+                          mp->map_class, HBC_CTXT_HEADER, action,
                           STR(header), LEN(header), offset));
-    } else if (mp && mp->error) {
+    } else if (mp->maps && mp->maps->error) {
        return (HBC_CHECKS_STAT_ERROR);
     } else {
        return (STR(header));
@@ -326,18 +343,18 @@ char   *hbc_body_checks(void *context, HBC_CHECKS *hbc, const char *line,
 {
     const char *myname = "hbc_body_checks";
     const char *action;
-    MAPS   *mp;
+    HBC_MAP_INFO *mp;
 
     if (msg_verbose)
        msg_info("%s: '%.30s'", myname, line);
 
-    mp = hbc->map_info[0];
+    mp = hbc->map_info;
 
-    if ((action = maps_find(mp, line, 0)) != 0) {
+    if ((action = maps_find(mp->maps, line, 0)) != 0) {
        return (hbc_action(context, hbc->call_backs,
-                          maps_title(mp), HBC_CTXT_BODY, action,
+                          mp->map_class, HBC_CTXT_BODY, action,
                           line, len, offset));
-    } else if (mp->error) {
+    } else if (mp->maps->error) {
        return (HBC_CHECKS_STAT_ERROR);
     } else {
        return ((char *) line);
@@ -346,9 +363,12 @@ char   *hbc_body_checks(void *context, HBC_CHECKS *hbc, const char *line,
 
 /* hbc_header_checks_create - create header checking context */
 
-HBC_CHECKS *hbc_header_checks_create(MAPS *header_checks_maps,
-                                            MAPS *mime_header_checks_maps,
-                                            MAPS *nested_header_checks_maps,
+HBC_CHECKS *hbc_header_checks_create(const char *header_checks_name,
+                                            const char *header_checks_value,
+                                       const char *mime_header_checks_name,
+                                      const char *mime_header_checks_value,
+                                     const char *nested_header_checks_name,
+                                    const char *nested_header_checks_value,
                                             HBC_CALL_BACKS *call_backs)
 {
     HBC_CHECKS *hbc;
@@ -356,26 +376,27 @@ HBC_CHECKS *hbc_header_checks_create(MAPS *header_checks_maps,
     /*
      * Optimize for the common case.
      */
-    if (header_checks_maps == 0 && mime_header_checks_maps == 0
-       && nested_header_checks_maps == 0) {
+    if (*header_checks_value == 0 && *mime_header_checks_value == 0
+       && *nested_header_checks_value == 0) {
        return (0);
     } else {
        hbc = (HBC_CHECKS *) mymalloc(sizeof(*hbc)
-               + (MIME_HDR_LAST - MIME_HDR_FIRST) * sizeof(hbc->map_info));
+                + (MIME_HDR_LAST - MIME_HDR_FIRST) * sizeof(HBC_MAP_INFO));
        hbc->call_backs = call_backs;
-       hbc->map_info[HBC_HEADER_INDEX(MIME_HDR_PRIMARY)] =
-           header_checks_maps;
-       hbc->map_info[HBC_HEADER_INDEX(MIME_HDR_MULTIPART)] =
-           mime_header_checks_maps;
-       hbc->map_info[HBC_HEADER_INDEX(MIME_HDR_NESTED)] =
-           nested_header_checks_maps;
+       HBC_INIT(hbc, HBC_HEADER_INDEX(MIME_HDR_PRIMARY),
+                header_checks_name, header_checks_value);
+       HBC_INIT(hbc, HBC_HEADER_INDEX(MIME_HDR_MULTIPART),
+                mime_header_checks_name, mime_header_checks_value);
+       HBC_INIT(hbc, HBC_HEADER_INDEX(MIME_HDR_NESTED),
+                nested_header_checks_name, nested_header_checks_value);
        return (hbc);
     }
 }
 
 /* hbc_body_checks_create - create body checking context */
 
-HBC_CHECKS *hbc_body_checks_create(MAPS *body_checks_maps,
+HBC_CHECKS *hbc_body_checks_create(const char *body_checks_name,
+                                          const char *body_checks_value,
                                           HBC_CALL_BACKS *call_backs)
 {
     HBC_CHECKS *hbc;
@@ -383,12 +404,12 @@ HBC_CHECKS *hbc_body_checks_create(MAPS *body_checks_maps,
     /*
      * Optimize for the common case.
      */
-    if (body_checks_maps == 0) {
+    if (*body_checks_value == 0) {
        return (0);
     } else {
        hbc = (HBC_CHECKS *) mymalloc(sizeof(*hbc));
        hbc->call_backs = call_backs;
-       hbc->map_info[HBC_BODY_INDEX] = body_checks_maps;
+       HBC_INIT(hbc, HBC_BODY_INDEX, body_checks_name, body_checks_value);
        return (hbc);
     }
 }
@@ -397,6 +418,11 @@ HBC_CHECKS *hbc_body_checks_create(MAPS *body_checks_maps,
 
 void    _hbc_checks_free(HBC_CHECKS *hbc, ssize_t len)
 {
+    HBC_MAP_INFO *mp;
+
+    for (mp = hbc->map_info; mp < hbc->map_info + len; mp++)
+       if (mp->maps)
+           maps_free(mp->maps);
     myfree((void *) hbc);
 }
 
@@ -577,18 +603,13 @@ int     main(int argc, char **argv)
                                  body_out, body_end,
                                  err_print,
                                  (void *) &context);
-
-#define MAPS_OR_NULL(name, value) \
-       (*(value) ? maps_create((name), (value), DICT_FLAG_LOCK) : (MAPS *) 0)
-
     context.header_checks =
-       hbc_header_checks_create(MAPS_OR_NULL("header_checks", argv[1]),
-                                MAPS_OR_NULL("mime_header_checks", argv[2]),
-                             MAPS_OR_NULL("nested_header_checks", argv[3]),
+       hbc_header_checks_create("header_checks", argv[1],
+                                "mime_header_checks", argv[2],
+                                "nested_header_checks", argv[3],
                                 call_backs);
     context.body_checks =
-       hbc_body_checks_create(MAPS_OR_NULL("body_checks", argv[4]),
-                              call_backs);
+       hbc_body_checks_create("body_checks", argv[4], call_backs);
     context.buf = vstring_alloc(100);
     context.fp = VSTREAM_OUT;
     context.queueid = "test-queueID";
index abdfcc75e302f45f9dedb584257ee24f4685b507..7a2718e0592158c3c61e537007c22e364d402162 100644 (file)
  /*
   * External interface.
   */
+typedef struct {
+    const char *map_class;             /* parameter name */
+    MAPS   *maps;                      /* map handle */
+} HBC_MAP_INFO;
+
 typedef struct {
     void    (*logger) (void *, const char *, const char *, const char *, const char *);
     void    (*prepend) (void *, int, const char *, ssize_t, off_t);
@@ -36,16 +41,19 @@ typedef struct {
 
 typedef struct {
     HBC_CALL_BACKS *call_backs;
-    MAPS   *map_info[1];               /* actually, a bunch; NOT owned */
+    HBC_MAP_INFO map_info[1];          /* actually, a bunch */
 } HBC_CHECKS;
 
 #define HBC_CHECKS_STAT_IGNORE ((char *) 0)
 #define HBC_CHECKS_STAT_ERROR  (&hbc_checks_error)
 #define HBC_CHECKS_STAT_UNKNOWN        (&hbc_checks_unknown)
 
-extern HBC_CHECKS *hbc_header_checks_create(MAPS *, MAPS *, MAPS *,
+extern HBC_CHECKS *hbc_header_checks_create(const char *, const char *,
+                                                const char *, const char *,
+                                                const char *, const char *,
                                                    HBC_CALL_BACKS *);
-extern HBC_CHECKS *hbc_body_checks_create(MAPS *, HBC_CALL_BACKS *);
+extern HBC_CHECKS *hbc_body_checks_create(const char *, const char *,
+                                                 HBC_CALL_BACKS *);
 extern char *hbc_header_checks(void *, HBC_CHECKS *, int, const HEADER_OPTS *,
                                       VSTRING *, off_t);
 extern char *hbc_body_checks(void *, HBC_CHECKS *, const char *, ssize_t, off_t);
index dc3a36f2d5a8a147be2c17a860f132a120708f98..a85e79a0c4e33966b04e1aed64667bfb2d84e723 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20220403"
+#define MAIL_RELEASE_DATE      "20220407"
 #define MAIL_VERSION_NUMBER    "3.8"
 
 #ifdef SNAPSHOT
index 599d724f290c0651b6391a04769e30cfe7e81885..7c84e9aa01a145396e430cda09ebab8f334e621a 100644 (file)
@@ -21,9 +21,6 @@
 /*     const char *key;
 /*     int     flags;
 /*
-/*     const char *maps_title(maps)
-/*     MAPS    *maps;
-/*
 /*     MAPS    *maps_free(maps)
 /*     MAPS    *maps;
 /* DESCRIPTION
@@ -51,9 +48,6 @@
 /*     the base64 lookup result. This requires that the maps are
 /*     opened with DICT_FLAG_SRC_RHS_IS_FILE.
 /*
-/*     maps_title() returns a pointer to a copy of the title
-/*     specified with maps_create().
-/*
 /*     maps_free() releases storage claimed by maps_create()
 /*     and conveniently returns a null pointer.
 /*
index bf12845f999bb06176c90b9802b72441ad791fdd..04ee6dc933e69d0368b9a7ddbece733561ec7d32 100644 (file)
@@ -28,8 +28,6 @@ typedef struct MAPS {
 extern MAPS *maps_create(const char *, const char *, int);
 extern const char *maps_find(MAPS *, const char *, int);
 extern const char *maps_file_find(MAPS *, const char *, int);
-
-#define maps_title(maps) ((const char *) ((maps)->title))
 extern MAPS *maps_free(MAPS *);
 
 /* LICENSE
index 798a53b320e28ea6892aeaab88e65e5c35cf9925..3ccbfe8c96343f4b633fe99ab9582f3a94c378cd 100644 (file)
@@ -1090,7 +1090,7 @@ int     var_smtp_sasl_auth_cache_time;
 bool    var_smtp_sasl_auth_soft_bounce;
 
 char   *var_hfrom_format;
-bool    var_smtp_bind_addr_enforce;
+bool var_smtp_bind_addr_enforce;
 
  /*
   * Global variables.
@@ -1539,16 +1539,13 @@ static void pre_init(char *unused_name, char **unused_argv)
     /*
      * Header/body checks.
      */
-#define MAPS_OR_NULL(name, value) \
-       (*(value) ? maps_create((name), (value), DICT_FLAG_LOCK) : (MAPS *) 0)
-
     smtp_header_checks = hbc_header_checks_create(
-                MAPS_OR_NULL(VAR_LMTP_SMTP(HEAD_CHKS), var_smtp_head_chks),
-                MAPS_OR_NULL(VAR_LMTP_SMTP(MIME_CHKS), var_smtp_mime_chks),
-                MAPS_OR_NULL(VAR_LMTP_SMTP(NEST_CHKS), var_smtp_nest_chks),
+                              VAR_LMTP_SMTP(HEAD_CHKS), var_smtp_head_chks,
+                              VAR_LMTP_SMTP(MIME_CHKS), var_smtp_mime_chks,
+                              VAR_LMTP_SMTP(NEST_CHKS), var_smtp_nest_chks,
                                                  smtp_hbc_callbacks);
     smtp_body_checks = hbc_body_checks_create(
-                MAPS_OR_NULL(VAR_LMTP_SMTP(BODY_CHKS), var_smtp_body_chks),
+                              VAR_LMTP_SMTP(BODY_CHKS), var_smtp_body_chks,
                                              smtp_hbc_callbacks);
 
     /*
index 591283ef2d1471f0399a9e634403ed9d70ef6b06..dded7e425a885881e4f216ced2e7009102966d0f 100644 (file)
@@ -101,9 +101,13 @@ int     inet_connect(const char *addr, int block_mode, int timeout)
     if ((parse_err = host_port(buf, &host, "localhost", &port, (char *) 0)) != 0)
        msg_fatal("%s: %s", addr, parse_err);
     if ((aierr = hostname_to_sockaddr(host, port, SOCK_STREAM, &res0)) != 0)
-       msg_fatal("host or service %s not found: %s",
-                 addr, MAI_STRERROR(aierr));
+       msg_warn("host or service %s not found: %s",
+                addr, MAI_STRERROR(aierr));
     myfree(buf);
+    if (aierr) {
+       errno = EADDRNOTAVAIL;                  /* for up-stream "%m" */
+       return (-1);
+    }
 
     proto_info = inet_proto_info();
     for (sock = -1, found = 0, res = res0; res != 0; res = res->ai_next) {