]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.3-20170716
authorWietse Venema <wietse@porcupine.org>
Sun, 16 Jul 2017 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Sun, 20 Aug 2017 03:39:16 +0000 (23:39 -0400)
12 files changed:
postfix/HISTORY
postfix/WISHLIST
postfix/src/global/mail_addr_crunch.c
postfix/src/global/mail_addr_crunch.ref
postfix/src/global/mail_addr_map.c
postfix/src/global/mail_version.h
postfix/src/postconf/Makefile.in
postfix/src/postconf/postconf_dbms.c
postfix/src/postconf/test66.ref [new file with mode: 0644]
postfix/src/postscreen/postscreen_haproxy.c
postfix/src/smtpd/smtpd_haproxy.c
postfix/src/util/sys_defs.h

index 0f55b7bd1805fa47e68b63691b498673ab8f472c..1eb3a09c3a322a160e06952bf0531adfc1c48a74 100644 (file)
@@ -23023,10 +23023,40 @@ Apologies for any names omitted.
 
        Security: Berkeley DB 2 and later try to read settings from
        a file DB_CONFIG in the current directory.  This undocumented
-       feature may introduce undisclosed vulnerabilities resulting in
-       privilege escalation with Postfix set-gid programs (postdrop,
-       postqueue) before they chdir to the Postfix queue directory,
-       and with the postmap and postalias commands depending on whether
-       the user's current directory is writable by other users. This
-       fix does not change Postfix behavior for Berkeley DB < 3.
-       File: util/dict_db.c.
+       feature may introduce undisclosed vulnerabilities resulting
+       in privilege escalation with Postfix set-gid programs
+       (postdrop, postqueue) before they chdir to the Postfix queue
+       directory, and with the postmap and postalias commands
+       depending on whether the user's current directory is writable
+       by other users. This fix does not change Postfix behavior
+       for Berkeley DB < 3, but reduces file create performance
+       for Berkeley DB 3 .. 4.6.  File: util/dict_db.c.
+
+20170617
+
+       Cleanup: the postconf command warns about unknown parameter
+       names in a database configuration file, specified as an
+       absolute pathname (for example, ldap:/path/to/file). This
+       code was mostly written in January 2017, and it still is a
+       partial implementation.  Files: postconf/postconf_dbms.c,
+       postconf/Makefile.in, postconf/test66.ref.
+
+20170618 
+
+       Cleanup: added missing "defined(__GLIBC__)" guards for
+       GLIBC version tests. File: util/sys_defs.h.
+
+20170620
+
+       Bugfix (introduced: Postfix 3.2) extension propagation was
+       broken with "recipient_delimiter = .", because of code that
+       was too clever by half. Files: global/mail_adr_crunch.c,
+       global/mail_addr_crunch.ref.
+
+20170704
+
+       Typos (introduced: Postfix 2.10): in comments about
+       IPv4-in-IPv6 addresses, replace :ffff::1.2.3.4 with the
+       correct form :ffff::1.2.3.4. Incorrect or misleading comments
+       are worse than no comments. Files: smtpd/smtpd_haproxy.c,
+       postscreen/postscreen_haproxy.c.
index 397e7833cc24afd485bba2012a5fc03fef6ff642..06e4907cdcbceb89d04aa6d7712ab8f6b8fe6e59 100644 (file)
@@ -6,6 +6,20 @@ Wish list:
 
        Disable -DSNAPSHOT and -DNONPROD in makedefs.
 
+       Add postwhite as a postscreen-related project.
+       https://github.com/stevejenkins/postwhite/blob/master/README.md
+
+       Decide whether to deprecate database configuration pathnames
+       that start with ".", for example, ldap:./file/name. These forms
+       are documented for ldap:, memcache:, mysql:, pgsql:, and sqlite:
+       maps. Postfix daemon processes will look up files relative to the
+       queue directory, but with postmap command-line processes it would
+       be more natural to interpret relative pathnames relative to the
+       current directory of the calling process (it would be a surprise
+       if "postmap hash:./foo" would access "/var/spool/postfix/foo",
+       or if "postmap hash:foo" and or "postmap hash:./foo" would access
+       different files).
+
        Convert postalias(1) to store external-form keys, and convert
        aliases(5) to perform external-first lookup with fallback to
        internal form, to make it consistent with the rest of Postfix.
