From: Wietse Venema Date: Thu, 7 Apr 2022 05:00:00 +0000 (-0500) Subject: postfix-3.8-20220407 X-Git-Tag: v3.8.0-RC1~28 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=450f02cbae463982e1fab2c7ac7a5e0b405a652f;p=thirdparty%2Fpostfix.git postfix-3.8-20220407 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 4447ce573..c59bc0572 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -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. diff --git a/postfix/README_FILES/STANDARD_CONFIGURATION_README b/postfix/README_FILES/STANDARD_CONFIGURATION_README index ca188fe2b..f3cdb587b 100644 --- a/postfix/README_FILES/STANDARD_CONFIGURATION_README +++ b/postfix/README_FILES/STANDARD_CONFIGURATION_README @@ -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 ddbbmm instead of hhaasshh if your system uses ddbbmm files instead of ddbb files. To find out what lookup tables Postfix supports, use the command "ppoossttccoonnff --mm". diff --git a/postfix/WISHLIST b/postfix/WISHLIST index b60afff26..808d5e09d 100644 --- a/postfix/WISHLIST +++ b/postfix/WISHLIST @@ -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. diff --git a/postfix/html/STANDARD_CONFIGURATION_README.html b/postfix/html/STANDARD_CONFIGURATION_README.html index ee076f61f..fa401cc07 100644 --- a/postfix/html/STANDARD_CONFIGURATION_README.html +++ b/postfix/html/STANDARD_CONFIGURATION_README.html @@ -377,7 +377,7 @@ is the real 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] @@ -399,7 +399,12 @@ 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. -

    +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.

    diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index 0810dd858..837a5d38a 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -11505,15 +11505,14 @@ Postfix 2.3 and later use smtp
    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.

    - -

    -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.

    + +

    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.

    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 diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index 58cfe3648..4ad946652 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -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 diff --git a/postfix/proto/STANDARD_CONFIGURATION_README.html b/postfix/proto/STANDARD_CONFIGURATION_README.html index b4f4efcf5..3008cfda6 100644 --- a/postfix/proto/STANDARD_CONFIGURATION_README.html +++ b/postfix/proto/STANDARD_CONFIGURATION_README.html @@ -377,7 +377,7 @@ is the real 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] @@ -399,7 +399,12 @@ 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. -

    +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.

    diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index 9b5a550d4..7dfb60548 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -1482,15 +1482,14 @@ export_environment = TZ PATH=/bin:/usr/bin %PARAM smtp_fallback_relay $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.

    - -

    -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.

    + +

    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.

    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 diff --git a/postfix/proto/stop.double-cc b/postfix/proto/stop.double-cc index 1e9b3de22..6bdd97f3a 100644 --- a/postfix/proto/stop.double-cc +++ b/postfix/proto/stop.double-cc @@ -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 diff --git a/postfix/proto/stop.spell-cc b/postfix/proto/stop.spell-cc index 916629853..10f22509a 100644 --- a/postfix/proto/stop.spell-cc +++ b/postfix/proto/stop.spell-cc @@ -1782,3 +1782,5 @@ softwareengineering stackexchange stdint Noll +deinit +reinit diff --git a/postfix/src/cleanup/cleanup.h b/postfix/src/cleanup/cleanup.h index 9c557119f..baecaadb7 100644 --- a/postfix/src/cleanup/cleanup.h +++ b/postfix/src/cleanup/cleanup.h @@ -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 *); diff --git a/postfix/src/cleanup/cleanup_init.c b/postfix/src/cleanup/cleanup_init.c index ffe40ba16..8c43a0212 100644 --- a/postfix/src/cleanup/cleanup_init.c +++ b/postfix/src/cleanup/cleanup_init.c @@ -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(); } diff --git a/postfix/src/cleanup/cleanup_milter.c b/postfix/src/cleanup/cleanup_milter.c index 6da61575c..673b59c3c 100644 --- a/postfix/src/cleanup/cleanup_milter.c +++ b/postfix/src/cleanup/cleanup_milter.c @@ -6,6 +6,8 @@ /* SYNOPSIS /* #include /* +/* 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 @@ -222,6 +227,8 @@ /*#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); } diff --git a/postfix/src/cleanup/cleanup_state.c b/postfix/src/cleanup/cleanup_state.c index 7790f1b51..99adf84b9 100644 --- a/postfix/src/cleanup/cleanup_state.c +++ b/postfix/src/cleanup/cleanup_state.c @@ -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; diff --git a/postfix/src/global/header_body_checks.c b/postfix/src/global/header_body_checks.c index 74a4f6f95..0252dd192 100644 --- a/postfix/src/global/header_body_checks.c +++ b/postfix/src/global/header_body_checks.c @@ -19,15 +19,23 @@ /* } 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) @@ -63,14 +71,11 @@ /* /* 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"; diff --git a/postfix/src/global/header_body_checks.h b/postfix/src/global/header_body_checks.h index abdfcc75e..7a2718e05 100644 --- a/postfix/src/global/header_body_checks.h +++ b/postfix/src/global/header_body_checks.h @@ -28,6 +28,11 @@ /* * 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); diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index dc3a36f2d..a85e79a0c 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 diff --git a/postfix/src/global/maps.c b/postfix/src/global/maps.c index 599d724f2..7c84e9aa0 100644 --- a/postfix/src/global/maps.c +++ b/postfix/src/global/maps.c @@ -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. /* diff --git a/postfix/src/global/maps.h b/postfix/src/global/maps.h index bf12845f9..04ee6dc93 100644 --- a/postfix/src/global/maps.h +++ b/postfix/src/global/maps.h @@ -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 diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c index 798a53b32..3ccbfe8c9 100644 --- a/postfix/src/smtp/smtp.c +++ b/postfix/src/smtp/smtp.c @@ -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); /* diff --git a/postfix/src/util/inet_connect.c b/postfix/src/util/inet_connect.c index 591283ef2..dded7e425 100644 --- a/postfix/src/util/inet_connect.c +++ b/postfix/src/util/inet_connect.c @@ -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) {