Prereq: "3.5.15" diff -ur --new-file /var/tmp/postfix-3.5.15/src/global/mail_version.h ./src/global/mail_version.h --- /var/tmp/postfix-3.5.15/src/global/mail_version.h 2022-02-05 18:28:33.000000000 -0500 +++ ./src/global/mail_version.h 2022-04-18 12:17:05.000000000 -0400 @@ -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 "20220205" -#define MAIL_VERSION_NUMBER "3.5.15" +#define MAIL_RELEASE_DATE "20220418" +#define MAIL_VERSION_NUMBER "3.5.16" #ifdef SNAPSHOT #define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE diff -ur --new-file /var/tmp/postfix-3.5.15/HISTORY ./HISTORY --- /var/tmp/postfix-3.5.15/HISTORY 2022-02-04 15:58:42.000000000 -0500 +++ ./HISTORY 2022-04-18 11:38:45.000000000 -0400 @@ -25096,3 +25096,38 @@ Bitrot: Berkeley DB 18 is like Berkeley DB 6. Yasuhiro Kimura. File: util/dict_db.c. + +20220322 + + Cleanup: added missing _checks, _reply_footer, _reply_filter, + _command_filter, and _delivery_status_filter parameter names + to the proxy_read_maps default value. Files: global/mail_params.h, + mantools/missing-proxy-read-maps. + +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). + Problem reported by Christian Degenkolb. File: util/inet_connect.c. + +20220415 + + Cleanup (problem introduced: Postfix 3.0): with dynamic map + loading enabled, an attempt to create a map with "postmap + regexp:path" would result in a bogus error message "Is the + postfix-regexp package installed?" instead of "unsupported + map type for this operation". This happened with all built-in + map types (static, cidr, etc.) that have no 'bulk create' + support. Problem reported by Greg Klanderman. File: + global/dynamicmaps.c. + +20220417 + + Cleanup (problem introduced: Postfix 2.7): milter_header_checks + maps are now opened before the cleanup server enters the + chroot jail. Problem reported by Jesper Dybdal. Files: + cleanup/cleanup.h, cleanup/cleanup_init.c, + cleanup/cleanup_milter.c, cleanup/cleanup_state.c. diff -ur --new-file /var/tmp/postfix-3.5.15/src/cleanup/cleanup.h ./src/cleanup/cleanup.h --- /var/tmp/postfix-3.5.15/src/cleanup/cleanup.h 2018-01-06 19:29:46.000000000 -0500 +++ ./src/cleanup/cleanup.h 2022-04-17 18:10:42.000000000 -0400 @@ -117,8 +117,6 @@ 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 */ /* @@ -318,6 +316,7 @@ /* * 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 -ur --new-file /var/tmp/postfix-3.5.15/src/cleanup/cleanup_init.c ./src/cleanup/cleanup_init.c --- /var/tmp/postfix-3.5.15/src/cleanup/cleanup_init.c 2019-10-13 11:32:18.000000000 -0400 +++ ./src/cleanup/cleanup_init.c 2022-04-17 18:10:42.000000000 -0400 @@ -426,6 +426,8 @@ 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 -ur --new-file /var/tmp/postfix-3.5.15/src/cleanup/cleanup_milter.c ./src/cleanup/cleanup_milter.c --- /var/tmp/postfix-3.5.15/src/cleanup/cleanup_milter.c 2021-11-05 18:39:27.000000000 -0400 +++ ./src/cleanup/cleanup_milter.c 2022-04-17 18:32:23.000000000 -0400 @@ -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 @@ 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 @@ } 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 @@ * 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,8 +511,10 @@ /* 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) { + static const char myname[] = "cleanup_milter_header_checks_init"; + #define NO_NESTED_HDR_NAME "" #define NO_NESTED_HDR_VALUE "" #define NO_MIME_HDR_NAME "" @@ -517,30 +526,60 @@ cleanup_milter_hbc_extend, }; - state->milter_hbc_checks = + 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"); + 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"); + 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; if (state->redirect) myfree(state->redirect); state->redirect = 0; + VSTRING_RESET(cleanup_milter_hbc_reply); } /* cleanup_milter_hbc_finish - finalize post-Milter header checks */ 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)) @@ -644,7 +683,7 @@ */ 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); @@ -707,8 +746,8 @@ * 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. @@ -1032,7 +1071,7 @@ * 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); @@ -1101,8 +1140,8 @@ */ 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 +2021,8 @@ * 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); /* @@ -2149,7 +2188,7 @@ * Prologue: prepare for Milter header/body checks. */ if (*var_milt_head_checks) - cleanup_milter_header_checks_init(state); + cleanup_milter_header_checks_reinit(state); /* * Process mail filter replies. The reply format is verified by the mail @@ -2563,9 +2602,10 @@ cleanup_milter_hbc_finish(state); myfree(var_milt_head_checks); var_milt_head_checks = ""; + 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] : "", @@ -2667,7 +2707,7 @@ msg_warn("can't change header checks"); } else { var_milt_head_checks = mystrdup(argv->argv[1]); - 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) { diff -ur --new-file /var/tmp/postfix-3.5.15/src/cleanup/cleanup_state.c ./src/cleanup/cleanup_state.c --- /var/tmp/postfix-3.5.15/src/cleanup/cleanup_state.c 2017-12-27 16:53:13.000000000 -0500 +++ ./src/cleanup/cleanup_state.c 2022-04-17 18:10:42.000000000 -0400 @@ -107,8 +107,6 @@ 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 -ur --new-file /var/tmp/postfix-3.5.15/src/global/dynamicmaps.c ./src/global/dynamicmaps.c --- /var/tmp/postfix-3.5.15/src/global/dynamicmaps.c 2014-12-06 20:35:32.000000000 -0500 +++ ./src/global/dynamicmaps.c 2022-04-17 16:46:55.000000000 -0400 @@ -168,11 +168,23 @@ * All errors are fatal. If the postmap(1) or postalias(1) command can't * create the requested database, then graceful degradation is not * useful. - */ - if ((dp = (DYMAP_INFO *) htable_find(dymap_info, dict_type)) == 0) + * + * Fix 20220416: if this dictionary type is registered for some non-mkmap + * purpose, then don't talk nonsense about a missing package. + */ + if ((dp = (DYMAP_INFO *) htable_find(dymap_info, dict_type)) == 0) { + ARGV *types = dict_mapnames(); + char **cpp; + + for (cpp = types->argv; *cpp; cpp++) { + if (strcmp(dict_type, *cpp) == 0) + msg_fatal("unsupported dictionary type: %s does not support " + "bulk-mode creation.", dict_type); + } msg_fatal("unsupported dictionary type: %s. " "Is the postfix-%s package installed?", dict_type, dict_type); + } if (!dp->mkmap_name) msg_fatal("unsupported dictionary type: %s does not support " "bulk-mode creation.", dict_type); diff -ur --new-file /var/tmp/postfix-3.5.15/src/global/mail_params.h ./src/global/mail_params.h --- /var/tmp/postfix-3.5.15/src/global/mail_params.h 2022-01-11 19:46:53.000000000 -0500 +++ ./src/global/mail_params.h 2022-03-22 17:30:42.000000000 -0400 @@ -2445,7 +2445,33 @@ " $" VAR_VIRT_UID_MAPS \ " $" VAR_PSC_REJ_FTR_MAPS \ " $" VAR_SMTPD_REJ_FTR_MAPS \ - " $" VAR_TLS_SERVER_SNI_MAPS + " $" VAR_TLS_SERVER_SNI_MAPS \ + " $" VAR_DSN_FILTER \ + " $" VAR_LMTP_DSN_FILTER \ + " $" VAR_LMTP_DNS_RE_FILTER \ + " $" VAR_LMTP_RESP_FILTER \ + " $" VAR_LOCAL_DSN_FILTER \ + " $" VAR_PIPE_DSN_FILTER \ + " $" VAR_PSC_CMD_FILTER \ + " $" VAR_SMTP_DSN_FILTER \ + " $" VAR_SMTP_DNS_RE_FILTER \ + " $" VAR_SMTP_RESP_FILTER \ + " $" VAR_SMTPD_CMD_FILTER \ + " $" VAR_SMTPD_DNS_RE_FILTER \ + " $" VAR_VIRT_DSN_FILTER \ + " $" VAR_BODY_CHECKS \ + " $" VAR_HEADER_CHECKS \ + " $" VAR_LMTP_BODY_CHKS \ + " $" VAR_LMTP_HEAD_CHKS \ + " $" VAR_LMTP_MIME_CHKS \ + " $" VAR_LMTP_NEST_CHKS \ + " $" VAR_MILT_HEAD_CHECKS \ + " $" VAR_MIMEHDR_CHECKS \ + " $" VAR_NESTHDR_CHECKS \ + " $" VAR_SMTP_BODY_CHKS \ + " $" VAR_SMTP_HEAD_CHKS \ + " $" VAR_SMTP_MIME_CHKS \ + " $" VAR_SMTP_NEST_CHKS extern char *var_proxy_read_maps; #define VAR_PROXY_WRITE_MAPS "proxy_write_maps" diff -ur --new-file /var/tmp/postfix-3.5.15/src/util/inet_connect.c ./src/util/inet_connect.c --- /var/tmp/postfix-3.5.15/src/util/inet_connect.c 2009-01-10 11:57:46.000000000 -0500 +++ ./src/util/inet_connect.c 2022-04-18 11:53:13.000000000 -0400 @@ -96,10 +96,13 @@ 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/service %s/%s not found: %s", - host, port, 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) {