]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.12-20150113-nonprod 20150110-nonprod
authorWietse Venema <wietse@porcupine.org>
Tue, 13 Jan 2015 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Wed, 14 Jan 2015 05:49:47 +0000 (00:49 -0500)
45 files changed:
postfix/HISTORY
postfix/WISHLIST
postfix/src/bounce/bounce.c
postfix/src/cleanup/cleanup_init.c
postfix/src/cleanup/cleanup_masquerade.c
postfix/src/flush/flush.c
postfix/src/global/addr_match_list.c
postfix/src/global/addr_match_list.h
postfix/src/global/db_common.c
postfix/src/global/debug_peer.c
postfix/src/global/domain_list.c
postfix/src/global/domain_list.h
postfix/src/global/flush_clnt.c
postfix/src/global/mail_version.h
postfix/src/global/match_parent_style.c
postfix/src/global/namadr_list.c
postfix/src/global/namadr_list.h
postfix/src/global/namadr_list.ref
postfix/src/global/resolve_local.c
postfix/src/global/resolve_local.ref
postfix/src/global/server_acl.c
postfix/src/global/server_acl.ref
postfix/src/global/string_list.c
postfix/src/global/string_list.h
postfix/src/global/user_acl.c
postfix/src/global/user_acl.h
postfix/src/postdrop/postdrop.c
postfix/src/postqueue/postqueue.c
postfix/src/postscreen/postscreen.c
postfix/src/qmqpd/qmqpd.c
postfix/src/sendmail/sendmail.c
postfix/src/smtp/smtp.c
postfix/src/smtp/smtp_sasl_glue.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpd/smtpd_error.ref
postfix/src/trivial-rewrite/resolve.c
postfix/src/util/casefold.c
postfix/src/util/casefold_test.in
postfix/src/util/casefold_test.ref
postfix/src/util/dict_utf8.c
postfix/src/util/match_list.c
postfix/src/util/match_list.h
postfix/src/util/match_ops.c
postfix/src/util/printable.c

index 6126f4ba91a03a6c847af5c4a822132f584a0b7e..f990bedc3c48ecf6ac6d757ffa3160496bffa4d8 100644 (file)
@@ -21348,11 +21348,34 @@ Apologies for any names omitted.
 
 20150112
 
-       Support for UTF-8 casefolding in match_lists. Instead of
-       using strcasecmp(), casefold all string constant patterns
-       during initialization, and casefold a search string at the
-       beginning of the search, and use strcmp() for comparison.
-       Files: util/casefold.c util/dict.h, util/dict_utf8.c,
+       Infrastructure: support for UTF-8 casefolding in match_lists.
+       Instead of using strcasecmp(), casefold all fixed-string
+       patterns during initialization, casefold a search string
+       at the beginning of the search, and use strcmp() for
+       comparison.  Files: util/casefold.c util/dict.h, util/dict_utf8.c,
        util/match_list.c, util/match_list.h, util/match_ops.c,
        util/stringops.h, global/addr_match_list.c, global/domain_list.c,
        global/namadr_list.c, global/string_list.c.
+
+20150113
+
+       Cleanup: show the configuration parameter name in error
+       messages while parsing or searching match_list-based features
+       such as mydestination, relay_domains and a few dozen more.
+       Files: cleanup/cleanup_init.c, flush/flush.c,
+       global/addr_match_list.c, global/debug_peer.c,
+       global/domain_list.c, global/flush_clnt.c,
+       global/match_parent_style.c, global/namadr_list.c,
+       global/resolve_local.c, global/string_list.c, global/user_acl.[hc],
+       postdrop/postdrop.c, postqueue/postqueue.c,
+       postscreen/postscreen.c, qmqpd/qmqpd.c, sendmail/sendmail.c.,
+       smtp/smtp.c, smtp/smtp_sasl_glue.c, smtpd/smtpd.c,
+       smtpd/smtpd_check.c, trivial-rewrite/resolve.c,
+       util/match_list.[hc], util/match_ops.c.
+
+       Cleanup: apply printable() to all bounce(8) service
+       string-valued protocol fields. File: bounce/bounce.c.
+
+       Apparenly the UCI 4.8 ucasemap_utf8FoldCase() function does
+       not complain about UTF-8 syntax errors, so we add our own
+       redundant check. File: util/casefold.c.
index 26f80b1d10217c6f9acc7855f55c7afae5b5d12d..b83e5f0f3420bdc2a6dd7d09ec1f7058b6a00d6b 100644 (file)
@@ -8,17 +8,6 @@ Wish list:
 
        Things to do after the stable release:
 
-       Add context argument for better match_list diagnostics.
-
-       Expose UTF8 flag in server_acl API. Some applications such
-       as postscreen don't need UTF8 support.
-
-       Expose UTF8 flag in match_list API. Some applications
-       such as address lists don't need UTF8 support.
-
-       Implement UTF8 casefolding in match_list for non-table
-       patterns.
-
        UTF8 DNS[BW]L domain name.
 
        Consolidate maps flags in mail_params.h instead of having
index b33fefc4c846727b21fdfd9a27d1e70c49ed83fe..3b067cb617ba79f861bf58dca0dcd4787833be61 100644 (file)
@@ -319,7 +319,9 @@ static int bounce_notify_proto(char *service_name, VSTREAM *client,
        msg_warn("malformed queue id: %s", printable(STR(queue_id), '?'));
        return (-1);
     }
-    printable(STR(dsn_envid), '?');
+    VS_NEUTER(encoding);
+    VS_NEUTER(sender);
+    VS_NEUTER(dsn_envid);
     if (msg_verbose)
        msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s smtputf8=%d sender=%s envid=%s ret=0x%x",
                 myname, flags, service_name, STR(queue_name), STR(queue_id),
@@ -380,10 +382,12 @@ static int bounce_verp_proto(char *service_name, VSTREAM *client)
        msg_warn("malformed queue id: %s", printable(STR(queue_id), '?'));
        return (-1);
     }
-    printable(STR(dsn_envid), '?');
+    VS_NEUTER(encoding);
+    VS_NEUTER(sender);
+    VS_NEUTER(dsn_envid);
+    VS_NEUTER(verp_delims);
     if (strlen(STR(verp_delims)) != 2) {
-       msg_warn("malformed verp delimiter string: %s",
-                printable(STR(verp_delims), '?'));
+       msg_warn("malformed verp delimiter string: %s", STR(verp_delims));
        return (-1);
     }
     if (msg_verbose)
@@ -460,7 +464,9 @@ static int bounce_one_proto(char *service_name, VSTREAM *client)
        msg_warn("malformed queue id: %s", printable(STR(queue_id), '?'));
        return (-1);
     }
-    printable(STR(dsn_envid), '?');
+    VS_NEUTER(encoding);
+    VS_NEUTER(sender);
+    VS_NEUTER(dsn_envid);
     VS_NEUTER(rcpt_buf->address);
     VS_NEUTER(rcpt_buf->orig_addr);
     VS_NEUTER(rcpt_buf->dsn_orcpt);
index f43f34f2c4a92084e942ee7b7cb20043efcebf9f..cf9381518408c9e98d6cb893c52fa6f4140d2139 100644 (file)
@@ -379,7 +379,8 @@ void    cleanup_pre_jail(char *unused_name, char **unused_argv)
            maps_create(VAR_BODY_CHECKS, var_body_checks, DICT_FLAG_LOCK);
     if (*var_masq_exceptions)
        cleanup_masq_exceptions =
-           string_list_init(MATCH_FLAG_RETURN, var_masq_exceptions);
+           string_list_init(VAR_MASQ_EXCEPTIONS, MATCH_FLAG_RETURN,
+                            var_masq_exceptions);
     if (*var_masq_classes)
        cleanup_masq_flags = name_mask(VAR_MASQ_CLASSES, masq_class_table,
                                       var_masq_classes);
index e81bc188c74618b5da809d526c18d102525cea42..58053c063c39bc9fc94605fb2683b191bd6cd257 100644 (file)
@@ -206,7 +206,8 @@ int     main(int argc, char **argv)
 
     var_masq_exceptions = argv[1];
     cleanup_masq_exceptions =
-       string_list_init(MATCH_FLAG_RETURN, var_masq_exceptions);
+       string_list_init(VAR_MASQ_EXCEPTIONS, MATCH_FLAG_RETURN,
+                        var_masq_exceptions);
     masq_domains = argv_split(argv[2], CHARS_COMMA_SP);
     addr = vstring_alloc(1);
     if (strchr(argv[3], '@') == 0)
