2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-31 14:17:41 +00:00

postfix-3.8-20230406

This commit is contained in:
Wietse Venema
2023-04-06 00:00:00 -05:00
committed by Viktor Dukhovni
parent 7b4ef3b6e1
commit 8c9a1f419c
13 changed files with 250 additions and 45 deletions

View File

@@ -26990,11 +26990,13 @@ Apologies for any names omitted.
20230330
Safety: the long form { name = value } in import_environment
or export_environment is not documented, but accepted, and
it was stored in the process environment as the invalid
form "name = value" instead of the expected "name=value".
Found during code maintenance. Also refined an "empty name"
check. Files: clean_env.c, split_nameval.c.
or export_environment is not documented, but it is accepted,
and it was stored in the process environment as the invalid
form "name = value, thus not setting or overriding an entry
for "name". This form is now stored as the expected
"name=value". Found during code maintenance. Also refined
the "missing attribute name" detection. Files: clean_env.c,
split_nameval.c.
20230402
@@ -27014,3 +27016,23 @@ Apologies for any names omitted.
example, inline maps. Added Valgrind support to the namadr_list
unit test. Files: util/match_list.c, global/namadr_list.in,
util/Makefile.in.
20240406
Bugfix (introduced: 20230402): after a change in the DNS_RR
structure, the dns_rr_copy() function had not been updated,
causing the Postfix SMTP client to panic as it detected a
double-free() attempt. Reported by Florian Piekert. File:
dns/dns_rr.c.
Usability: Postfix does not support #comments after other
text, but people add them anyway, with unexpected results.
The postconf command now warns for trailing comments in
main.cf files. Similar warnings are planned for database
client configuration files. Files: util/mystrtok.c,
util/mystrtok.ref, util/match_list.c, global/namadr_list.ref,
postconf/postconf_dbms.c, postconf/test71.ref.
TODO: #comment after text in DB client configuration files.
TOIDO: test for dns_rr_copy() + dns_rr_free().

View File

@@ -1800,3 +1800,4 @@ Stringify
bitcount
bytecount
ipproto
cw

View File

