diff --git a/postfix/HISTORY b/postfix/HISTORY index 538f86001..07f458c1c 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -25694,3 +25694,34 @@ Apologies for any names omitted. previously occupied by the original message body. Problem report by BenoƮt Panizzon. + +20211115 + + Bugfix (introduced: 20210708): duplicate bounce_notice_recipient + entries in postconf output. The fix to send SMTP session + transcripts to bounce_notice_recipient was incomplete. + Reported by Vincent Lefevre. File: smtpd/smtpd.c. + +20211216 + + Bugfix (introduced: Postfix 3.0): the proxymap daemon did + not automatically authorize proxied maps inside pipemap + (example: pipemap:{proxy:maptype:mapname, ...}) or inside + unionmap. Problem reported by Mirko Vogt. Files: + proxymap/proxymap.c. + +20211220 + + Bugfix (introduced: Postfix 2.5): off-by-one error while + writing a string terminator. This code had passed all memory + corruption tests, presumably because it wrote over an + alignment padding byte, or over an adjacent character byte + that was never read. Reported by Robert Siemer. Files: + *qmgr/qmgr_feedback.c. + +20211223 + + Cleanup: added missing _maps parameter names to the + proxy_read_maps default value, based on output from the + mantools/missing-proxy-read-maps script. File: + global/mail_params.h. diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index ed99874eb..d0c50eb17 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -2491,7 +2491,11 @@ extern int var_local_rcpt_code; " $" VAR_SMTPD_EHLO_DIS_MAPS \ " $" VAR_SMTPD_MILTER_MAPS \ " $" VAR_VIRT_GID_MAPS \ - " $" VAR_VIRT_UID_MAPS + " $" VAR_VIRT_UID_MAPS \ + " $" VAR_LOCAL_LOGIN_SND_MAPS \ + " $" VAR_PSC_REJ_FTR_MAPS \ + " $" VAR_SMTPD_REJ_FTR_MAPS \ + " $" VAR_TLS_SERVER_SNI_MAPS extern char *var_proxy_read_maps; #define VAR_PROXY_WRITE_MAPS "proxy_write_maps" diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 099c17c90..b995ab324 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 "20211107" -#define MAIL_VERSION_NUMBER "3.6.3" +#define MAIL_RELEASE_DATE "20220114" +#define MAIL_VERSION_NUMBER "3.6.4" #ifdef SNAPSHOT #define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE diff --git a/postfix/src/oqmgr/qmgr_feedback.c b/postfix/src/oqmgr/qmgr_feedback.c index f341b9591..bf7aebb20 100644 --- a/postfix/src/oqmgr/qmgr_feedback.c +++ b/postfix/src/oqmgr/qmgr_feedback.c @@ -109,7 +109,7 @@ void qmgr_feedback_init(QMGR_FEEDBACK *fb, double enum_val; char denom_str[30 + 1]; double denom_val; - char slash; + char slash[1 + 1]; char junk; char *fbck_name; char *fbck_val; @@ -135,7 +135,7 @@ void qmgr_feedback_init(QMGR_FEEDBACK *fb, fb->base = -1; /* assume error */ switch (sscanf(fbck_val, "%lf %1[/] %30s%c", - &enum_val, &slash, denom_str, &junk)) { + &enum_val, slash, denom_str, &junk)) { case 1: fb->index = QMGR_FEEDBACK_IDX_NONE; fb->base = enum_val; diff --git a/postfix/src/proxymap/proxymap.c b/postfix/src/proxymap/proxymap.c index b0b844678..73163905e 100644 --- a/postfix/src/proxymap/proxymap.c +++ b/postfix/src/proxymap/proxymap.c @@ -232,6 +232,8 @@ #include #include #include +#include +#include /* Global library. */ @@ -295,6 +297,27 @@ static int proxy_writer; #define STR(x) vstring_str(x) #define VSTREQ(x,y) (strcmp(STR(x),y) == 0) +/* get_nested_dict_name - return nested dictionary name pointer, or null */ + +static char *get_nested_dict_name(char *type_name) +{ + const struct { + const char *type_col; + ssize_t type_col_len; + } *prefix, prefixes[] = { + DICT_TYPE_UNION ":", (sizeof(DICT_TYPE_UNION ":") - 1), + DICT_TYPE_PIPE ":", (sizeof(DICT_TYPE_PIPE ":") - 1), + }; + +#define COUNT_OF(x) (sizeof(x)/sizeof((x)[0])) + + for (prefix = prefixes; prefix < prefixes + COUNT_OF(prefixes); prefix++) { + if (strncmp(type_name, prefix->type_col, prefix->type_col_len) == 0) + return (type_name + prefix->type_col_len); + } + return (0); +} + /* proxy_map_find - look up or open table */ static DICT *proxy_map_find(const char *map_type_name, int request_flags, @@ -660,15 +683,68 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags) return (dict_open(map, open_flags, dict_flags)); } +/* authorize_proxied_maps - recursively authorize maps */ + +static void authorize_proxied_maps(char *bp) +{ + const char *sep = CHARS_COMMA_SP; + const char *parens = CHARS_BRACE; + char *type_name; + + while ((type_name = mystrtokq(&bp, sep, parens)) != 0) { + char *nested_info; + + /* Maybe { maptype:mapname attr=value... } */ + if (*type_name == parens[0]) { + char *err; + + /* Warn about blatant syntax error. */ + if ((err = extpar(&type_name, parens, EXTPAR_FLAG_NONE)) != 0) { + msg_warn("bad %s parameter value: %s", + PROXY_MAP_PARAM_NAME(proxy_writer), err); + myfree(err); + continue; + } + /* Don't try to second-guess the semantics of { }. */ + if ((type_name = mystrtokq(&type_name, sep, parens)) == 0) + continue; + } + /* Recurse into nested map (pipemap, unionmap). */ + if ((nested_info = get_nested_dict_name(type_name)) != 0) { + char *err; + + if (*nested_info != parens[0]) + continue; + /* Warn about blatant syntax error. */ + if ((err = extpar(&nested_info, parens, EXTPAR_FLAG_NONE)) != 0) { + msg_warn("bad %s parameter value: %s", + PROXY_MAP_PARAM_NAME(proxy_writer), err); + myfree(err); + continue; + } + authorize_proxied_maps(nested_info); + continue; + } + if (strncmp(type_name, PROXY_COLON, PROXY_COLON_LEN)) + continue; + do { + type_name += PROXY_COLON_LEN; + } while (!strncmp(type_name, PROXY_COLON, PROXY_COLON_LEN)); + if (strchr(type_name, ':') != 0 + && htable_locate(proxy_auth_maps, type_name) == 0) { + (void) htable_enter(proxy_auth_maps, type_name, (void *) 0); + if (msg_verbose) + msg_info("allowlisting %s from %s", type_name, + PROXY_MAP_PARAM_NAME(proxy_writer)); + } + } +} + /* post_jail_init - initialization after privilege drop */ static void post_jail_init(char *service_name, char **unused_argv) { - const char *sep = CHARS_COMMA_SP; - const char *parens = CHARS_BRACE; char *saved_filter; - char *bp; - char *type_name; /* * Are we proxy writer? @@ -691,38 +767,10 @@ static void post_jail_init(char *service_name, char **unused_argv) /* * Prepare the pre-approved list of proxied tables. */ - saved_filter = bp = mystrdup(proxy_writer ? var_proxy_write_maps : - var_proxy_read_maps); + saved_filter = mystrdup(proxy_writer ? var_proxy_write_maps : + var_proxy_read_maps); proxy_auth_maps = htable_create(13); - while ((type_name = mystrtokq(&bp, sep, parens)) != 0) { - /* Maybe { maptype:mapname attr=value... } */ - if (*type_name == parens[0]) { - char *err; - - /* Warn about blatant syntax error. */ - if ((err = extpar(&type_name, parens, EXTPAR_FLAG_NONE)) != 0) { - msg_warn("bad %s parameter value: %s", - PROXY_MAP_PARAM_NAME(proxy_writer), err); - myfree(err); - continue; - } - /* Don't try to second-guess the semantics of { }. */ - if ((type_name = mystrtokq(&type_name, sep, parens)) == 0) - continue; - } - if (strncmp(type_name, PROXY_COLON, PROXY_COLON_LEN)) - continue; - do { - type_name += PROXY_COLON_LEN; - } while (!strncmp(type_name, PROXY_COLON, PROXY_COLON_LEN)); - if (strchr(type_name, ':') != 0 - && htable_locate(proxy_auth_maps, type_name) == 0) { - (void) htable_enter(proxy_auth_maps, type_name, (void *) 0); - if (msg_verbose) - msg_info("allowlisting %s from %s", type_name, - PROXY_MAP_PARAM_NAME(proxy_writer)); - } - } + authorize_proxied_maps(saved_filter); myfree(saved_filter); /* diff --git a/postfix/src/qmgr/qmgr_feedback.c b/postfix/src/qmgr/qmgr_feedback.c index f341b9591..bf7aebb20 100644 --- a/postfix/src/qmgr/qmgr_feedback.c +++ b/postfix/src/qmgr/qmgr_feedback.c @@ -109,7 +109,7 @@ void qmgr_feedback_init(QMGR_FEEDBACK *fb, double enum_val; char denom_str[30 + 1]; double denom_val; - char slash; + char slash[1 + 1]; char junk; char *fbck_name; char *fbck_val; @@ -135,7 +135,7 @@ void qmgr_feedback_init(QMGR_FEEDBACK *fb, fb->base = -1; /* assume error */ switch (sscanf(fbck_val, "%lf %1[/] %30s%c", - &enum_val, &slash, denom_str, &junk)) { + &enum_val, slash, denom_str, &junk)) { case 1: fb->index = QMGR_FEEDBACK_IDX_NONE; fb->base = enum_val; diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index fc47e012f..7e95b32fd 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -6432,7 +6432,7 @@ int main(int argc, char **argv) VAR_EOD_CHECKS, DEF_EOD_CHECKS, &var_eod_checks, 0, 0, VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains, 0, 0, VAR_RBL_REPLY_MAPS, DEF_RBL_REPLY_MAPS, &var_rbl_reply_maps, 0, 0, - VAR_BOUNCE_RCPT, DEF_ERROR_RCPT, &var_bounce_rcpt, 1, 0, + VAR_BOUNCE_RCPT, DEF_BOUNCE_RCPT, &var_bounce_rcpt, 1, 0, VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0, VAR_REST_CLASSES, DEF_REST_CLASSES, &var_rest_classes, 0, 0, VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, 0, 0,