index 7ca7c0c9ccc648923fef99fafa39ec0490120944..006d322b45985e72e6f48f29624456af622d9bb9 100644 (file)
@@ -120,7 +120,7 @@ ARGV   *mail_addr_crunch_opt(const char *string, const char *extension,
        tok822_externalize(extern_addr, tpp[0]->head, TOK822_STR_DEFL);
        canon_addr_external(canon_addr, STR(extern_addr));
        unquote_822_local(intern_addr, STR(canon_addr));
-       if (extension && strchr(STR(intern_addr), *extension) == 0) {
+       if (extension) {
            VSTRING_SPACE(intern_addr, extlen + 1);
            if ((ratsign = strrchr(STR(intern_addr), '@')) == 0) {
                vstring_strcat(intern_addr, extension);
index ec95edfe67320937ae19eea63470fe12a182fbcc..fe5fb2e27a9a411974e606b47ce0196b1758fefd 100644 (file)
@@ -1,7 +1,7 @@
 ==== external to internal, with extension
 |foo+extension@example.com|
 |foo bar+extension@example.com|
-|foo+ext@example.com|
+|foo+ext+extension@example.com|
 ==== external to internal, without extension
 |foo@example.com|
 |foo bar@example.com|
@@ -9,14 +9,14 @@
 ==== external to external, with extension
 |foo+extension@example.com|
 |"foo bar+extension"@example.com|
-|foo+ext@example.com|
+|foo+ext+extension@example.com|
 ==== external to external, without extension
 |foo@example.com|
 |"foo bar"@example.com|
 |foo+ext@example.com|
 ==== internal to internal, with extension
 |foo+extension@example.com|
-|foo+ext@example.com|
+|foo+ext+extension@example.com|
 ==== internal to internal, without extension
 |foo@example.com|
 |foo+ext@example.com|
index de2ab09de12747d8787ad0b8563e1839e833376a..5e0959072d0bf39d7948101d4f6bc5f970afcc7d 100644 (file)
@@ -256,6 +256,7 @@ typedef struct {
 #define DO_PROPAGATE_UNMATCHED_EXTENSION       1
 #define NO_RECIPIENT_DELIMITER                 ""
 #define PLUS_RECIPIENT_DELIMITER               "+"
+#define DOT_RECIPIENT_DELIMITER                        "."
 
  /*
   * All these tests must pass, so that we know that mail_addr_map_opt() works
@@ -352,6 +353,14 @@ static MAIL_ADDR_MAP_TEST pass_tests[] = {
        "a@a@example.com",
        {"\"a@a\"@example.net"}, 1,
     },
+    {
+        "12 external -external-> external, extension, propagation",
+        "inline:{ aa@example.com=bb@example.com }",
+        DO_PROPAGATE_UNMATCHED_EXTENSION, DOT_RECIPIENT_DELIMITER,
+        MA_FORM_EXTERNAL, MA_FORM_EXTERNAL, MA_FORM_EXTERNAL,
+        "aa.ext@example.com",
+        {"bb.ext@example.com"}, 1,
+    },
     0,
 };
 
index bd7b1b29bd9e1ff153d91bd8e6a6d792d7126e50..beb0abbd646890faca8278a5f0a0dfad859fe5d3 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      "20170612"
+#define MAIL_RELEASE_DATE      "20170716"
 #define MAIL_VERSION_NUMBER    "3.3"
 
 #ifdef SNAPSHOT
index 05c6a334247de98cb564e65281df7b4d22a0ed53..4a7d7ead1b8036bc3480071c60063b29bc8bb33a 100644 (file)
@@ -52,7 +52,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
+       test62 test63 test64 test65 test66
 
 root_tests:
 
@@ -870,6 +870,22 @@ test65: $(PROG) test65.ref
        diff test65.ref test65.tmp
        rm -f main.cf master.cf test65.tmp
 
+# unknown parameters in database configuration file (absolute pathname).
+
+test66: $(PROG) test66.ref
+       rm -f main.cf master.cf
+       touch master.cf
+       echo alias_maps = ldap:`pwd`/test66.cf >> main.cf
+       echo " " mysql:`pwd`/test66.cf >> main.cf
+       echo " " pgsql:`pwd`/test66.cf >> main.cf
+       echo " " sqlite:`pwd`/test66.cf >> main.cf
+       echo " " memcache:`pwd`/test66.cf >> main.cf
+       echo junk = junk >> test66.cf
+       touch -t 197101010000 main.cf
+       $(SHLIB_ENV) ./$(PROG) -c. 2>test66.tmp >/dev/null
+       sed "s;PWD;`pwd`;" test66.ref | diff - test66.tmp
+       rm -f main.cf master.cf test66.tmp test66.cf
+
 printfck: $(OBJS) $(PROG)
        rm -rf printfck
        mkdir printfck
@@ -971,6 +987,7 @@ postconf_builtin.o: time_vars.h
 postconf_dbms.o: ../../include/argv.h
 postconf_dbms.o: ../../include/check_arg.h
 postconf_dbms.o: ../../include/dict.h
+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
index 5e3aca2e3b548f00ef9f3ad94c679002f87ccff0..33542073af173e3c853f4644960bd9eb046c69ed 100644 (file)
@@ -22,7 +22,9 @@
 /*     When a database type is found that supports legacy-style
 /*     configuration, the table name is combined with each of the
 /*     database-defined suffixes to generate candidate parameter
-/*     names for that database type.
+/*     names for that database type; if the table name specifies
+/*     a client configuration file, that file is scanned for unused
+/*     parameter settings.
 /* .IP flag_parameter
 /*     A function that takes as arguments a candidate parameter
 /*     name, parameter flags, and a PCF_MASTER_ENT pointer.  The
@@ -46,6 +48,7 @@
 /* System library. */
 
 #include <sys_defs.h>
+#include <errno.h>
 #include <string.h>
 
 /* Utility library. */
@@ -61,6 +64,7 @@
 
 #include <mail_conf.h>
 #include <mail_params.h>
+#include <dict_ht.h>
 #include <dict_proxy.h>
 #include <dict_ldap.h>
 #include <dict_mysql.h>
@@ -145,6 +149,64 @@ static const PCF_DBMS_INFO pcf_dbms_info[] = {
     0,
 };
 
+/* 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)
+{
+    DICT   *dict;
+    VSTREAM *fp;
+    const char **cpp;
+    const char *name;
+    const char *value;
+    char   *dict_spec;
+    int     dir;
+
+    /*
+     * We read each database client configuration file into its own
+     * dictionary, and nag only the first time that a file is visited.
+     */
+    dict_spec = concatenate(dp->db_type, ":", cf_file, (char *) 0);
+    if ((dict = dict_handle(dict_spec)) == 0) {
+
+       /*
+        * Populate the dictionary with settings in this database client
+        * configuration file. Don't die if a file can't be opened - some
+        * files may contain passwords and should not be world-readable.
+        * Note: dict_load_fp() nags about duplicate pameter settings.
+        */
+       dict = dict_ht_open(dict_spec, O_CREAT | O_RDWR, 0);
+       dict_register(dict_spec, dict);
+       if ((fp = vstream_fopen(cf_file, O_RDONLY, 0)) == 0
+           && errno != EACCES) {
+           msg_warn("open \"%s\" configuration \"%s\": %m",
+                    dp->db_type, cf_file);
+           myfree(dict_spec);
+           return;
+       }
+       dict_load_fp(dict_spec, fp);
+       if (vstream_fclose(fp)) {
+           msg_warn("read \"%s\" configuration \"%s\": %m",
+                    dp->db_type, cf_file);
+           myfree(dict_spec);
+           return;
+       }
+
+       /*
+        * Remove all known database client parameters from this dictionary,
+        * then report the remaining ones as "unused". We use ad-hoc logging
+        * code, because a database client parameter namespace is unlike the
+        * parameter namespaces in main.cf or master.cf.
+        */
+       for (cpp = dp->db_suffixes; *cpp; cpp++)
+           (void) dict_del(dict, *cpp);
+       for (dir = DICT_SEQ_FUN_FIRST;
+            dict->sequence(dict, dir, &name, &value) == DICT_STAT_SUCCESS;
+            dir = DICT_SEQ_FUN_NEXT)
+           msg_warn("%s: unused parameter: %s=%s", dict_spec, name, value);
+    }
+    myfree(dict_spec);
+}
+
 /* pcf_register_dbms_helper - parse one possible database type:name */
 
 static void pcf_register_dbms_helper(char *str_value,
@@ -172,6 +234,28 @@ static void pcf_register_dbms_helper(char *str_value,
               && strcmp(db_type, DICT_TYPE_PROXY) == 0)
            db_type = prefix;
 
+       if (prefix == 0)
+           continue;
+
+       /*
+        * Look for database:prefix where the prefix is an absolute pathname.
+        * Then, report unknown database client configuration parameters.
+        * 
+        * XXX What about a pathname beginning with '.'? This supposedly is
+        * relative to the queue directory, which is the default directory
+        * for all Postfix daemon processes. This would also have to handle
+        * the case that the queue is not yet created.
+        */
+       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);
+                   break;
+               }
+           }
+           continue;
+       }
+
        /*
         * Look for database:prefix where the prefix is not a pathname and
         * the database is a known type. Synthesize candidate parameter names
@@ -179,7 +263,7 @@ static void pcf_register_dbms_helper(char *str_value,
         * list, and see if those parameters have a "name=value" entry in the
         * local or global namespace.
         */
-       if (prefix != 0 && *prefix != '/' && *prefix != '.') {
+       if (*prefix != '.') {
            if (*prefix == CHARS_BRACE[0]) {
                if ((err = extpar(&prefix, CHARS_BRACE, EXTPAR_FLAG_NONE)) != 0) {
                    /* XXX Encapsulate this in pcf_warn() function. */
diff --git a/postfix/src/postconf/test66.ref b/postfix/src/postconf/test66.ref
new file mode 100644 (file)
index 0000000..bd35822
--- /dev/null
@@ -0,0 +1,5 @@
+./postconf: warning: ldap:PWD/test66.cf: unused parameter: junk=junk
+./postconf: warning: mysql:PWD/test66.cf: unused parameter: junk=junk
+./postconf: warning: pgsql:PWD/test66.cf: unused parameter: junk=junk
+./postconf: warning: sqlite:PWD/test66.cf: unused parameter: junk=junk
+./postconf: warning: memcache:PWD/test66.cf: unused parameter: junk=junk
index 664d76c04384033e030894f8d76351ef7495e3ac..b91cf19538b96398767775712551b971f64c6636 100644 (file)
@@ -133,7 +133,7 @@ static void psc_endpt_haproxy_event(int event, void *context)
     /*
      * Parse the haproxy line. Note: the haproxy_srvr_parse() routine
      * performs address protocol checks, address and port syntax checks, and
-     * converts IPv4-in-IPv6 address string syntax (:ffff::1.2.3.4) to IPv4
+     * converts IPv4-in-IPv6 address string syntax (::ffff:1.2.3.4) to IPv4
      * syntax where permitted by the main.cf:inet_protocols setting.
      */
     if (status == 0 && last_char == '\n') {
index 300bce44ac5607483fea375551a8c6eac773282d..3bcbffc6aebe5740b04c3ed127866ee04cc8da75 100644 (file)
@@ -111,7 +111,7 @@ int     smtpd_peer_from_haproxy(SMTPD_STATE *state)
     /*
      * Note: the haproxy_srvr_parse() routine performs address protocol
      * checks, address and port syntax checks, and converts IPv4-in-IPv6
-     * address string syntax (:ffff::1.2.3.4) to IPv4 syntax where permitted
+     * address string syntax (::ffff:1.2.3.4) to IPv4 syntax where permitted
      * by the main.cf:inet_protocols setting, but logs no warnings.
      */
 #define ENABLE_DEADLINE        1
index 3f570c46aa6ca74e8853775a54abc80aec1354e0..f4f53300f317383621abd2299de544ad19ed26c2 100644 (file)
@@ -782,7 +782,8 @@ extern int initgroups(const char *, int);
 #define HAVE_GLIBC_API_VERSION_SUPPORT(maj, min) __GLIBC_PREREQ(maj, min)
 #else
 #define HAVE_GLIBC_API_VERSION_SUPPORT(maj, min) \
-    ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min))
+    (defined(__GLIBC__) && \
+       ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min)))
 #endif
 #if HAVE_GLIBC_API_VERSION_SUPPORT(2, 1)
 #define SOCKADDR_SIZE  socklen_t
@@ -805,7 +806,7 @@ extern int initgroups(const char *, int);
 #define KERNEL_VERSION(a,b,c) (LINUX_VERSION_CODE + 1)
 #endif
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)) \
-       || (__GLIBC__ < 2)
+       || (defined(__GLIBC__) && __GLIBC__ < 2)
 #define CANT_USE_SEND_RECV_MSG
 #define DEF_SMTP_CACHE_DEMAND  0
 #else