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.
/* SYNOPSIS
/* #include <cleanup.h>
/*
+/* void cleanup_milter_header_checks_init(void)
+/*
/* void cleanup_milter_receive(state, count)
/* CLEANUP_STATE *state;
/* int count;
/* 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 *);
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)) {
}
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);
* 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) {
/* 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 ""
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))
*/
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);
* 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.
* 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);
*/
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.
* 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);
/*
* 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
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] : "",
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) {