index 52603cb46b086c3f1275c1f537918e38d5a17d9d..fccb61cd7cbf62a0ae2337127b87d6ed3107d9ad 100644 (file)
@@ -805,7 +805,7 @@ static void flush_service(VSTREAM *client_stream, char *unused_service,
 
 static void pre_jail_init(char *unused_name, char **unused_argv)
 {
-    flush_domains = domain_list_init(MATCH_FLAG_RETURN
+    flush_domains = domain_list_init(VAR_FFLUSH_DOMAINS, MATCH_FLAG_RETURN
                                   | match_parent_style(VAR_FFLUSH_DOMAINS),
                                     var_fflush_domains);
 }
index fdc95d012a8d664492b4cf28635205aaa3ff6e50..de3d3f9671082329dcabf9ce1ff24b6b43b23fb5 100644 (file)
 
 #ifdef TEST
 
-#include <msg.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
+#include <msg.h>
 #include <vstream.h>
 #include <vstring_vstream.h>
 #include <msg_vstream.h>
+#include <dict.h>
 #include <stringops.h>                 /* util_utf8_enable */
 
 static void usage(char *progname)
@@ -116,7 +117,8 @@ int     main(int argc, char **argv)
        usage(argv[0]);
     dict_allow_surrogate = 1;
     util_utf8_enable = 1;
-    list = addr_match_list_init(MATCH_FLAG_PARENT | MATCH_FLAG_RETURN, argv[optind]);
+    list = addr_match_list_init("command line", MATCH_FLAG_PARENT
+                               | MATCH_FLAG_RETURN, argv[optind]);
     addr = argv[optind + 1];
     if (strcmp(addr, "-") == 0) {
        VSTRING *buf = vstring_alloc(100);
index 67c7e2316d81861c9fabc6b1f5a068c3b64d7ab5..f03c09d95798efb8c0bea02267fe2a9b08429d32 100644 (file)
@@ -21,8 +21,8 @@
   */
 #define ADDR_MATCH_LIST MATCH_LIST
 
-#define addr_match_list_init(f, p) \
-       match_list_init((f), (p), 1, match_hostaddr)
+#define addr_match_list_init(o, f, p) \
+       match_list_init((o), (f), (p), 1, match_hostaddr)
 #define addr_match_list_match(l, a) \
        match_list_match((l), (a))
 #define addr_match_list_free   match_list_free
index 1e5a1d4edb236f2a6ebadc279500f101421ef1eb..491a7269010c59c9dfb26756c1f72c119aa74083 100644 (file)
@@ -256,7 +256,8 @@ void    db_common_parse_domain(CFG_PARSER *parser, void *ctxPtr)
 
     domainlist = cfg_get_str(parser, "domain", "", 0, 0);
     if (*domainlist) {
-       ctx->domain = string_list_init(MATCH_FLAG_RETURN, domainlist);
+       ctx->domain = string_list_init(parser->name, MATCH_FLAG_RETURN,
+                                      domainlist);
        if (ctx->domain == 0)
 
            /*
index 023e1ffda771a7e4d68a804d8e6567830530b4ec..06fcfc8632b2a577da75e64cb620ee5c6ab43ce3 100644 (file)
@@ -99,7 +99,7 @@ void    debug_peer_init(void)
      */
     if (*var_debug_peer_list)
        debug_peer_list =
-           namadr_list_init(MATCH_FLAG_RETURN
+           namadr_list_init(VAR_DEBUG_PEER_LIST, MATCH_FLAG_RETURN
                             | match_parent_style(VAR_DEBUG_PEER_LIST),
                             var_debug_peer_list);
 }
index c64f4de38a8d38a0647a691ab8159813e2c92b8f..2bcd38d2ddf33b2990fe304ba78fa05cf0697417 100644 (file)
 
 #ifdef TEST
 
-#include <msg.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <msg.h>
 #include <vstream.h>
 #include <msg_vstream.h>
+#include <dict.h>
 #include <stringops.h>                 /* util_utf8_enable */
 
 static void usage(char *progname)
@@ -116,7 +117,8 @@ int     main(int argc, char **argv)
        usage(argv[0]);
     dict_allow_surrogate = 1;
     util_utf8_enable = 1;
-    list = domain_list_init(MATCH_FLAG_PARENT | MATCH_FLAG_RETURN, argv[optind]);
+    list = domain_list_init("command line", MATCH_FLAG_PARENT
+                           | MATCH_FLAG_RETURN, argv[optind]);
     host = argv[optind + 1];
     vstream_printf("%s: %s\n", host, domain_list_match(list, host) ?
                   "YES" : list->error == 0 ? "NO" : "ERROR");
index 8612219d9cd8ca65477fcc221fc062820aa1c3c2..b0dfaec1f67dcf3ee8b3a06f15634aa472fe1961 100644 (file)
@@ -21,7 +21,8 @@
   */
 #define DOMAIN_LIST    MATCH_LIST
 
-#define domain_list_init(f, p) match_list_init((f), (p), 1, match_hostname)
+#define domain_list_init(o, f, p)\
+                       match_list_init((o), (f), (p), 1, match_hostname)
 #define domain_list_match      match_list_match
 #define domain_list_free       match_list_free
 
index 07985dc2073ac7904cc9ab5b070ebbdc375ed7a1..7accaa98abadde8b11bfe7e283351310db492ec6 100644 (file)
@@ -103,7 +103,7 @@ static DOMAIN_LIST *flush_domains;
 
 void    flush_init(void)
 {
-    flush_domains = domain_list_init(MATCH_FLAG_RETURN
+    flush_domains = domain_list_init(VAR_FFLUSH_DOMAINS, MATCH_FLAG_RETURN
                                   | match_parent_style(VAR_FFLUSH_DOMAINS),
                                     var_fflush_domains);
 }
index c97ed8e8747325e4c3134e7d6cec7c9b8f677871..04eb716b05932e3b066e43fc6ddc05b1ead1d51c 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      "20150112"
+#define MAIL_RELEASE_DATE      "20150113"
 #define MAIL_VERSION_NUMBER    "2.12"
 
 #ifdef SNAPSHOT
index b07a4fdcd05c064fa01456d8ea6fb51f86a5bda5..c3c9db66f97d849ed29466833183618cb4ef8da8 100644 (file)
@@ -60,7 +60,8 @@ int     match_parent_style(const char *name)
      */
     if (match_par_dom_list == 0)
        match_par_dom_list =
-           string_list_init(MATCH_FLAG_NONE, var_par_dom_match);
+           string_list_init(VAR_PAR_DOM_MATCH, MATCH_FLAG_NONE,
+                            var_par_dom_match);
 
     /*
      * Look up the parent domain matching policy.
index eebfa68db8a29f21b5d6c1c3a8f52e5805b827ea..1be7d54c9ebcb199b503cc99dd1a3b2d9d235ac0 100644 (file)
@@ -89,9 +89,9 @@
 
 #ifdef TEST
 
-#include <msg.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <msg.h>
 #include <vstream.h>
 #include <msg_vstream.h>
 #include <dict.h>
@@ -124,7 +124,8 @@ int     main(int argc, char **argv)
        usage(argv[0]);
     dict_allow_surrogate = 1;
     util_utf8_enable = 1;
-    list = namadr_list_init(MATCH_FLAG_PARENT | MATCH_FLAG_RETURN, argv[optind]);
+    list = namadr_list_init("command line", MATCH_FLAG_PARENT
+                           | MATCH_FLAG_RETURN, argv[optind]);
     host = argv[optind + 1];
     addr = argv[optind + 2];
     vstream_printf("%s/%s: %s\n", host, addr,
index b2322edf86305e977e512647294045600a33756d..e327784a34eab5dd9d274ed827ba075d477b0e92 100644 (file)
@@ -21,8 +21,8 @@
   */
 #define NAMADR_LIST MATCH_LIST
 
-#define namadr_list_init(f, p) \
-       match_list_init((f), (p), 2, match_hostname, match_hostaddr)
+#define namadr_list_init(o, f, p) \
+       match_list_init((o), (f), (p), 2, match_hostname, match_hostaddr)
 #define namadr_list_match      match_list_match
 #define namadr_list_free       match_list_free
 
index b21fe54eaa7f1a891cbf68c759fb94468d5a7ae5..7df05be912c960d3ca5b0fc560d4103994b80c78 100644 (file)
@@ -2,18 +2,18 @@ dummy/168.100.189.2: YES
 dummy/168.100.189.2: NO
 dummy/168.100.189.3: YES
 dummy/168.100.189.16: NO
-./namadr_list: warning: bad net/mask pattern: "168.100.189.0/98"
+./namadr_list: warning: command line: bad net/mask pattern: "168.100.189.0/98"
 dummy/168.100.189.16: ERROR
-./namadr_list: warning: bad net/mask pattern: "168.100.589.0/28"
+./namadr_list: warning: command line: bad net/mask pattern: "168.100.589.0/28"
 dummy/168.100.189.16: ERROR
 dummy/168.100.989.16: NO
 ./namadr_list: error: unsupported dictionary type: 2001
 ./namadr_list: warning: 2001:240:5c7:0:2d0:b7ff:fe88:2ca7 is unavailable. unsupported dictionary type: 2001
-./namadr_list: warning: 2001:240:5c7:0:2d0:b7ff:fe88:2ca7: table lookup problem
+./namadr_list: warning: command line: 2001:240:5c7:0:2d0:b7ff:fe88:2ca7: table lookup problem
 dummy/2001:240:5c7:0:2d0:b7ff:fe88:2ca7: ERROR
 dummy/2001:240:5c7:0:2d0:b7ff:fe88:2ca7: YES
 dummy/2001:240:5c7:0:2d0:b7ff:fe88:2ca8: NO
-./namadr_list: warning: non-null host address bits in "2001:240:5c7:0:2d0:b7ff:fe88:2ca7/64", perhaps you should use "2001:240:5c7::/64" instead
+./namadr_list: warning: command line: non-null host address bits in "2001:240:5c7:0:2d0:b7ff:fe88:2ca7/64", perhaps you should use "2001:240:5c7::/64" instead
 dummy/2001:240:5c7:0:2d0:b7ff:fe88:2ca8: ERROR
 dummy/2001:240:5c7:0:2d0:b7ff:fe88:2ca8: YES
 dummy/2001:24:5c7:0:2d0:b7ff:fe88:2ca8: NO
@@ -32,10 +32,10 @@ foo/168.100.189.3: YES
 bar/168.100.189.3: NO
 baz/168.100.189.3: YES
 x.x.x/127.0.0.1: NO
-./namadr_list: warning: bad net/mask pattern: "be/be"
+./namadr_list: warning: command line: bad net/mask pattern: "be/be"
 x.x.x/127.0.0.1: ERROR
 x.x.x/127.0.0.1: NO
-./namadr_list: warning: bad address pattern: "be:be"
+./namadr_list: warning: command line: bad address pattern: "be:be"
 x.x.x/::1: ERROR
 foo/168.100.189.3: YES
 bar/168.100.189.3: NO
@@ -43,11 +43,11 @@ foo/168.100.189.3: NO
 bar/168.100.189.3: NO
 foo/168.100.189.3: YES
 bar/168.100.189.3: NO
-./namadr_list: warning: fail:1: table lookup problem
+./namadr_list: warning: command line: fail:1: table lookup problem
 bar/168.100.189.3: ERROR
-./namadr_list: warning: fail:1: table lookup problem
+./namadr_list: warning: command line: fail:1: table lookup problem
 bar/168.100.189.3: ERROR
 ./namadr_list: error: open file /tmp/nosuchfile: No such file or directory
 ./namadr_list: warning: non-existent:/tmp/nosuchfile is unavailable. open file /tmp/nosuchfile: No such file or directory
-./namadr_list: warning: non-existent:/tmp/nosuchfile: table lookup problem
+./namadr_list: warning: command line: non-existent:/tmp/nosuchfile: table lookup problem
 bar/168.100.189.3: ERROR
index 98d04b2a8c8e283a578178e75e756c72a4a01c58..c6ef84808c0155f70f29481eef22d2b8b304bcbd 100644 (file)
@@ -69,7 +69,8 @@ void    resolve_local_init(void)
     /* Allow on-the-fly update to make testing easier. */
     if (resolve_local_list)
        string_list_free(resolve_local_list);
-    resolve_local_list = string_list_init(MATCH_FLAG_RETURN, var_mydest);
+    resolve_local_list = string_list_init(VAR_MYDEST, MATCH_FLAG_RETURN,
+                                         var_mydest);
 }
 
 /* resolve_local - match domain against list of local destinations */
index ce46b616f5a8f949ec9fe524b3aa8fe50c9e21f4..e77146999b11e0bebff3c05b2e6f59b840e3c78a 100644 (file)
@@ -1,6 +1,6 @@
 mydestination=example.com destination=example.com YES
 mydestination=example.net destination=example.com NO
-unknown: warning: fail:1_resolve_local: table lookup problem
+unknown: warning: mydestination: fail:1_resolve_local: table lookup problem
 mydestination=fail:1_resolve_local destination=example.com ERROR
 mydestination=fail:1_resolve_local destination=example.com.. NO
 mydestination=fail:1_resolve_local destination= NO
index 2caf063c8b4f07c12e604aa0361b4a7e9c3b1db9..daa2c3ec2b83637f5c614e939d15610f7fdf2d81 100644 (file)
@@ -102,12 +102,12 @@ void    server_acl_pre_jail_init(const char *mynetworks, const char *origin)
            addr_match_list_free(server_acl_mynetworks_host);
     }
     server_acl_mynetworks =
-       addr_match_list_init(MATCH_FLAG_RETURN | match_parent_style(origin),
-                            mynetworks);
+       addr_match_list_init(origin, MATCH_FLAG_RETURN
+                            | match_parent_style(origin), mynetworks);
     if (warn_compat_break_mynetworks_style)
        server_acl_mynetworks_host =
-           addr_match_list_init(MATCH_FLAG_RETURN | match_parent_style(origin),
-                                mynetworks_host());
+           addr_match_list_init(origin, MATCH_FLAG_RETURN
+                                | match_parent_style(origin), mynetworks_host());
 }
 
 /* server_acl_parse - parse access list */
@@ -279,7 +279,7 @@ int     main(void)
        } else if (STREQ(cmd, VAR_SERVER_ACL)) {
            UPDATE_VAR(var_server_acl, value);
        } else if (STREQ(cmd, "address")) {
-           server_acl_pre_jail_init(var_mynetworks, VAR_SERVER_ACL);
+           server_acl_pre_jail_init(var_mynetworks, VAR_MYNETWORKS);
            argv = server_acl_parse(var_server_acl, VAR_SERVER_ACL);
            ret = server_acl_eval(value, argv, VAR_SERVER_ACL);
            argv_free(argv);
index 442fda128914e94b761aa174ec70b96affc6219e..b70f3c654fb6fe09543f6407ecac1612dc32275a 100644 (file)
@@ -9,7 +9,7 @@
 168.100.189.3: permit
 > mynetworks=fail:1
 > address=168.100.189.4
-unknown: warning: fail:1: table lookup problem
+unknown: warning: mynetworks: fail:1: table lookup problem
 unknown: warning: server_acl: permit_mynetworks: mynetworks lookup error -- ignoring the remainder of this access list
 168.100.189.4: error
 > server_acl=fail:1,reject
index b5dda32e838f5388a20b068cf286025462739413..076556783ffd28ace06fe0da6b059fa1154717fa 100644 (file)
 
 #ifdef TEST
 
-#include <msg.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <msg.h>
 #include <vstream.h>
 #include <vstring.h>
 #include <msg_vstream.h>
+#include <dict.h>
 #include <stringops.h>                 /* util_utf8_enable */
 
 static void usage(char *progname)
@@ -109,7 +110,7 @@ int     main(int argc, char **argv)
        usage(argv[0]);
     dict_allow_surrogate = 1;
     util_utf8_enable = 1;
-    list = string_list_init(MATCH_FLAG_RETURN, argv[optind]);
+    list = string_list_init("command line", MATCH_FLAG_RETURN, argv[optind]);
     string = argv[optind + 1];
     vstream_printf("%s: %s\n", string, string_list_match(list, string) ?
                   "YES" : list->error == 0 ? "NO" : "ERROR");
index 0a96bacfeb017bd11cb706fd1e914a6ec1840f9c..1079a7623061a2f087e9433064a9d04a2625bc36 100644 (file)
@@ -21,7 +21,8 @@
   */
 #define STRING_LIST    MATCH_LIST
 
-#define string_list_init(f, p) match_list_init((f), (p), 1, match_string)
+#define string_list_init(o, f, p) \
+                               match_list_init((o), (f), (p), 1, match_string)
 #define string_list_match      match_list_match
 #define string_list_free       match_list_free
 
index 9dd19c0f7e91dea9a988f1f745509c320bbc539e..ecdde9f15b1ee94c76e2fcf9dad43a3880cfc571 100644 (file)
@@ -6,7 +6,8 @@
 /* SYNOPSIS
 /*     #include <user_acl.h>
 /*
-/*     const char *check_user_acl_byuid(acl, uid)
+/*     const char *check_user_acl_byuid(pname, acl, uid)
+/*     cobnst char *pname;
 /*     const char *acl;
 /*     uid_t   uid;
 /* DESCRIPTION
@@ -20,6 +21,8 @@
 /*     calls.
 /*
 /*     Arguments:
+/* .IP pname
+/*     The parameter name of the acl.
 /* .IP acl
 /*     Authorized user name list suitable for input to string_list_init(3).
 /* .IP uid
@@ -59,7 +62,7 @@
 
 /* check_user_acl_byuid - check user authorization */
 
-const char *check_user_acl_byuid(char *acl, uid_t uid)
+const char *check_user_acl_byuid(const char *pname, const char *acl, uid_t uid)
 {
     struct mypasswd *mypwd;
     STRING_LIST *list;
@@ -101,7 +104,7 @@ const char *check_user_acl_byuid(char *acl, uid_t uid)
        name = mypwd->pw_name;
     }
 
-    list = string_list_init(MATCH_FLAG_NONE, acl);
+    list = string_list_init(pname, MATCH_FLAG_NONE, acl);
     if ((matched = string_list_match(list, name)) == 0) {
        if (!who)
            who = vstring_alloc(10);
index 8a9afb2b7b3e46e9ff3672eb936403e30a268243..4e36fbfcb36ec0557cfa6d954495edf6c1e944cf 100644 (file)
@@ -25,7 +25,7 @@
  /*
   * External interface
   */
-extern const char *check_user_acl_byuid(char *, uid_t);
+extern const char *check_user_acl_byuid(const char *, const char *, uid_t);
 
 /* AUTHOR(S)
 /*     Wietse Venema
index 9c435fbf58ef36015badf7fd2a6742df965d9b4d..1a4096c7c647b119a9c108c54fdefb9b7263beb5 100644 (file)
@@ -315,7 +315,8 @@ int     main(int argc, char **argv)
      * or in the daemon process?
      */
     mail_dict_init();
-    if ((errstr = check_user_acl_byuid(var_submit_acl, uid)) != 0)
+    if ((errstr = check_user_acl_byuid(VAR_SUBMIT_ACL, var_submit_acl,
+                                      uid)) != 0)
        msg_fatal("User %s(%ld) is not allowed to submit mail",
                  errstr, (long) uid);
 
index caa0e059b58118638ec1def630c65ae4c3a5b707..c90285db73119b0eb23e705bc40c51c0b34c3258 100644 (file)
@@ -270,7 +270,8 @@ static void show_queue(void)
     uid_t   uid = getuid();
 
     if (uid != 0 && uid != var_owner_uid
-       && (errstr = check_user_acl_byuid(var_showq_acl, uid)) != 0)
+       && (errstr = check_user_acl_byuid(VAR_SHOWQ_ACL, var_showq_acl,
+                                         uid)) != 0)
        msg_fatal_status(EX_NOPERM,
                       "User %s(%ld) is not allowed to view the mail queue",
                         errstr, (long) uid);
@@ -344,7 +345,8 @@ static void flush_queue(void)
     uid_t   uid = getuid();
 
     if (uid != 0 && uid != var_owner_uid
-       && (errstr = check_user_acl_byuid(var_flush_acl, uid)) != 0)
+       && (errstr = check_user_acl_byuid(VAR_FLUSH_ACL, var_flush_acl,
+                                         uid)) != 0)
        msg_fatal_status(EX_NOPERM,
                      "User %s(%ld) is not allowed to flush the mail queue",
                         errstr, (long) uid);
@@ -370,7 +372,8 @@ static void flush_site(const char *site)
     uid_t   uid = getuid();
 
     if (uid != 0 && uid != var_owner_uid
-       && (errstr = check_user_acl_byuid(var_flush_acl, uid)) != 0)
+       && (errstr = check_user_acl_byuid(VAR_FLUSH_ACL, var_flush_acl,
+                                         uid)) != 0)
        msg_fatal_status(EX_NOPERM,
                      "User %s(%ld) is not allowed to flush the mail queue",
                         errstr, (long) uid);
