mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-22 09:57:34 +00:00
postfix-3.9-20230502
This commit is contained in:
parent
38163b3ac4
commit
ef6c34f504
@ -27078,3 +27078,29 @@ Apologies for any names omitted.
|
|||||||
Cleanup: in the PostgreSQL client, cosmetic changes to make
|
Cleanup: in the PostgreSQL client, cosmetic changes to make
|
||||||
the code easier to maintain (in preparation for adding new
|
the code easier to maintain (in preparation for adding new
|
||||||
functionality). File: global/dict_pgsql.c.
|
functionality). File: global/dict_pgsql.c.
|
||||||
|
|
||||||
|
20230428
|
||||||
|
|
||||||
|
Bugfix (defect introduced: Postfix 1.0): the command 'postconf
|
||||||
|
.. name=v1 .. name=v2 ..' (multiple instances of the same
|
||||||
|
parameter name) created multiple name=value entries with
|
||||||
|
the same parameter name. It now logs a warning and skips
|
||||||
|
the earlier update. Found during code maintenance. File:
|
||||||
|
postconf/postconf_edit.c
|
||||||
|
|
||||||
|
Bugfix (defect introduced: Postfix 3.3): the command 'postconf
|
||||||
|
-M name1/type1='name2 type2 ..." died with a segmentation
|
||||||
|
violation when the request matched multiple master.cf
|
||||||
|
entries. The master.cf file was not damaged. Problem reported
|
||||||
|
by SATOH Fumiyasu. File: postconf/postconf_master.c.
|
||||||
|
|
||||||
|
20230502
|
||||||
|
|
||||||
|
Bugfix (defect introduced: Postfix 2.11): the command
|
||||||
|
'postconf -M name1/type1="name2 type2 ...'" could add a
|
||||||
|
service definition to master.cf that conflicted with an
|
||||||
|
already existing service definition. It now replaces all
|
||||||
|
existing service definitions that match the service pattern
|
||||||
|
'name1/type1' or the service name and type in 'name2 type2
|
||||||
|
...' with a single service definition 'name2 type2 ...'.
|
||||||
|
Problem reported by SATOH Fumiyasu. File: postconf/postconf_edit.c.
|
||||||
|
@ -56,3 +56,5 @@ Valgrind
|
|||||||
Florian
|
Florian
|
||||||
Piekert
|
Piekert
|
||||||
refactored
|
refactored
|
||||||
|
Fumiyasu
|
||||||
|
SATOH
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||||
* patchlevel; they change the release date only.
|
* patchlevel; they change the release date only.
|
||||||
*/
|
*/
|
||||||
#define MAIL_RELEASE_DATE "20230419"
|
#define MAIL_RELEASE_DATE "20230502"
|
||||||
#define MAIL_VERSION_NUMBER "3.9"
|
#define MAIL_VERSION_NUMBER "3.9"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@ -55,7 +55,8 @@ tests: test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 \
|
|||||||
test31 test32 test33 test34 test35 test36 test37 test39 test40 test41 \
|
test31 test32 test33 test34 test35 test36 test37 test39 test40 test41 \
|
||||||
test42 test43 test44 test45 test46 test47 test48 test49 test50 test51 \
|
test42 test43 test44 test45 test46 test47 test48 test49 test50 test51 \
|
||||||
test52 test53 test54 test55 test56 test57 test58 test59 test60 test61 \
|
test52 test53 test54 test55 test56 test57 test58 test59 test60 test61 \
|
||||||
test62 test63 test64 test65 test66 test67 test68 test69 test70 test71
|
test62 test63 test64 test65 test66 test67 test68 test69 test70 test71 \
|
||||||
|
test72 test73 test74 test75
|
||||||
|
|
||||||
root_tests:
|
root_tests:
|
||||||
|
|
||||||
@ -989,6 +990,54 @@ test71: $(PROG) test71.ref
|
|||||||
diff test71.ref test71.tmp
|
diff test71.ref test71.tmp
|
||||||
rm -f main.cf master.cf test71.tmp
|
rm -f main.cf master.cf test71.tmp
|
||||||
|
|
||||||
|
# Different requests to add lines to master.cf.
|
||||||
|
test72: $(PROG) test72.ref
|
||||||
|
rm -f main.cf master.cf
|
||||||
|
touch main.cf master.cf
|
||||||
|
./postconf -Mc. smtp/unix='smtp unix - n n - 0 other'
|
||||||
|
./postconf -Mc. smtp/abcd='smtp fifo - n n - 0 other'
|
||||||
|
./postconf -Mc. smtp/abcd='smtp inet - n n - 0 other'
|
||||||
|
touch -t 197201010000 main.cf
|
||||||
|
$(HTABLE_FIX) $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -Mc. >test72.tmp 2>&1
|
||||||
|
diff test72.ref test72.tmp
|
||||||
|
rm -f main.cf master.cf test72.tmp
|
||||||
|
|
||||||
|
# Replace one entry based on the name+type in the request's service entry.
|
||||||
|
test73: $(PROG) test73.ref
|
||||||
|
rm -f main.cf master.cf
|
||||||
|
touch main.cf master.cf
|
||||||
|
./postconf -Mc. smtp/unix='smtp unix - n n - 0 other'
|
||||||
|
./postconf -Mc. smtp/abcd='smtp fifo - n n - 0 other'
|
||||||
|
./postconf -Mc. smtp/abcd='smtp inet - n n - 0 other'
|
||||||
|
./postconf -Mc. smtp/abcd='smtp unix - n n - 0 otherx'
|
||||||
|
touch -t 197301010000 main.cf
|
||||||
|
$(HTABLE_FIX) $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -Mc. >test73.tmp 2>&1
|
||||||
|
diff test73.ref test73.tmp
|
||||||
|
rm -f main.cf master.cf test73.tmp
|
||||||
|
|
||||||
|
# Replace one entry based on the name+type in the request's service pattern.
|
||||||
|
test74: $(PROG) test74.ref
|
||||||
|
rm -f main.cf master.cf
|
||||||
|
touch main.cf master.cf
|
||||||
|
./postconf -Mc. smtp/unix='smtp unix - n n - 0 other'
|
||||||
|
./postconf -Mc. smtp/abcd='smtp fifo - n n - 0 other'
|
||||||
|
./postconf -Mc. smtp/abcd='smtp inet - n n - 0 other'
|
||||||
|
./postconf -Mc. smtp/fifo='lmtp unix - n n - 0 otherx'
|
||||||
|
touch -t 197401010000 main.cf
|
||||||
|
$(HTABLE_FIX) $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -Mc. >test74.tmp 2>&1
|
||||||
|
diff test74.ref test74.tmp
|
||||||
|
rm -f main.cf master.cf test74.tmp
|
||||||
|
|
||||||
|
# Warn about skipping redundant name=value update.
|
||||||
|
test75: $(PROG) test75.ref
|
||||||
|
rm -f main.cf master.cf
|
||||||
|
touch main.cf master.cf
|
||||||
|
./postconf -c. mail_version=x mail_version=y >test75.tmp 2>&1
|
||||||
|
touch -t 197501010000 main.cf
|
||||||
|
$(HTABLE_FIX) $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -nc. >>test75.tmp 2>&1
|
||||||
|
diff test75.ref test75.tmp
|
||||||
|
rm -f main.cf master.cf test75.tmp
|
||||||
|
|
||||||
printfck: $(OBJS) $(PROG)
|
printfck: $(OBJS) $(PROG)
|
||||||
rm -rf printfck
|
rm -rf printfck
|
||||||
mkdir printfck
|
mkdir printfck
|
||||||
@ -1184,6 +1233,7 @@ postconf_main.o: postconf_main.c
|
|||||||
postconf_master.o: ../../include/argv.h
|
postconf_master.o: ../../include/argv.h
|
||||||
postconf_master.o: ../../include/check_arg.h
|
postconf_master.o: ../../include/check_arg.h
|
||||||
postconf_master.o: ../../include/dict.h
|
postconf_master.o: ../../include/dict.h
|
||||||
|
postconf_master.o: ../../include/dict_ht.h
|
||||||
postconf_master.o: ../../include/htable.h
|
postconf_master.o: ../../include/htable.h
|
||||||
postconf_master.o: ../../include/mail_params.h
|
postconf_master.o: ../../include/mail_params.h
|
||||||
postconf_master.o: ../../include/master_proto.h
|
postconf_master.o: ../../include/master_proto.h
|
||||||
|
@ -192,6 +192,11 @@ void pcf_edit_main(int mode, int argc, char **argv)
|
|||||||
} else {
|
} else {
|
||||||
msg_panic("pcf_edit_main: unknown mode %d", mode);
|
msg_panic("pcf_edit_main: unknown mode %d", mode);
|
||||||
}
|
}
|
||||||
|
if ((cvalue = htable_find(table, pattern)) != 0) {
|
||||||
|
msg_warn("ignoring earlier request: '%s = %s'",
|
||||||
|
pattern, cvalue->value);
|
||||||
|
htable_delete(table, pattern, myfree);
|
||||||
|
}
|
||||||
cvalue = (struct cvalue *) mymalloc(sizeof(*cvalue));
|
cvalue = (struct cvalue *) mymalloc(sizeof(*cvalue));
|
||||||
cvalue->value = edit_value;
|
cvalue->value = edit_value;
|
||||||
cvalue->found = 0;
|
cvalue->found = 0;
|
||||||
@ -456,8 +461,38 @@ void pcf_edit_master(int mode, int argc, char **argv)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Match each service pattern.
|
* Match each service pattern.
|
||||||
|
*
|
||||||
|
* Additional care is needed when a request adds or replaces an
|
||||||
|
* entire service definition, instead of a specific field or
|
||||||
|
* parameter. Given a command "postconf -M name1/type1='name2
|
||||||
|
* type2 ...'", where name1 and name2 may differ, and likewise
|
||||||
|
* for type1 and type2:
|
||||||
|
*
|
||||||
|
* - First, if an existing service definition a) matches the service
|
||||||
|
* pattern 'name1/type1', or b) matches the name and type in the
|
||||||
|
* new service definition 'name2 type2 ...', remove the service
|
||||||
|
* definition.
|
||||||
|
*
|
||||||
|
* - Then, after an a) or b) type match, add a new service
|
||||||
|
* definition for 'name2 type2 ...', but only after the first
|
||||||
|
* match.
|
||||||
|
*
|
||||||
|
* - Finally, if a request had no a) or b) type match for any
|
||||||
|
* master.cf service definition, add a new service definition for
|
||||||
|
* 'name2 type2 ...'.
|
||||||
*/
|
*/
|
||||||
for (req = edit_reqs; req < edit_reqs + num_reqs; req++) {
|
for (req = edit_reqs; req < edit_reqs + num_reqs; req++) {
|
||||||
|
PCF_MASTER_ENT *tentative_entry = 0;
|
||||||
|
int use_tentative_entry = 0;
|
||||||
|
|
||||||
|
/* Additional care for whole service definition requests. */
|
||||||
|
if ((mode & PCF_MASTER_ENTRY) && (mode & PCF_EDIT_CONF)) {
|
||||||
|
tentative_entry = (PCF_MASTER_ENT *)
|
||||||
|
mymalloc(sizeof(*tentative_entry));
|
||||||
|
if ((err = pcf_parse_master_entry(tentative_entry,
|
||||||
|
req->edit_value)) != 0)
|
||||||
|
msg_fatal("%s: \"%s\"", err, req->raw_text);
|
||||||
|
}
|
||||||
if (PCF_MATCH_SERVICE_PATTERN(req->service_pattern,
|
if (PCF_MATCH_SERVICE_PATTERN(req->service_pattern,
|
||||||
service_name,
|
service_name,
|
||||||
service_type)) {
|
service_type)) {
|
||||||
@ -503,18 +538,30 @@ void pcf_edit_master(int mode, int argc, char **argv)
|
|||||||
* Replace entire master.cf entry.
|
* Replace entire master.cf entry.
|
||||||
*/
|
*/
|
||||||
case PCF_MASTER_ENTRY:
|
case PCF_MASTER_ENTRY:
|
||||||
if (new_entry != 0)
|
if (req->match_count == 1)
|
||||||
pcf_free_master_entry(new_entry);
|
use_tentative_entry = 1;
|
||||||
new_entry = (PCF_MASTER_ENT *)
|
|
||||||
mymalloc(sizeof(*new_entry));
|
|
||||||
if ((err = pcf_parse_master_entry(new_entry,
|
|
||||||
req->edit_value)) != 0)
|
|
||||||
msg_fatal("%s: \"%s\"", err, req->raw_text);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
msg_panic("%s: unknown edit mode %d", myname, mode);
|
msg_panic("%s: unknown edit mode %d", myname, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (tentative_entry != 0
|
||||||
|
&& PCF_MATCH_SERVICE_PATTERN(tentative_entry->argv,
|
||||||
|
service_name,
|
||||||
|
service_type)) {
|
||||||
|
service_name_type_matched = 1; /* Sticky flag */
|
||||||
|
req->match_count += 1;
|
||||||
|
if (req->match_count == 1)
|
||||||
|
use_tentative_entry = 1;
|
||||||
|
}
|
||||||
|
if (tentative_entry != 0) {
|
||||||
|
if (use_tentative_entry) {
|
||||||
|
if (new_entry != 0)
|
||||||
|
pcf_free_master_entry(new_entry);
|
||||||
|
new_entry = tentative_entry;
|
||||||
|
} else {
|
||||||
|
pcf_free_master_entry(tentative_entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +156,7 @@
|
|||||||
#include <readlline.h>
|
#include <readlline.h>
|
||||||
#include <stringops.h>
|
#include <stringops.h>
|
||||||
#include <split_at.h>
|
#include <split_at.h>
|
||||||
|
#include <dict_ht.h>
|
||||||
|
|
||||||
/* Global library. */
|
/* Global library. */
|
||||||
|
|
||||||
@ -395,12 +396,12 @@ const char *pcf_parse_master_entry(PCF_MASTER_ENT *masterp, const char *buf)
|
|||||||
concatenate("ro", PCF_NAMESP_SEP_STR, masterp->name_space, (char *) 0);
|
concatenate("ro", PCF_NAMESP_SEP_STR, masterp->name_space, (char *) 0);
|
||||||
masterp->argv = argv;
|
masterp->argv = argv;
|
||||||
masterp->valid_names = 0;
|
masterp->valid_names = 0;
|
||||||
|
masterp->ro_params = dict_ht_open(ro_name_space, O_CREAT | O_RDWR, 0);
|
||||||
process_name = basename(argv->argv[PCF_MASTER_FLD_CMD]);
|
process_name = basename(argv->argv[PCF_MASTER_FLD_CMD]);
|
||||||
dict_update(ro_name_space, VAR_PROCNAME, process_name);
|
dict_put(masterp->ro_params, VAR_PROCNAME, process_name);
|
||||||
dict_update(ro_name_space, VAR_SERVNAME,
|
dict_put(masterp->ro_params, VAR_SERVNAME,
|
||||||
strcmp(process_name, argv->argv[0]) != 0 ?
|
strcmp(process_name, argv->argv[0]) != 0 ?
|
||||||
argv->argv[0] : process_name);
|
argv->argv[0] : process_name);
|
||||||
masterp->ro_params = dict_handle(ro_name_space);
|
|
||||||
myfree(ro_name_space);
|
myfree(ro_name_space);
|
||||||
masterp->all_params = 0;
|
masterp->all_params = 0;
|
||||||
return (0);
|
return (0);
|
||||||
|
3
postfix/src/postconf/test72.ref
Normal file
3
postfix/src/postconf/test72.ref
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
smtp unix - n n - 0 other
|
||||||
|
smtp fifo - n n - 0 other
|
||||||
|
smtp inet - n n - 0 other
|
3
postfix/src/postconf/test73.ref
Normal file
3
postfix/src/postconf/test73.ref
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
smtp unix - n n - 0 otherx
|
||||||
|
smtp fifo - n n - 0 other
|
||||||
|
smtp inet - n n - 0 other
|
3
postfix/src/postconf/test74.ref
Normal file
3
postfix/src/postconf/test74.ref
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
smtp unix - n n - 0 other
|
||||||
|
lmtp unix - n n - 0 otherx
|
||||||
|
smtp inet - n n - 0 other
|
3
postfix/src/postconf/test75.ref
Normal file
3
postfix/src/postconf/test75.ref
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
./postconf: warning: ignoring earlier request: 'mail_version = x'
|
||||||
|
config_directory = .
|
||||||
|
mail_version = y
|
Loading…
x
Reference in New Issue
Block a user