]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.9-20230502
authorWietse Venema <wietse@porcupine.org>
Tue, 2 May 2023 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Thu, 4 May 2023 03:52:56 +0000 (23:52 -0400)
postfix/HISTORY
postfix/proto/stop.spell-history
postfix/src/global/mail_version.h
postfix/src/postconf/Makefile.in
postfix/src/postconf/postconf_edit.c
postfix/src/postconf/postconf_master.c
postfix/src/postconf/test72.ref [new file with mode: 0644]
postfix/src/postconf/test73.ref [new file with mode: 0644]
postfix/src/postconf/test74.ref [new file with mode: 0644]
postfix/src/postconf/test75.ref [new file with mode: 0644]

index baaf4922ac175096bdf2c8189e121d5ef9fd7570..d535f378f1023b22177326b3b3572cfda472c8ce 100644 (file)
@@ -27078,3 +27078,29 @@ Apologies for any names omitted.
        Cleanup: in the PostgreSQL client, cosmetic changes to make
        the code easier to maintain (in preparation for adding new
        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.
index 096da091a198c0d9dab29d1a05c9c66f059f9e60..ccaef1f1fb5cf498f0bff527681642bbd67ab690 100644 (file)
@@ -56,3 +56,5 @@ Valgrind
 Florian
 Piekert
 refactored
+Fumiyasu
+SATOH
index 775fa2a8c4d1fc01ca9719738bdc4743425c242c..202583f1259537855803d1219b32c584ee5a77ae 100644 (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      "20230419"
+#define MAIL_RELEASE_DATE      "20230502"
 #define MAIL_VERSION_NUMBER    "3.9"
 
 #ifdef SNAPSHOT
index 6aff794aa72d3406d719f88f1333b3cfe8e53322..f872b8aae83540934370bec247079a5a29feaefa 100644 (file)
@@ -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 \
        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 test71
+       test62 test63 test64 test65 test66 test67 test68 test69 test70 test71 \
+       test72 test73 test74 test75
 
 root_tests:
 
@@ -989,6 +990,54 @@ test71:    $(PROG) test71.ref
        diff test71.ref 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)
        rm -rf printfck
        mkdir printfck
@@ -1184,6 +1233,7 @@ postconf_main.o: postconf_main.c
 postconf_master.o: ../../include/argv.h
 postconf_master.o: ../../include/check_arg.h
 postconf_master.o: ../../include/dict.h
+postconf_master.o: ../../include/dict_ht.h
 postconf_master.o: ../../include/htable.h
 postconf_master.o: ../../include/mail_params.h
 postconf_master.o: ../../include/master_proto.h
index eb57cc8b504118d8854616d93a998b1b7de13b56..7085acd7278d406341253a768e26b199158d7fdf 100644 (file)
@@ -192,6 +192,11 @@ void    pcf_edit_main(int mode, int argc, char **argv)
        } else {
            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->value = edit_value;
        cvalue->found = 0;
@@ -456,8 +461,38 @@ void    pcf_edit_master(int mode, int argc, char **argv)
 
            /*
             * 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++) {
+               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,
                                              service_name,
                                              service_type)) {
@@ -503,18 +538,30 @@ void    pcf_edit_master(int mode, int argc, char **argv)
                             * Replace entire master.cf entry.
                             */
                        case PCF_MASTER_ENTRY:
-                           if (new_entry != 0)
-                               pcf_free_master_entry(new_entry);
-                           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);
+                           if (req->match_count == 1)
+                               use_tentative_entry = 1;
                            break;
                        default:
                            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);
+                   }
                }
            }
 
index 3606ac70cea2dcb768fc587e53a4c335094c4242..bddb1af25f8337781a29d9f9a9a04481c8d18fcf 100644 (file)
 #include <readlline.h>
 #include <stringops.h>
 #include <split_at.h>
+#include <dict_ht.h>
 
 /* 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);
     masterp->argv = argv;
     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]);
-    dict_update(ro_name_space, VAR_PROCNAME, process_name);
-    dict_update(ro_name_space, VAR_SERVNAME,
-               strcmp(process_name, argv->argv[0]) != 0 ?
-               argv->argv[0] : process_name);
-    masterp->ro_params = dict_handle(ro_name_space);
+    dict_put(masterp->ro_params, VAR_PROCNAME, process_name);
+    dict_put(masterp->ro_params, VAR_SERVNAME,
+            strcmp(process_name, argv->argv[0]) != 0 ?
+            argv->argv[0] : process_name);
     myfree(ro_name_space);
     masterp->all_params = 0;
     return (0);
diff --git a/postfix/src/postconf/test72.ref b/postfix/src/postconf/test72.ref
new file mode 100644 (file)
index 0000000..6b13cdc
--- /dev/null
@@ -0,0 +1,3 @@
+smtp       unix  -       n       n       -       0       other
+smtp       fifo  -       n       n       -       0       other
+smtp       inet  -       n       n       -       0       other
diff --git a/postfix/src/postconf/test73.ref b/postfix/src/postconf/test73.ref
new file mode 100644 (file)
index 0000000..9554cc0
--- /dev/null
@@ -0,0 +1,3 @@
+smtp       unix  -       n       n       -       0       otherx
+smtp       fifo  -       n       n       -       0       other
+smtp       inet  -       n       n       -       0       other
diff --git a/postfix/src/postconf/test74.ref b/postfix/src/postconf/test74.ref
new file mode 100644 (file)
index 0000000..2886334
--- /dev/null
@@ -0,0 +1,3 @@
+smtp       unix  -       n       n       -       0       other
+lmtp       unix  -       n       n       -       0       otherx
+smtp       inet  -       n       n       -       0       other
diff --git a/postfix/src/postconf/test75.ref b/postfix/src/postconf/test75.ref
new file mode 100644 (file)
index 0000000..b8c54ab
--- /dev/null
@@ -0,0 +1,3 @@
+./postconf: warning: ignoring earlier request: 'mail_version = x'
+config_directory = .
+mail_version = y