@@ -160,6 +160,9 @@ DNS_RR *dns_rr_create(const char *qname, const char *rname,
{
DNS_RR *rr;
/*
* Note: if this function is changed, update dns_rr_copy().
*/
rr = (DNS_RR *) mymalloc(sizeof(*rr));
rr->qname = mystrdup(qname);
rr->rname = mystrdup(rname);
@@ -200,16 +203,17 @@ void dns_rr_free(DNS_RR *rr)
DNS_RR *dns_rr_copy(DNS_RR *src)
{
ssize_t len = sizeof(*src) + src->data_len - 1;
DNS_RR *dst;
/*
* Combine struct assignment and data copy in one block copy operation.
* Note: struct copy, because dns_rr_create() would not copy all fields.
*/
dst = (DNS_RR *) mymalloc(len);
memcpy((void *) dst, (void *) src, len);
dst = (DNS_RR *) mymalloc(sizeof(*dst));
memcpy((void *) dst, (void *) src, sizeof(*dst));
dst->qname = mystrdup(src->qname);
dst->rname = mystrdup(src->rname);
if (dst->data)
dst->data = mymemdup(dst->data, dst->data_len);
dst->next = 0;
return (dst);
}

View File

@@ -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 "20230402"
#define MAIL_RELEASE_DATE "20230406"
#define MAIL_VERSION_NUMBER "3.8"
#ifdef SNAPSHOT

View File

@@ -51,9 +51,9 @@ bar/168.100.3.3: ERROR
./namadr_list: warning: non-existent:/tmp/nosuchfile is unavailable. open file /tmp/nosuchfile: No such file or directory
./namadr_list: warning: command line: non-existent:/tmp/nosuchfile: table lookup problem
bar/168.100.3.3: ERROR
./namadr_list: warning: command line: comment at end of line is not supported: #text
./namadr_list: warning: command line: #comment after other text is not allowed: #text ...
foo/1.2.3.4: YES
./namadr_list: warning: command line: comment at end of line is not supported: #text
./namadr_list: warning: command line: #comment after other text is not allowed: #text ...
fool/1.2.3.4: NO
foo/1.2.3.4: YES
bar/1.2.3.4: YES

View File

@@ -55,7 +55,7 @@ tests: test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 \
test31 test32 test33 test34 test35 test36 test37 test39 test40 test41 \
test42 test43 test44 test45 test46 test47 test48 test49 test50 test51 \
test52 test53 test54 test55 test56 test57 test58 test59 test60 test61 \
test62 test63 test64 test65 test66 test67 test68 test69 test70
test62 test63 test64 test65 test66 test67 test68 test69 test70 test71
root_tests:
@@ -964,7 +964,24 @@ test70: $(PROG) test70.ref
touch -t 197101010000 main.cf
$(HTABLE_FIX) $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -nc . >test70.tmp 2>&1
diff test70.ref test70.tmp
rm -f main.cf master.cf test70.tmp test70.cf
rm -f main.cf master.cf test70.tmp
test71: $(PROG) test71.ref
rm -f main.cf master.cf
touch main.cf master.cf
echo "smtpd_client_restrictions = inline:{" >>main.cf
echo " { aaa0 = #aaa1 } #aaa2" >>main.cf
echo " }" >>main.cf
echo "smtpd_helo_restrictions = pcre:{" >>main.cf
echo " { /bbb0 #bbb1/ } #bbb2" >>main.cf
echo " }" >>main.cf
echo "smtpd_sender_restrictions = regexp:{" >>main.cf
echo " { /ccc0 #ccc1/ } #ccc2" >>main.cf
echo " }" >>main.cf
touch -t 197101010000 main.cf
$(HTABLE_FIX) $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -nc . >test71.tmp 2>&1
diff test71.ref test71.tmp
rm -f main.cf master.cf test71.tmp
printfck: $(OBJS) $(PROG)
rm -rf printfck
@@ -1072,8 +1089,10 @@ postconf_dbms.o: ../../include/dict_ht.h
postconf_dbms.o: ../../include/dict_ldap.h
postconf_dbms.o: ../../include/dict_memcache.h
postconf_dbms.o: ../../include/dict_mysql.h
postconf_dbms.o: ../../include/dict_pcre.h
postconf_dbms.o: ../../include/dict_pgsql.h
postconf_dbms.o: ../../include/dict_proxy.h
postconf_dbms.o: ../../include/dict_regexp.h
postconf_dbms.o: ../../include/dict_sqlite.h
postconf_dbms.o: ../../include/htable.h
postconf_dbms.o: ../../include/mac_expand.h

View File

@@ -48,6 +48,8 @@
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*
/* Wietse Venema
/*--*/
/* System library. */
@@ -77,6 +79,8 @@
#include <dict_pgsql.h>
#include <dict_sqlite.h>
#include <dict_memcache.h>
#include <dict_regexp.h>
#include <dict_pcre.h>
/* Application-specific. */
@@ -134,18 +138,31 @@ static const char *pcf_memcache_suffixes[] = {
*/
typedef struct {
const char *db_type;
int db_class;
const char **db_suffixes;
} PCF_DBMS_INFO;
#define PCF_DBMS_CLASS_CLIENT (1) /* DB name is client config path */
#define PCF_DBMS_CLASS_REGEX (2) /* DB name contains regex patterns */
static const PCF_DBMS_INFO pcf_dbms_info[] = {
DICT_TYPE_LDAP, pcf_ldap_suffixes,
DICT_TYPE_MYSQL, pcf_mysql_suffixes,
DICT_TYPE_PGSQL, pcf_pgsql_suffixes,
DICT_TYPE_SQLITE, pcf_sqlite_suffixes,
DICT_TYPE_MEMCACHE, pcf_memcache_suffixes,
0,
{DICT_TYPE_LDAP, PCF_DBMS_CLASS_CLIENT, pcf_ldap_suffixes},
{DICT_TYPE_MYSQL, PCF_DBMS_CLASS_CLIENT, pcf_mysql_suffixes},
{DICT_TYPE_PGSQL, PCF_DBMS_CLASS_CLIENT, pcf_pgsql_suffixes},
{DICT_TYPE_SQLITE, PCF_DBMS_CLASS_CLIENT, pcf_sqlite_suffixes},
{DICT_TYPE_MEMCACHE, PCF_DBMS_CLASS_CLIENT, pcf_memcache_suffixes},
{DICT_TYPE_REGEXP, PCF_DBMS_CLASS_REGEX},
{DICT_TYPE_PCRE, PCF_DBMS_CLASS_REGEX},
{0},
};
/*
* Workaround to prevent a false warning about "#comment after other text",
* when an inline pcre or regexp pattern contains "#text".
*/
#define PCF_DBMS_RECURSE 1 /* Parse inline {map-entry} */
#define PCF_DBMS_NO_RECURSE 0 /* Don't parse inline {map-entry} */
/* pcf_check_dbms_client - look for unused names in client configuration */
static void pcf_check_dbms_client(const PCF_DBMS_INFO *dp, const char *cf_file)
@@ -216,7 +233,8 @@ static void pcf_check_dbms_client(const PCF_DBMS_INFO *dp, const char *cf_file)
static void pcf_register_dbms_helper(char *str_value,
const char *(flag_parameter) (const char *, int, PCF_MASTER_ENT *),
PCF_MASTER_ENT *local_scope)
PCF_MASTER_ENT *local_scope,
int recurse)
{
const PCF_DBMS_INFO *dp;
char *db_type;
@@ -229,7 +247,8 @@ static void pcf_register_dbms_helper(char *str_value,
* Naive parsing. We don't really know if this substring specifies a
* database or some other text.
*/
while ((db_type = mystrtokq(&str_value, CHARS_COMMA_SP, CHARS_BRACE)) != 0) {
while ((db_type = mystrtokq_cw(&str_value, CHARS_COMMA_SP, CHARS_BRACE,
local_scope ? MASTER_CONF_FILE : MAIN_CONF_FILE)) != 0) {
if (*db_type == CHARS_BRACE[0]) {
if ((err = extpar(&db_type, CHARS_BRACE, EXTPAR_FLAG_NONE)) != 0) {
/* XXX Encapsulate this in pcf_warn() function. */
@@ -240,7 +259,9 @@ static void pcf_register_dbms_helper(char *str_value,
msg_warn("%s: %s", MAIN_CONF_FILE, err);
myfree(err);
}
pcf_register_dbms_helper(db_type, flag_parameter, local_scope);
if (recurse)
pcf_register_dbms_helper(db_type, flag_parameter, local_scope,
recurse);
continue;
}
@@ -267,7 +288,8 @@ static void pcf_register_dbms_helper(char *str_value,
if (*prefix == '/') {
for (dp = pcf_dbms_info; dp->db_type != 0; dp++) {
if (strcmp(db_type, dp->db_type) == 0) {
pcf_check_dbms_client(dp, prefix);
if (dp->db_class == PCF_DBMS_CLASS_CLIENT)
pcf_check_dbms_client(dp, prefix);
break;
}
}
@@ -282,6 +304,8 @@ static void pcf_register_dbms_helper(char *str_value,
* local or global namespace.
*/
if (*prefix != '.') {
int next_recurse = recurse;
if (*prefix == CHARS_BRACE[0]) {
if ((err = extpar(&prefix, CHARS_BRACE, EXTPAR_FLAG_NONE)) != 0) {
/* XXX Encapsulate this in pcf_warn() function. */
@@ -293,18 +317,28 @@ static void pcf_register_dbms_helper(char *str_value,
msg_warn("%s: %s", MAIN_CONF_FILE, err);
myfree(err);
}
pcf_register_dbms_helper(prefix, flag_parameter, local_scope);
for (dp = pcf_dbms_info; dp->db_type != 0; dp++) {
if (strcmp(db_type, dp->db_type) == 0) {
if (dp->db_class == PCF_DBMS_CLASS_REGEX)
next_recurse = PCF_DBMS_NO_RECURSE;
break;
}
}
pcf_register_dbms_helper(prefix, flag_parameter, local_scope,
next_recurse);
continue;
} else {
for (dp = pcf_dbms_info; dp->db_type != 0; dp++) {
if (strcmp(db_type, dp->db_type) == 0) {
for (cpp = dp->db_suffixes; *cpp; cpp++) {
vstring_sprintf(candidate ? candidate :
if (dp->db_class == PCF_DBMS_CLASS_CLIENT) {
for (cpp = dp->db_suffixes; *cpp; cpp++) {
vstring_sprintf(candidate ? candidate :
(candidate = vstring_alloc(30)),
"%s_%s", prefix, *cpp);
flag_parameter(STR(candidate),
"%s_%s", prefix, *cpp);
flag_parameter(STR(candidate),
PCF_PARAM_FLAG_DBMS | PCF_PARAM_FLAG_USER,
local_scope);
local_scope);
}
}
break;
}
@@ -332,7 +366,7 @@ void pcf_register_dbms_parameters(const char *param_value,
buffer = vstring_alloc(100);
bufp = pcf_expand_parameter_value(buffer, PCF_SHOW_EVAL, param_value,
local_scope);
pcf_register_dbms_helper(bufp, flag_parameter, local_scope);
pcf_register_dbms_helper(bufp, flag_parameter, local_scope, PCF_DBMS_RECURSE);
}
#endif

View File

@@ -0,0 +1,8 @@
./postconf: warning: main.cf: #comment after other text is not allowed: #aaa1 ...
./postconf: warning: main.cf: #comment after other text is not allowed: #aaa2 ...
./postconf: warning: main.cf: #comment after other text is not allowed: #ccc2 ...
./postconf: warning: main.cf: #comment after other text is not allowed: #bbb2 ...
config_directory = .
smtpd_client_restrictions = inline:{ { aaa0 = #aaa1 } #aaa2 }
smtpd_helo_restrictions = pcre:{ { /bbb0 #bbb1/ } #bbb2 }
smtpd_sender_restrictions = regexp:{ { /ccc0 #ccc1/ } #ccc2 }

View File

@@ -2419,6 +2419,7 @@ myrand.o: myrand.c
myrand.o: myrand.h
myrand.o: sys_defs.h
mystrtok.o: check_arg.h
mystrtok.o: msg.h
mystrtok.o: mystrtok.c
mystrtok.o: stringops.h
mystrtok.o: sys_defs.h

View File

@@ -84,6 +84,8 @@
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/*--*/
/* System library. */
@@ -145,12 +147,8 @@ static ARGV *match_list_parse(MATCH_LIST *match_list, ARGV *pat_list,
* If there is an error, implement graceful degradation by inserting a
* pseudo table whose lookups fail with a warning message.
*/
while ((start = mystrtokq(&bp, delim, CHARS_BRACE)) != 0) {
if (*start == '#') {
msg_warn("%s: comment at end of line is not supported: %s %s",
match_list->pname, start, bp);
break;
}
while ((start = mystrtokq_cw(&bp, delim, CHARS_BRACE,
match_list->pname)) != 0) {
for (match = init_match, item = start; *item == '!'; item++)
match = !match;
if (*item == 0)

View File

@@ -18,6 +18,22 @@
/* char *mystrtokdq(bufp, delimiters)
/* char **bufp;
/* const char *delimiters;
/*
/* char *mystrtok_cw(bufp, delimiters, blame)
/* char **bufp;
/* const char *delimiters;
/* const char *blame;
/*
/* char *mystrtokq_cw(bufp, delimiters, parens, blame)
/* char **bufp;
/* const char *delimiters;
/* const char *parens;
/* const char *blame;
/*
/* char *mystrtokdq_cw(bufp, delimiters, blame)
/* char **bufp;
/* const char *delimiters;
/* const char *blame;
/* DESCRIPTION
/* mystrtok() splits a buffer on the specified \fIdelimiters\fR.
/* Tokens are delimited by runs of delimiters, so this routine
@@ -38,6 +54,12 @@
/*
/* The result value is the next token, or a null pointer when the
/* end of the buffer was reached.
/*
/* mystrtok_cw(), mystrtokq_cw(), and mystrtokdq_cw, log a
/* warning and return null when the result would look like
/* comment. The \fBblame\fR argument provides context for
/* warning messages. Specify a null pointer to disable the
/* comment check.
/* LICENSE
/* .ad
/* .fi
@@ -52,20 +74,40 @@
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*
/* Wietse Venema
/*--*/
/* System library. */
#include "sys_defs.h"
#include <sys_defs.h>
#include <string.h>
/* Utility library. */
#include "stringops.h"
#include <msg.h>
#include <stringops.h>
/* mystrtok_warn - warn for #comment after other text */
static void mystrtok_warn(const char *start, const char *bufp, const char *blame)
{
msg_warn("%s: #comment after other text is not allowed: %s %.20s...",
blame, start, bufp);
}
/* mystrtok - ABI compatibility wrapper */
#undef mystrtok
char *mystrtok(char **src, const char *sep)
{
return (mystrtok_cw(src, sep, (char *) 0));
}
/* mystrtok - safe tokenizer */
char *mystrtok(char **src, const char *sep)
char *mystrtok_cw(char **src, const char *sep, const char *blame)
{
char *start = *src;
char *end;
@@ -86,12 +128,28 @@ char *mystrtok(char **src, const char *sep)
if (*end != 0)
*end++ = 0;
*src = end;
return (start);
if (blame && *start == '#') {
mystrtok_warn(start, *src, blame);
return (0);
} else {
return (start);
}
}
/* mystrtokq - safe tokenizer with quoting support */
/* mystrtokq - ABI compatibility wrapper */
#undef mystrtokq
char *mystrtokq(char **src, const char *sep, const char *parens)
{
return (mystrtokq_cw(src, sep, parens, (char *) 0));
}
/* mystrtokq_cw - safe tokenizer with quoting support */
char *mystrtokq_cw(char **src, const char *sep, const char *parens,
const char *blame)
{
char *start = *src;
static char *cp;
@@ -121,12 +179,27 @@ char *mystrtokq(char **src, const char *sep, const char *parens)
}
}
*src = cp;
return (start);
if (blame && *start == '#') {
mystrtok_warn(start, *src, blame);
return (0);
} else {
return (start);
}
}
/* mystrtokdq - safe tokenizer, double quote and backslash support */
/* mystrtokdq - ABI compatibility wrapper */
#undef mystrtokdq
char *mystrtokdq(char **src, const char *sep)
{
return (mystrtokdq_cw(src, sep, (char *) 0));
}
/* mystrtokdq_cw - safe tokenizer, double quote and backslash support */
char *mystrtokdq_cw(char **src, const char *sep, const char *blame)
{
char *cp = *src;
char *start;
@@ -157,7 +230,13 @@ char *mystrtokdq(char **src, const char *sep)
}
}
*src = cp;
return (start);
if (blame && start && *start == '#') {
mystrtok_warn(start, *src, blame);
return (0);
} else {
return (start);
}
}
#ifdef TEST
@@ -195,6 +274,12 @@ static const struct testcase testcases[] = {
{"mystrtokdq", " foo\\ bar ", {"foo\\ bar"}},
{"mystrtokdq", " foo \\\" bar", {"foo", "\\\"", "bar"}},
{"mystrtokdq", " foo \" bar baz\" ", {"foo", "\" bar baz\""}},
{"mystrtok_cw", "#after text"},
{"mystrtok_cw", "before-text #after text", {"before-text"}},
{"mystrtokq_cw", "#after text"},
{"mystrtokq_cw", "{ before text } #after text", "{ before text }"},
{"mystrtokdq_cw", "#after text"},
{"mystrtokdq_cw", "\"before text\" #after text", {"\"before text\""}},
};
int main(void)
@@ -229,6 +314,12 @@ int main(void)
actual = mystrtokq(&cp, CHARS_SPACE, CHARS_BRACE);
} else if (strcmp(tp->action, "mystrtokdq") == 0) {
actual = mystrtokdq(&cp, CHARS_SPACE);
} else if (strcmp(tp->action, "mystrtok_cw") == 0) {
actual = mystrtok_cw(&cp, CHARS_SPACE, "test");
} else if (strcmp(tp->action, "mystrtokq_cw") == 0) {
actual = mystrtokq_cw(&cp, CHARS_SPACE, CHARS_BRACE, "test");
} else if (strcmp(tp->action, "mystrtokdq_cw") == 0) {
actual = mystrtokdq_cw(&cp, CHARS_SPACE, "test");
} else {
msg_panic("invalid command: %s", tp->action);
}

View File

@@ -28,3 +28,21 @@ unknown: RUN test case 13 mystrtokdq > foo \" bar<
unknown: PASS test 13
unknown: RUN test case 14 mystrtokdq > foo " bar baz" <
unknown: PASS test 14
unknown: RUN test case 15 mystrtok_cw >#after text<
unknown: warning: test: #comment after other text is not allowed: #after text...
unknown: PASS test 15
unknown: RUN test case 16 mystrtok_cw >before-text #after text<
unknown: warning: test: #comment after other text is not allowed: #after text...
unknown: PASS test 16
unknown: RUN test case 17 mystrtokq_cw >#after text<
unknown: warning: test: #comment after other text is not allowed: #after text...
unknown: PASS test 17
unknown: RUN test case 18 mystrtokq_cw >{ before text } #after text<
unknown: warning: test: #comment after other text is not allowed: #after text...
unknown: PASS test 18
unknown: RUN test case 19 mystrtokdq_cw >#after text<
unknown: warning: test: #comment after other text is not allowed: #after text...
unknown: PASS test 19
unknown: RUN test case 20 mystrtokdq_cw >"before text" #after text<
unknown: warning: test: #comment after other text is not allowed: #after text...
unknown: PASS test 20

View File

@@ -31,8 +31,15 @@ extern char *concatenate(const char *,...);
extern char *mystrtok(char **, const char *);
extern char *mystrtokq(char **, const char *, const char *);
extern char *mystrtokdq(char **, const char *);
extern char *mystrtok_cw(char **, const char *, const char *);
extern char *mystrtokq_cw(char **, const char *, const char *, const char *);
extern char *mystrtokdq_cw(char **, const char *, const char *);
extern char *translit(char *, const char *, const char *);
#define mystrtok(cp, sp) mystrtok_cw((cp), (sp), (char *) 0)
#define mystrtokq(cp, sp, pp) mystrtokq_cw((cp), (sp), (pp), (char *) 0)
#define mystrtokdq(cp, sp) mystrtokdq_cw((cp), (sp), (char *) 0)
#define printable(string, replacement) \
printable_except((string), (replacement), (char *) 0)
@@ -102,6 +109,8 @@ extern int strncasecmp_utf8x(int, const char *, const char *, ssize_t);
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*
/* Wietse Venema
/*--*/
#endif