@@ -404,7 +407,8 @@ static void flush_file(const char *queue_id)
     uid_t   uid = getuid();
 
     if (uid != 0 && uid != var_owner_uid
-       && (errstr = check_user_acl_byuid(var_flush_acl, uid)) != 0)
+       && (errstr = check_user_acl_byuid(VAR_FLUSH_ACL, var_flush_acl,
+                                         uid)) != 0)
        msg_fatal_status(EX_NOPERM,
                      "User %s(%ld) is not allowed to flush the mail queue",
                         errstr, (long) uid);
index d7dbaaa94caed21103264df332963f17f235e1c0..e4bf8e4865473e44f004e49a367b973bff0b2d19 100644 (file)
@@ -852,7 +852,8 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
        psc_acl = psc_acl_parse(var_psc_acl, VAR_PSC_ACL);
     /* Ignore smtpd_forbid_cmds lookup errors. Non-critical feature. */
     if (*var_psc_forbid_cmds)
-       psc_forbid_cmds = string_list_init(MATCH_FLAG_RETURN,
+       psc_forbid_cmds = string_list_init(VAR_PSC_FORBID_CMDS,
+                                          MATCH_FLAG_RETURN,
                                           var_psc_forbid_cmds);
     if (*var_psc_dnsbl_reply)
        psc_dnsbl_reply = dict_open(var_psc_dnsbl_reply, O_RDONLY,
@@ -998,7 +999,8 @@ static void post_jail_init(char *unused_name, char **unused_argv)
        msg_fatal("bad %s value: %s", VAR_PSC_BARLF_ACTION,
                  var_psc_barlf_action);
     /* Fail "closed" on error. */
-    psc_wlist_if = addr_match_list_init(MATCH_FLAG_RETURN, var_psc_wlist_if);
+    psc_wlist_if = addr_match_list_init(VAR_PSC_WLIST_IF, MATCH_FLAG_RETURN,
+                                       var_psc_wlist_if);
 
     /*
      * Start the cache maintenance pseudo thread last. Early cleanup makes
index d1864ab2da851a94152a2448aa28d06c1c7f8ad3..2f1347187878a41891dd1e05931b3ee07ff0575f 100644 (file)
@@ -785,7 +785,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
 {
     debug_peer_init();
     qmqpd_clients =
-       namadr_list_init(MATCH_FLAG_RETURN
+       namadr_list_init(VAR_QMQPD_CLIENTS, MATCH_FLAG_RETURN
                         | match_parent_style(VAR_QMQPD_CLIENTS),
                         var_qmqpd_clients);
 }
index f8ce7dfdbc579f118ea02caa7a09e25852c9c534..4a91aa48e07b43a114d87e0f4e1b8d12251e4f05 100644 (file)
@@ -646,7 +646,8 @@ static void enqueue(const int flags, const char *encoding,
      * Access control is enforced in the postdrop command. The code here
      * merely produces a more user-friendly interface.
      */
-    if ((errstr = check_user_acl_byuid(var_submit_acl, uid)) != 0)
+    if ((errstr = check_user_acl_byuid(VAR_SUBMIT_ACL,
+                                      var_submit_acl, uid)) != 0)
        msg_fatal_status(EX_NOPERM,
          "User %s(%ld) is not allowed to submit mail", errstr, (long) uid);
 
@@ -1404,7 +1405,8 @@ int     main(int argc, char **argv)
            msg_fatal_status(EX_USAGE,
                             "stand-alone mode requires no recipient");
        /* The actual enforcement happens in the postdrop command. */
-       if ((errstr = check_user_acl_byuid(var_submit_acl, uid = getuid())) != 0)
+       if ((errstr = check_user_acl_byuid(VAR_SUBMIT_ACL, var_submit_acl,
+                                          uid = getuid())) != 0)
            msg_fatal_status(EX_NOPERM,
                             "User %s(%ld) is not allowed to submit mail",
                             errstr, (long) uid);
index 45961764c42685be1e4ceb15cbd55973470ef6c1..c48735876783ef740427ba0a9840463bc5b60552 100644 (file)
@@ -1186,7 +1186,9 @@ static void pre_init(char *unused_name, char **unused_argv)
      * Session cache domain list.
      */
     if (*var_smtp_cache_dest)
-       smtp_cache_dest = string_list_init(MATCH_FLAG_RETURN, var_smtp_cache_dest);
+       smtp_cache_dest = string_list_init(VAR_SMTP_CACHE_DEST,
+                                          MATCH_FLAG_RETURN,
+                                          var_smtp_cache_dest);
 
     /*
      * EHLO keyword filter.
index 09ef734c8271eb9662f39ab2809a111a1bb094c8..d2c1c3c59e9123c2b7f3a1e42e77e5c22d69c312 100644 (file)
@@ -246,7 +246,8 @@ void    smtp_sasl_initialize(void)
      * Initialize optional supported mechanism matchlist
      */
     if (*var_smtp_sasl_mechs)
-       smtp_sasl_mechs = string_list_init(MATCH_FLAG_NONE,
+       smtp_sasl_mechs = string_list_init(VAR_SMTP_SASL_MECHS,
+                                          MATCH_FLAG_NONE,
                                           var_smtp_sasl_mechs);
 
     /*
index d9312f9ddfbe13fcb2bae1205d9a900cb7ec589c..566bc3b2fbc9e5db2b915896e6e4ff86a034fb25 100644 (file)
@@ -5246,12 +5246,18 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
      * Initialize blacklist/etc. patterns before entering the chroot jail, in
      * case they specify a filename pattern.
      */
-    smtpd_noop_cmds = string_list_init(MATCH_FLAG_RETURN, var_smtpd_noop_cmds);
-    smtpd_forbid_cmds = string_list_init(MATCH_FLAG_RETURN, var_smtpd_forbid_cmds);
-    verp_clients = namadr_list_init(MATCH_FLAG_RETURN, var_verp_clients);
-    xclient_hosts = namadr_list_init(MATCH_FLAG_RETURN, var_xclient_hosts);
-    xforward_hosts = namadr_list_init(MATCH_FLAG_RETURN, var_xforward_hosts);
-    hogger_list = namadr_list_init(MATCH_FLAG_RETURN
+    smtpd_noop_cmds = string_list_init(VAR_SMTPD_NOOP_CMDS, MATCH_FLAG_RETURN,
+                                      var_smtpd_noop_cmds);
+    smtpd_forbid_cmds = string_list_init(VAR_SMTPD_FORBID_CMDS,
+                                        MATCH_FLAG_RETURN,
+                                        var_smtpd_forbid_cmds);
+    verp_clients = namadr_list_init(VAR_VERP_CLIENTS, MATCH_FLAG_RETURN,
+                                   var_verp_clients);
+    xclient_hosts = namadr_list_init(VAR_XCLIENT_HOSTS, MATCH_FLAG_RETURN,
+                                    var_xclient_hosts);
+    xforward_hosts = namadr_list_init(VAR_XFORWARD_HOSTS, MATCH_FLAG_RETURN,
+                                     var_xforward_hosts);
+    hogger_list = namadr_list_init(VAR_SMTPD_HOGGERS, MATCH_FLAG_RETURN
                                   | match_parent_style(VAR_SMTPD_HOGGERS),
                                   var_smtpd_hoggers);
 
@@ -5276,7 +5282,8 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
 
     if (*var_smtpd_sasl_exceptions_networks)
        sasl_exceptions_networks =
-           namadr_list_init(MATCH_FLAG_RETURN,
+           namadr_list_init(VAR_SMTPD_SASL_EXCEPTIONS_NETWORKS,
+                            MATCH_FLAG_RETURN,
                             var_smtpd_sasl_exceptions_networks);
 #else
        msg_warn("%s is true, but SASL support is not compiled in",
index 27de37bf2e71c0669f9726e1c6f113b55a0d1a74..5286ba86d61cbc55f120cf49af30a7515717627b 100644 (file)
@@ -706,16 +706,17 @@ void    smtpd_check_init(void)
      * Pre-open access control lists before going to jail.
      */
     mynetworks_curr =
-       namadr_list_init(MATCH_FLAG_RETURN | match_parent_style(VAR_MYNETWORKS),
-                        var_mynetworks);
+       namadr_list_init(VAR_MYNETWORKS, MATCH_FLAG_RETURN
+                     | match_parent_style(VAR_MYNETWORKS), var_mynetworks);
     mynetworks_new =
-       namadr_list_init(MATCH_FLAG_RETURN | match_parent_style(VAR_MYNETWORKS),
-                        mynetworks_host());
+       namadr_list_init(VAR_MYNETWORKS, MATCH_FLAG_RETURN
+                  | match_parent_style(VAR_MYNETWORKS), mynetworks_host());
     relay_domains =
-       domain_list_init(match_parent_style(VAR_RELAY_DOMAINS),
+       domain_list_init(VAR_RELAY_DOMAINS,
+                        match_parent_style(VAR_RELAY_DOMAINS),
                         var_relay_domains);
     perm_mx_networks =
-       namadr_list_init(MATCH_FLAG_RETURN
+       namadr_list_init(VAR_PERM_MX_NETWORKS, MATCH_FLAG_RETURN
                         | match_parent_style(VAR_PERM_MX_NETWORKS),
                         var_perm_mx_networks);
 #ifdef USE_TLS
@@ -747,8 +748,10 @@ void    smtpd_check_init(void)
                                  | DICT_FLAG_UTF8_REQUEST);
 
 #ifdef TEST
-    virt_alias_doms = string_list_init(MATCH_FLAG_NONE, var_virt_alias_doms);
-    virt_mailbox_doms = string_list_init(MATCH_FLAG_NONE, var_virt_mailbox_doms);
+    virt_alias_doms = string_list_init(VAR_VIRT_ALIAS_DOMS, MATCH_FLAG_NONE,
+                                      var_virt_alias_doms);
+    virt_mailbox_doms = string_list_init(VAR_VIRT_MAILBOX_DOMS, MATCH_FLAG_NONE,
+                                        var_virt_mailbox_doms);
 #endif
 
     access_parent_style = match_parent_style(SMTPD_ACCESS_MAPS);
@@ -889,7 +892,8 @@ void    smtpd_check_init(void)
     /*
      * Optional permit logging.
      */
-    smtpd_acl_perm_log = string_list_init(MATCH_FLAG_RETURN,
+    smtpd_acl_perm_log = string_list_init(VAR_SMTPD_ACL_PERM_LOG,
+                                         MATCH_FLAG_RETURN,
                                          var_smtpd_acl_perm_log);
 }
 
@@ -5975,9 +5979,9 @@ int     main(int argc, char **argv)
 #define UPDATE_MAPS(ptr, var, val, lock) \
        { if (ptr) maps_free(ptr); ptr = maps_create(var, val, lock); }
 
-#define UPDATE_LIST(ptr, val) \
+#define UPDATE_LIST(ptr, var, val) \
        { if (ptr) string_list_free(ptr); \
-         ptr = string_list_init(MATCH_FLAG_NONE, val); }
+         ptr = string_list_init(var, MATCH_FLAG_NONE, val); }
 
        case 2:
            if (strcasecmp(args->argv[0], VAR_MYDEST) == 0) {
@@ -5997,7 +6001,8 @@ int     main(int argc, char **argv)
            }
            if (strcasecmp(args->argv[0], VAR_VIRT_ALIAS_DOMS) == 0) {
                UPDATE_STRING(var_virt_alias_doms, args->argv[1]);
-               UPDATE_LIST(virt_alias_doms, var_virt_alias_doms);
+               UPDATE_LIST(virt_alias_doms, VAR_VIRT_ALIAS_DOMS,
+                           var_virt_alias_doms);
                smtpd_resolve_init(100);
                resp = 0;
                break;
@@ -6012,7 +6017,8 @@ int     main(int argc, char **argv)
            }
            if (strcasecmp(args->argv[0], VAR_VIRT_MAILBOX_DOMS) == 0) {
                UPDATE_STRING(var_virt_mailbox_doms, args->argv[1]);
-               UPDATE_LIST(virt_mailbox_doms, var_virt_mailbox_doms);
+               UPDATE_LIST(virt_mailbox_doms, VAR_VIRT_MAILBOX_DOMS,
+                           var_virt_mailbox_doms);
                smtpd_resolve_init(100);
                resp = 0;
                break;
@@ -6053,7 +6059,7 @@ int     main(int argc, char **argv)
                /* NOT: UPDATE_STRING */
                namadr_list_free(mynetworks_curr);
                mynetworks_curr =
-                   namadr_list_init(MATCH_FLAG_RETURN
+                   namadr_list_init(VAR_MYNETWORKS, MATCH_FLAG_RETURN
                                     | match_parent_style(VAR_MYNETWORKS),
                                     args->argv[1]);
                smtpd_resolve_init(100);
@@ -6064,7 +6070,8 @@ int     main(int argc, char **argv)
                /* NOT: UPDATE_STRING */
                domain_list_free(relay_domains);
                relay_domains =
-                   domain_list_init(match_parent_style(VAR_RELAY_DOMAINS),
+                   domain_list_init(VAR_RELAY_DOMAINS,
+                                    match_parent_style(VAR_RELAY_DOMAINS),
                                     args->argv[1]);
                smtpd_resolve_init(100);
                resp = 0;
@@ -6074,7 +6081,7 @@ int     main(int argc, char **argv)
                UPDATE_STRING(var_perm_mx_networks, args->argv[1]);
                domain_list_free(perm_mx_networks);
                perm_mx_networks =
-                   namadr_list_init(MATCH_FLAG_RETURN
+                   namadr_list_init(VAR_PERM_MX_NETWORKS, MATCH_FLAG_RETURN
                                 | match_parent_style(VAR_PERM_MX_NETWORKS),
                                     args->argv[1]);
                resp = 0;
index 2316ac54ac248a236c3dc423999c06becf30dfe2..0f2e2fac3024c269f0c3e8382147fa160dcf71bd 100644 (file)
@@ -57,7 +57,7 @@ OK
 >>> recipient_restrictions permit_mynetworks
 OK
 >>> rcpt reject@dunno.domain
-./smtpd_check: warning: fail:1_mynetworks: table lookup problem
+./smtpd_check: warning: mynetworks: fail:1_mynetworks: table lookup problem
 ./smtpd_check: <queue id>: reject: RCPT from foo.dunno.com[131.155.210.17]: 451 4.3.0 <reject@dunno.domain>: Temporary lookup failure; from=<reject@dunno.domain> to=<reject@dunno.domain> proto=SMTP helo=<foobar>
 451 4.3.0 <reject@dunno.domain>: Temporary lookup failure
 >>> # 
@@ -69,7 +69,7 @@ OK
 >>> # Expect REJECT (server configuration error)
 >>> #
 >>> rcpt reject@dunno.domain
-./smtpd_check: warning: non-null host address bits in "168.100.189.1/27", perhaps you should use "168.100.189.0/27" instead
+./smtpd_check: warning: mynetworks: non-null host address bits in "168.100.189.1/27", perhaps you should use "168.100.189.0/27" instead
 ./smtpd_check: <queue id>: reject: RCPT from foo.dunno.com[131.155.210.17]: 451 4.3.0 <reject@dunno.domain>: Temporary lookup failure; from=<reject@dunno.domain> to=<reject@dunno.domain> proto=SMTP helo=<foobar>
 451 4.3.0 <reject@dunno.domain>: Temporary lookup failure
 >>> #
@@ -119,7 +119,7 @@ OK
 >>> mydestination fail:1_mydestination
 OK
 >>> rcpt user@example.com
-./smtpd_check: warning: fail:1_mydestination: table lookup problem
+./smtpd_check: warning: mydestination: fail:1_mydestination: table lookup problem
 ./smtpd_check: <queue id>: reject: RCPT from foo.dunno.com[131.155.210.17]: 451 4.3.0 <user@example.com>: Temporary lookup failure; from=<> to=<user@example.com> proto=SMTP helo=<foobar>
 451 4.3.0 <user@example.com>: Temporary lookup failure
 >>> #
index 5291b121649675f4fdeb90d116a2316c0ace7919..f7c5a6a6370487a6ff484ea5dc50165ebe6e6947 100644 (file)
@@ -795,15 +795,17 @@ void    resolve_init(void)
 
     if (*var_virt_alias_doms)
        virt_alias_doms =
-           string_list_init(MATCH_FLAG_RETURN, var_virt_alias_doms);
+           string_list_init(VAR_VIRT_ALIAS_DOMS, MATCH_FLAG_RETURN,
+                            var_virt_alias_doms);
 
     if (*var_virt_mailbox_doms)
        virt_mailbox_doms =
-           string_list_init(MATCH_FLAG_RETURN, var_virt_mailbox_doms);
+           string_list_init(VAR_VIRT_MAILBOX_DOMS, MATCH_FLAG_RETURN,
+                            var_virt_mailbox_doms);
 
     if (*var_relay_domains)
        relay_domains =
-           domain_list_init(MATCH_FLAG_RETURN
+           domain_list_init(VAR_RELAY_DOMAINS, MATCH_FLAG_RETURN
                             | match_parent_style(VAR_RELAY_DOMAINS),
                             var_relay_domains);
 
index 99acf757220f55c926eaf5c31599ef902a07a23a..072c14e3b97f11835d84692c64694ff588a765ee 100644 (file)
@@ -31,7 +31,8 @@
 /*
 /*     Arguments:
 /* .IP utf8_request
-/*     Perform UTF-8 case folding.
+/*     Boolean parameter that enables UTF-8 case folding. This is
+/*     ignored when compiled without EAI support.
 /* .IP src
 /*     Null-terminated input string.
 /* .IP dest
@@ -78,7 +79,7 @@ char   *casefold(int utf8_req, VSTRING *dest, const char *src,
 #ifdef NO_EAI
 
     /*
-     * ASCII mode only
+     * ASCII mode only.
      */
     vstring_strcpy(dest, src);
     return (lowercase(STR(dest)));
@@ -93,13 +94,24 @@ char   *casefold(int utf8_req, VSTRING *dest, const char *src,
     int     n;
 
     /*
-     * All-ASCII input.
+     * All-ASCII input, or ASCII mode only.
      */
     if (utf8_req == 0 || allascii(src)) {
        vstring_strcpy(dest, src);
        return (lowercase(STR(dest)));
     }
 
+    /*
+     * ICU 4.8 ucasemap_utf8FoldCase() does not complain about UTF-8 syntax
+     * errors. XXX Is this behavior guaranteed or accidental? We don't know,
+     * therefore must check it here.
+     */
+    if (valid_utf8_string(src, strlen(src)) == 0) {
+       if (err)
+           *err = "malformed UTF-8 or invalid codepoint";
+       return (0);
+    }
+
     /*
      * One-time initialization. With ICU 4.8 this works while chrooted.
      */
@@ -130,7 +142,9 @@ char   *casefold(int utf8_req, VSTRING *dest, const char *src,
     /*
      * Report the result. With ICU 4.8, there are no casefolding errors for
      * the entire RFC 3629 Unicode range (code points U+0000..U+10FFFF
-     * including surrogates).
+     * including surrogates), nor are there casefolding errors for bad UTF-8
+     * input. XXX Is this behavior guaranteed or accidental? We don't know,
+     * therefore we have the UTF-8 syntax check (and range check) above.
      */
     if (U_SUCCESS(error) == 0) {
        if (err)
@@ -200,7 +214,7 @@ int     main(int argc, char **argv)
 
     while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
        bp = STR(buffer);
-       msg_info("> %s", bp);
+       vstream_printf("> %s\n", bp);
        cmd = mystrtok(&bp, CHARS_SPACE);
        if (cmd == 0 || *cmd == '#')
            continue;
@@ -212,9 +226,9 @@ int     main(int argc, char **argv)
         */
        if (strcmp(cmd, "fold") == 0) {
            if ((conv_res = casefold(utf8_req, dest, bp, &fold_err)) != 0)
-               msg_info("\"%s\" ->fold \"%s\"", bp, conv_res);
+               vstream_printf("\"%s\" ->fold \"%s\"\n", bp, conv_res);
            else
-               msg_warn("cannot casefold \"%s\": %s", bp, fold_err);
+               vstream_printf("cannot casefold \"%s\": %s\n", bp, fold_err);
        }
 
        /*
@@ -225,20 +239,20 @@ int     main(int argc, char **argv)
                 && first <= last) {
            for (codepoint = first; codepoint <= last; codepoint++) {
                if (codepoint >= 0xD800 && codepoint <= 0xDFFF) {
-                   msg_warn("skipping surrogate range");
+                   vstream_printf("skipping surrogate range\n");
                    codepoint = 0xDFFF;
                } else {
                    encode_utf8(buffer, codepoint);
                    if (msg_verbose)
-                       msg_info("U+%X -> %s", codepoint, STR(buffer));
+                       vstream_printf("U+%X -> %s\n", codepoint, STR(buffer));
                    if (valid_utf8_string(STR(buffer), LEN(buffer)) == 0)
-                       msg_fatal("bad utf-8 encoding for U+%X", codepoint);
+                       msg_fatal("bad utf-8 encoding for U+%X\n", codepoint);
                    if (casefold(utf8_req, dest, STR(buffer), &fold_err) == 0)
-                       msg_warn("casefold error for U+%X: %s",
-                                codepoint, fold_err);
+                       vstream_printf("casefold error for U+%X: %s\n",
+                                      codepoint, fold_err);
                }
            }
-           msg_info("range completed: 0x%x..0x%x", first, last);
+           vstream_printf("range completed: 0x%x..0x%x\n", first, last);
        }
 
        /*
@@ -248,10 +262,10 @@ int     main(int argc, char **argv)
                 && sscanf(bp, "%255s", STR(buffer)) == 1) {
            if (geteuid() == 0) {
                if (chdir(STR(buffer)) < 0)
-                   msg_fatal("chdir(%s): %m", STR(buffer));
+                   msg_fatal("chdir(%s): %m\n", STR(buffer));
                if (chroot(STR(buffer)) < 0)
-                   msg_fatal("chroot(%s): %m", STR(buffer));
-               msg_info("chroot %s completed", STR(buffer));
+                   msg_fatal("chroot(%s): %m\n", STR(buffer));
+               vstream_printf("chroot %s completed\n", STR(buffer));
            }
        }
 
@@ -267,9 +281,10 @@ int     main(int argc, char **argv)
         * Usage
         */
        else {
-           msg_info("Usage: %s chroot <path> | fold <text> | range <first> <last> | verbose <int>",
-                    argv[0]);
+           vstream_printf("Usage: %s chroot <path> | fold <text> | range <first> <last> | verbose <int>\n",
+                          argv[0]);
        }
+       vstream_fflush(VSTREAM_OUT);
     }
     exit(0);
 }
index f1a0098fdb48ab8cd481dfea3949f04a3eb1ae2b..9b50e22e2b83b787ba66c429453368cab1d9507f 100644 (file)
@@ -17,3 +17,6 @@ fold HeLlO.ExAmPlE.CoM
 fold x。example.com
 fold x.example.com
 fold x。example.com
+# Bad UTF-8
+fold yyy\80\80\80
+fold \80\80\80xxx
index 18c6b6c54e190e626b7b860c781355b051b0ff58..00d6f8d1f45c64b0ddfa9cd4835b472030f5ac12 100644 (file)
@@ -1,39 +1,44 @@
-./casefold: > # Ignored when not running as root.
-./casefold: > chroot /tmp
-./casefold: > # Casefold U+0000 .. U+10FFFF excluding surrogates.
-./casefold: > range 0x0 0xD7FF
-./casefold: range completed: 0x0..0xd7ff
-./casefold: > range 0xD800 0xD800
-./casefold: warning: skipping surrogate range
-./casefold: range completed: 0xd800..0xd800
-./casefold: > range 0xDFFF 0xDFFF
-./casefold: warning: skipping surrogate range
-./casefold: range completed: 0xdfff..0xdfff
-./casefold: > range 0xE000 0x10FFFF
-./casefold: range completed: 0xe000..0x10ffff
-./casefold: > # Demonstrate that range is not a noop.
-./casefold: > verbose 1
-./casefold: > range 0xE000 0xE007
-./casefold: U+E000 -> 
-./casefold: U+E001 -> 
-./casefold: U+E002 -> 
-./casefold: U+E003 -> 
-./casefold: U+E004 -> 
-./casefold: U+E005 -> 
-./casefold: U+E006 -> 
-./casefold: U+E007 -> 
-./casefold: range completed: 0xe000..0xe007
-./casefold: > verbose 0
-./casefold: > # Upper-case greek -> lower-case greek.
-./casefold: > fold Δημοσθένους.example.com
-./casefold: "Δημοσθένους.example.com" ->fold "δημοσθένουσ.example.com"
-./casefold: > # Upper-case ASCII -> lower-case ASCII.
-./casefold: > fold HeLlO.ExAmPlE.CoM
-./casefold: "HeLlO.ExAmPlE.CoM" ->fold "hello.example.com"
-./casefold: > # Folding does not change aliases for '.'.
-./casefold: > fold x。example.com
-./casefold: "x。example.com" ->fold "x。example.com"
-./casefold: > fold x.example.com
-./casefold: "x.example.com" ->fold "x.example.com"
-./casefold: > fold x。example.com
-./casefold: "x。example.com" ->fold "x。example.com"
+> # Ignored when not running as root.
+> chroot /tmp
+> # Casefold U+0000 .. U+10FFFF excluding surrogates.
+> range 0x0 0xD7FF
+range completed: 0x0..0xd7ff
+> range 0xD800 0xD800
+skipping surrogate range
+range completed: 0xd800..0xd800
+> range 0xDFFF 0xDFFF
+skipping surrogate range
+range completed: 0xdfff..0xdfff
+> range 0xE000 0x10FFFF
+range completed: 0xe000..0x10ffff
+> # Demonstrate that range is not a noop.
+> verbose 1
+> range 0xE000 0xE007
+U+E000 -> 
+U+E001 -> 
+U+E002 -> 
+U+E003 -> 
+U+E004 -> 
+U+E005 -> 
+U+E006 -> 
+U+E007 -> 
+range completed: 0xe000..0xe007
+> verbose 0
+> # Upper-case greek -> lower-case greek.
+> fold Δημοσθένους.example.com
+"Δημοσθένους.example.com" ->fold "δημοσθένουσ.example.com"
+> # Upper-case ASCII -> lower-case ASCII.
+> fold HeLlO.ExAmPlE.CoM
+"HeLlO.ExAmPlE.CoM" ->fold "hello.example.com"
+> # Folding does not change aliases for '.'.
+> fold x。example.com
+"x。example.com" ->fold "x。example.com"
+> fold x.example.com
+"x.example.com" ->fold "x.example.com"
+> fold x。example.com
+"x。example.com" ->fold "x。example.com"
+> # Bad UTF-8
+> fold yyy\80\80\80
+cannot casefold "yyy\80\80\80": malformed UTF-8 or invalid codepoint
+> fold \80\80\80xxx
+cannot casefold "\80\80\80xxx": malformed UTF-8 or invalid codepoint
index 9a6c7b68d9bc8c8b3895fd5d8ee2224117caa801..17fe06131f2961bdc9d4bc0c3bf4311a6260945c 100644 (file)
@@ -8,7 +8,7 @@
 /*
 /*     DICT    *dict_utf8_activate(
 /*     DICT    *dict)
-/*
+/* AUXILIARY FUNCTIONS
 /*     char    *dict_utf8_check_fold(
 /*     DICT    *dict,
 /*     const char *string,
@@ -29,9 +29,9 @@
 /*     paths in application code).  Attempts to store non-UTF-8
 /*     keys or values are skipped while reporting a non-error
 /*     status, attempts to look up or delete non-UTF-8 keys are
-/*     skipped while reporting a non-error status, and attempts
-/*     to look up a non-UTF-8 value are flagged while reporting a
-/*     configuration error.
+/*     skipped while reporting a non-error status, and lookup
+/*     results that contain a non-UTF-8 value are blocked while
+/*     reporting a configuration error.
 /*
 /*     The dict_utf8_check* functions may be invoked to perform
 /*     UTF-8 validity checks when util_utf8_enable is non-zero.
index f0a3f90ab8bc67781ea1aac83955c45e35f32a7f..36ee0902ad73369acc06c6c30253a2322f737952 100644 (file)
@@ -6,7 +6,8 @@
 /* SYNOPSIS
 /*     #include <match_list.h>
 /*
-/*     MATCH_LIST *match_list_init(flags, pattern_list, count, func,...)
+/*     MATCH_LIST *match_list_init(pname, flags, pattern_list, count, func,...)
+/*     const char *pname;
 /*     int     flags;
 /*     const char *pattern_list;
 /*     int     count;
 /*     void match_list_free(list)
 /*     MATCH_LIST *list;
 /* DESCRIPTION
-/*     This module implements a framework for tests for list membership.
-/*     The actual tests are done by user-supplied functions. With
-/*     util_utf8_enable non-zero, string comparison supports UTF-8.
+/*     This module implements a framework for tests for list
+/*     membership.  The actual tests are done by user-supplied
+/*     functions.
 /*
 /*     Patterns are separated by whitespace and/or commas. A pattern
 /*     is either a string, a file name (in which case the contents
 /*     of the file are substituted for the file name) or a type:name
-/*     lookup table specification. In order to reverse the result of
-/*     a pattern match, precede a pattern with an exclamation point (!).
+/*     lookup table specification. In order to reverse the result
+/*     of a pattern match, precede a pattern with an exclamation
+/*     point (!).
 /*
-/*     match_list_init() performs initializations. The flags argument
-/*     specifies the bit-wise OR of zero or more of the following:
+/*     match_list_init() performs initializations.  When the global
+/*     util_utf8_enable variable is non-zero, and when the code
+/*     is compiled with EAI support, string comparison will use
+/*     caseless UTF-8 mode.  Otherwise, only ASCII characters will
+/*     be casefolded.
+/*
+/*     match_list_match() matches strings against the specified
+/*     pattern list, passing the first string to the first function
+/*     given to match_list_init(), the second string to the second
+/*     function, and so on.
+/*
+/*     match_list_free() releases storage allocated by match_list_init().
+/*
+/*     Arguments:
+/* .IP pname
+/*     Parameter name or other identiying information that is
+/*     prepended to error messages.
+/* .IP flags
+/*     Specifies the bit-wise OR of zero or more of the following:
 /* .RS
 /* .IP MATCH_FLAG_PARENT
-/*     The hostname pattern foo.com matches any name within the domain
-/*     foo.com. If this flag is cleared, foo.com matches itself
-/*     only, and .foo.com matches any name below the domain foo.com.
+/*     The hostname pattern foo.com matches any name within the
+/*     domain foo.com. If this flag is cleared, foo.com matches
+/*     itself only, and .foo.com matches any name below the domain
+/*     foo.com.
 /* .IP MATCH_FLAG_RETURN
 /*     Request that match_list_match() logs a warning and returns
 /*     zero (with list->error set to a non-zero dictionary error
 /*     code) instead of raising a fatal run-time error.
 /* .RE
 /*     Specify MATCH_FLAG_NONE to request none of the above.
-/*     The pattern_list argument specifies a list of patterns.  The third
-/*     argument specifies how many match functions follow.
-/*
-/*     match_list_match() matches strings against the specified pattern
-/*     list, passing the first string to the first function given to
-/*     match_list_init(), the second string to the second function, and
-/*     so on.
-/*
-/*     match_list_free() releases storage allocated by match_list_init().
+/* .IP pattern_list
+/*     A list of patterns.
+/* .IP count
+/*     Specifies how many match functions follow.
+/* .IP list
+/*     Pattern list produced by match_list_init().
+/* .IP string
+/*     Search string.
 /* DIAGNOSTICS
 /*     Fatal error: unable to open or read a match_list file; invalid
-/*     match_list pattern.
+/*     match_list pattern; casefold error (UTF-8 mode only).
 /* SEE ALSO
 /*     host_match(3) match hosts by name or by address
 /* LICENSE
@@ -110,9 +129,11 @@ static ARGV *match_list_parse(MATCH_LIST *match_list, ARGV *pat_list,
     const char *utf8_err;
 
     /*
-     * No DICT_FLAG_FOLD_FIX here, because we casefold the search string at
-     * the beginning of a search. String constant patterns are casefolded
-     * during match_list initialization.
+     * We do not use DICT_FLAG_FOLD_FIX, because we casefold the search
+     * string at the beginning of a search, and we use strcmp() for string
+     * comparison. This works because string patterns are casefolded during
+     * match_list initialization, and databases are supposed to fold case
+     * upon creation.
      */
 #define OPEN_FLAGS     O_RDONLY
 #define DICT_FLAGS     (DICT_FLAG_LOCK | DICT_FLAG_UTF8_REQUEST)
@@ -128,15 +149,17 @@ static ARGV *match_list_parse(MATCH_LIST *match_list, ARGV *pat_list,
     while ((start = mystrtokq(&bp, delim, CHARS_BRACE)) != 0) {
        if (*start == '#') {
            msg_warn("%s: comment at end of line is not supported: %s %s",
-                    myname, start, bp);
+                    match_list->pname, start, bp);
            break;
        }
        for (match = init_match, item = start; *item == '!'; item++)
            match = !match;
        if (*item == 0)
-           msg_fatal("%s: no pattern after '!'", myname);
+           /* No graceful degradation for this... */
+           msg_fatal("%s: no pattern after '!'", match_list->pname);
        if (*item == '/') {                     /* /file/name */
            if ((fp = vstream_fopen(item, O_RDONLY, 0)) == 0) {
+               /* Replace unusable pattern with pseudo table. */
                vstring_sprintf(buf, "%s:%s", DICT_TYPE_NOFILE, item);
                if (dict_handle(STR(buf)) == 0)
                    dict_register(STR(buf),
@@ -164,11 +187,12 @@ static ARGV *match_list_parse(MATCH_LIST *match_list, ARGV *pat_list,
            if (casefold(util_utf8_enable, match_list->fold_buf, match ?
                         item : STR(vstring_sprintf(buf, "!%s", item)),
                         &utf8_err) == 0) {
+               /* Replace unusable pattern with pseudo table. */
                vstring_sprintf(match_list->fold_buf, "%s:%s",
                                DICT_TYPE_NOUTF8, item);
                if (dict_handle(STR(match_list->fold_buf)) == 0)
                    dict_register(STR(match_list->fold_buf),
-                                 dict_surrogate(DICT_TYPE_NOFILE, item,
+                                 dict_surrogate(DICT_TYPE_NOUTF8, item,
                                                 OPEN_FLAGS, DICT_FLAGS,
                                                 "casefold error: %s",
                                                 utf8_err));
@@ -182,7 +206,8 @@ static ARGV *match_list_parse(MATCH_LIST *match_list, ARGV *pat_list,
 
 /* match_list_init - initialize pattern list */
 
-MATCH_LIST *match_list_init(int flags, const char *patterns, int match_count,...)
+MATCH_LIST *match_list_init(const char *pname, int flags,
+                                 const char *patterns, int match_count,...)
 {
     MATCH_LIST *list;
     char   *saved_patterns;
@@ -193,6 +218,7 @@ MATCH_LIST *match_list_init(int flags, const char *patterns, int match_count,...
        msg_panic("match_list_init: bad flags 0x%x", flags);
 
     list = (MATCH_LIST *) mymalloc(sizeof(*list));
+    list->pname = mystrdup(pname);
     list->flags = flags;
     list->match_count = match_count;
     list->match_func =
@@ -264,6 +290,7 @@ int     match_list_match(MATCH_LIST *list,...)
 void    match_list_free(MATCH_LIST *list)
 {
     /* XXX Should decrement map refcounts. */
+    myfree(list->pname);
     argv_free(list->patterns);
     myfree((void *) list->match_func);
     myfree((void *) list->match_args);
index c08475cd3c670ee6ff413356de2a56c8869cb695..d8b779430dc6013b1890d57ec8d3ba644c557fa7 100644 (file)
@@ -25,6 +25,7 @@ typedef struct MATCH_LIST MATCH_LIST;
 typedef int (*MATCH_LIST_FN) (MATCH_LIST *, const char *, const char *);
 
 struct MATCH_LIST {
+    char   *pname;                     /* used in error messages */
     int     flags;                     /* processing options */
     ARGV   *patterns;                  /* one pattern each */
     int     match_count;               /* match function/argument count */
@@ -39,7 +40,7 @@ struct MATCH_LIST {
 #define MATCH_FLAG_RETURN      (1<<1)
 #define MATCH_FLAG_ALL         (MATCH_FLAG_PARENT | MATCH_FLAG_RETURN)
 
-extern MATCH_LIST *match_list_init(int, const char *, int,...);
+extern MATCH_LIST *match_list_init(const char *, int, const char *, int,...);
 extern int match_list_match(MATCH_LIST *,...);
 extern void match_list_free(MATCH_LIST *);
 
@@ -63,4 +64,3 @@ extern int match_hostaddr(MATCH_LIST *, const char *, const char *);
 /*--*/
 
 #endif
-
index f49b13865a6868ecce5ba35efd429e0eb2d24989..6542f49106a1a4c1fbc5168d339b6425d82a2254 100644 (file)
@@ -99,9 +99,9 @@ static int match_error(MATCH_LIST *list, const char *fmt,...)
     vstring_vsprintf(buf, fmt, ap);
     va_end(ap);
     if (list->flags & MATCH_FLAG_RETURN) {
-       msg_warn("%s", vstring_str(buf));
+       msg_warn("%s: %s", list->pname, vstring_str(buf));
     } else {
-       msg_fatal("%s", vstring_str(buf));
+       msg_fatal("%s: %s", list->pname, vstring_str(buf));
     }
     vstring_free(buf);
     return (0);
@@ -115,7 +115,7 @@ int     match_string(MATCH_LIST *list, const char *string, const char *pattern)
     DICT   *dict;
 
     if (msg_verbose)
-       msg_info("%s: %s ~? %s", myname, string, pattern);
+       msg_info("%s: %s: %s ~? %s", myname, list->pname, string, pattern);
 
     /*
      * Try dictionary lookup: exact match.
@@ -157,7 +157,7 @@ int     match_hostname(MATCH_LIST *list, const char *name, const char *pattern)
     DICT   *dict;
 
     if (msg_verbose)
-       msg_info("%s: %s ~? %s", myname, name, pattern);
+       msg_info("%s: %s: %s ~? %s", myname, list->pname, name, pattern);
 
     /*
      * Try dictionary lookup: exact match and parent domains.
@@ -172,9 +172,9 @@ int     match_hostname(MATCH_LIST *list, const char *name, const char *pattern)
            if (entry == name || (dict->flags & DICT_FLAG_FIXED)) {
                match = (dict_get(dict, entry) != 0);
                if (msg_verbose > 1)
-                   msg_info("%s: lookup %s:%s %s: %s",
-                            myname, dict->type, dict->name, entry,
-                            match ? "found" : "notfound");
+                   msg_info("%s: %s: lookup %s:%s %s: %s",
+                            myname, list->pname, dict->type, dict->name,
+                            entry, match ? "found" : "notfound");
                if (match != 0)
                    break;
                if ((list->error = dict->error) != 0)
@@ -227,7 +227,7 @@ int     match_hostaddr(MATCH_LIST *list, const char *addr, const char *pattern)
     int     rc;
 
     if (msg_verbose)
-       msg_info("%s: %s ~? %s", myname, addr, pattern);
+       msg_info("%s: %s: %s ~? %s", myname, list->pname, addr, pattern);
 
 #define V4_ADDR_STRING_CHARS   "01234567890."
 #define V6_ADDR_STRING_CHARS   V4_ADDR_STRING_CHARS "abcdefABCDEF:"
index ff2ac63b32560fab6e70e1af1694ea2abfa784d4..a37ff6306410478105b3416ed31b6407cd69978d 100644 (file)
@@ -16,7 +16,7 @@
 /*     in its input with the given replacement.
 /*
 /*     util_utf8_enable controls whether UTF8 is considered printable.
-/*     By default, non-ASCII text is replaced.
+/*     With util_utf8_enable equal to zero, non-ASCII text is replaced.
 /*
 /*     Arguments:
 /* .IP buffer