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.
" $" VAR_SMTPD_EHLO_DIS_MAPS \
" $" VAR_SMTPD_MILTER_MAPS \
" $" VAR_VIRT_GID_MAPS \
- " $" VAR_VIRT_UID_MAPS
+ " $" VAR_VIRT_UID_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"
* 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.4.23"
+#define MAIL_RELEASE_DATE "20220114"
+#define MAIL_VERSION_NUMBER "3.4.24"
#ifdef SNAPSHOT
#define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
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;
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;
#include <htable.h>
#include <stringops.h>
#include <dict.h>
+#include <dict_pipe.h>
+#include <dict_union.h>
/* Global library. */
#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,
return (dict_open(map, open_flags, dict_flags));
}
-/* post_jail_init - initialization after privilege drop */
+/* authorize_proxied_maps - recursively authorize maps */
-static void post_jail_init(char *service_name, char **unused_argv)
+static void authorize_proxied_maps(char *bp)
{
const char *sep = CHARS_COMMA_SP;
const char *parens = CHARS_BRACE;
- char *saved_filter;
- char *bp;
char *type_name;
+ while ((type_name = mystrtokq(&bp, sep, parens)) != 0) {
+ char *nested_info;
+
+ /* 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_writer == 0 ? VAR_PROXY_READ_MAPS :
+ VAR_PROXY_WRITE_MAPS, 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);
+ }
+}
+
+/* post_jail_init - initialization after privilege drop */
+
+static void post_jail_init(char *service_name, char **unused_argv)
+{
+ char *saved_filter;
+
/*
* Are we proxy writer?
*/
/*
* 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) {
- 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);
- }
+ authorize_proxied_maps(saved_filter);
myfree(saved_filter);
/*
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;
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;
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,