]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.7-20211217
authorWietse Venema <wietse@porcupine.org>
Fri, 17 Dec 2021 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Wed, 19 Jan 2022 06:36:08 +0000 (01:36 -0500)
postfix/HISTORY
postfix/WISHLIST
postfix/src/global/mail_addr_find.c
postfix/src/global/mail_version.h
postfix/src/proxymap/proxymap.c
postfix/src/smtp/smtp_proto.c

index 205e72ad084cf795bb722dd3d79d87394f4af4e6..14dece592e607cbf5eaa260d644aa44b4b076de2 100644 (file)
@@ -25956,3 +25956,15 @@ Apologies for any names omitted.
 
        Documentation: added a "howto tip" to the stock main.cf
        file. File: conf/main.cf
+
+20211211
+
+       Logging: the Postfix SMTP client logs an info message when it
+       breaks a long line with "<CR><LF><SP>".
+
+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.
index 3801c64e568b6e933349a9560f4a1a6a9b4e1432..701d0c7cdf085fea5e2fa8e40d86eb702256a6c3 100644 (file)
@@ -1,11 +1,15 @@
 Wish list:
 
+       Factor out the new get_nested_dict_name() function from
+       proxymap.c, make it a library function, and reuse it in
+       postconf_dbms.c.
+
        Convert the proxymap protol into "server speaks first".
 
        Fix code that still uses "long" for data_size and data_offset,
        and that uses "%ld" in sscanf().
 
-       A smart query services for live Postfix tables that outputs JSON?
+       A smart query service for live Postfix tables that outputs JSON?
 
        proxy_read_maps needs a dedicated matcher that looks
        inside pipemap:{}. Maybe steal some code from postconf.
@@ -21,9 +25,6 @@ Wish list:
        (virtual_mailbox_maps or reject unverified_recipient), and
        virtual_transport.
 
-       In addition to the xxx_per_record_deadline, specify
-       a minimum data rate for the DATA stage.
-
        Make smtpd_relay_before_recipient_restrictions settable
        in smtpd_checks tests.
 
@@ -34,11 +35,6 @@ Wish list:
        requests for unsupported functionality; return an error status,
        instead of terminating.
 
-       Inline regexp/pcre/cidr table support. If the table name is
-       a string inside {}, then split the string on comma (ignoring
-       commas inside {}), write each resulting fragment as one line to
-       a VSTRING buffer, and open that buffer as a memory file.
-
        Add a robust dnssec_probe regression test (success and fail)
        that does not break existing regression tests.
 
index d8b94fb2f75cd6970e5476a75ee809b3f8926cbd..afbccd521ab8980320510f0cd0c80ba36eb6aed1 100644 (file)
@@ -94,7 +94,8 @@
 /*     external and internal forms differ), or MA_FORM_INTERNAL_FIRST
 /*     (internal form, then external form if the internal and external
 /*     forms differ).
-/* .IP in_form .IP out_form
+/* .IP in_form
+/* .IP out_form
 /*     Input and output address forms, one of MA_FORM_INTERNAL (unquoted
 /*     form), or MA_FORM_EXTERNAL (quoted form).
 /* .IP strategy
index 5774f1d991eec294ff3abaf2dd94f22b9490a84d..21d9d1d1fd9fb3a47b4b7bd06c6f1ac6b6833247 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      "20211205"
+#define MAIL_RELEASE_DATE      "20211217"
 #define MAIL_VERSION_NUMBER    "3.7"
 
 #ifdef SNAPSHOT
index b0b844678061e1938eab316db5ce64052775882a..a42ee73b873b8cabf8b987123236da21b54e912e 100644 (file)
 #include <htable.h>
 #include <stringops.h>
 #include <dict.h>
+#include <dict_pipe.h>
+#include <dict_union.h>
 
 /* Global library. */
 
@@ -295,6 +297,27 @@ static int proxy_writer;
 #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,
@@ -660,41 +683,17 @@ DICT   *dict_proxy_open(const char *map, int open_flags, int dict_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;
 
-    /*
-     * Are we proxy writer?
-     */
-    if (strcmp(service_name, MAIL_SERVICE_PROXYWRITE) == 0)
-       proxy_writer = 1;
-    else if (strcmp(service_name, MAIL_SERVICE_PROXYMAP) != 0)
-       msg_fatal("service name must be one of %s or %s",
-                 MAIL_SERVICE_PROXYMAP, MAIL_SERVICE_PROXYMAP);
-
-    /*
-     * Pre-allocate buffers.
-     */
-    request = vstring_alloc(10);
-    request_map = vstring_alloc(10);
-    request_key = vstring_alloc(10);
-    request_value = vstring_alloc(10);
-    map_type_name_flags = vstring_alloc(10);
-
-    /*
-     * Prepare the pre-approved list of proxied tables.
-     */
-    saved_filter = bp = 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) {
+       char   *nested_info;
+
        /* Maybe { maptype:mapname attr=value... } */
        if (*type_name == parens[0]) {
            char   *err;
@@ -710,6 +709,22 @@ static void post_jail_init(char *service_name, char **unused_argv)
            if ((type_name = mystrtokq(&type_name, sep, parens)) == 0)
                continue;
        }
+       /* 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_MAP_PARAM_NAME(proxy_writer), err);
+               myfree(err);
+               continue;
+           }
+           authorize_proxied_maps(nested_info);
+           continue;
+       }
        if (strncmp(type_name, PROXY_COLON, PROXY_COLON_LEN))
            continue;
        do {
@@ -723,6 +738,39 @@ static void post_jail_init(char *service_name, char **unused_argv)
                         PROXY_MAP_PARAM_NAME(proxy_writer));
        }
     }
+}
+
+/* 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?
+     */
+    if (strcmp(service_name, MAIL_SERVICE_PROXYWRITE) == 0)
+       proxy_writer = 1;
+    else if (strcmp(service_name, MAIL_SERVICE_PROXYMAP) != 0)
+       msg_fatal("service name must be one of %s or %s",
+                 MAIL_SERVICE_PROXYMAP, MAIL_SERVICE_PROXYMAP);
+
+    /*
+     * Pre-allocate buffers.
+     */
+    request = vstring_alloc(10);
+    request_map = vstring_alloc(10);
+    request_key = vstring_alloc(10);
+    request_value = vstring_alloc(10);
+    map_type_name_flags = vstring_alloc(10);
+
+    /*
+     * Prepare the pre-approved list of proxied tables.
+     */
+    saved_filter = mystrdup(proxy_writer ? var_proxy_write_maps :
+                           var_proxy_read_maps);
+    proxy_auth_maps = htable_create(13);
+    authorize_proxied_maps(saved_filter);
     myfree(saved_filter);
 
     /*
index 34afb3fee1848ede319978a43f133681ed1145c4..d110fc287fdfb6f9a9c73cf9c707afee35bcd99f 100644 (file)
@@ -1187,6 +1187,15 @@ static void smtp_text_out(void *context, int rec_type,
            if (data_left > 0 || rec_type == REC_TYPE_CONT) {
                smtp_fputc(' ', session->stream);
                state->space_left -= 1;
+
+               /*
+                * XXX This can insert a line break into the middle of a
+                * multi-byte character (not necessarily UTF-8). Note that
+                * multibyte characters can span queue file records, for
+                * example if line_length_limit == smtp_line_length_limit.
+                */
+               msg_info("%s: breaking line > %d bytes with <CR><LF>SPACE",
+                        state->request->queue_id, var_smtp_line_limit);
            }
        } else {
            if (rec_type == REC_TYPE_CONT) {