]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.9-20111222
authorWietse Venema <wietse@porcupine.org>
Thu, 22 Dec 2011 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:37:49 +0000 (06:37 +0000)
33 files changed:
postfix/HISTORY
postfix/README_FILES/SASL_README
postfix/html/SASL_README.html
postfix/proto/SASL_README.html
postfix/src/flush/flush.c
postfix/src/global/Makefile.in
postfix/src/global/addr_match_list.c
postfix/src/global/debug_peer.c
postfix/src/global/domain_list.c
postfix/src/global/flush_clnt.c
postfix/src/global/mail_version.h
postfix/src/global/maps.c
postfix/src/global/maps.in [new file with mode: 0644]
postfix/src/global/maps.ref [new file with mode: 0644]
postfix/src/global/namadr_list.c
postfix/src/global/resolve_local.c
postfix/src/global/resolve_local.h
postfix/src/global/resolve_local.in [new file with mode: 0644]
postfix/src/global/resolve_local.ref [new file with mode: 0644]
postfix/src/global/server_acl.c
postfix/src/global/string_list.c
postfix/src/qmqpd/qmqpd.c
postfix/src/smtpd/Makefile.in
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpd/smtpd_error.in
postfix/src/smtpd/smtpd_error.ref
postfix/src/trivial-rewrite/resolve.c
postfix/src/util/cidr_match.c
postfix/src/util/dict.h
postfix/src/util/match_list.c
postfix/src/util/match_ops.c
postfix/src/util/match_ops.h
postfix/src/util/name_mask.c

index e68ebd443cadd152ced9357df280f917145dd010..14141d6ed3e784e95e27025e13f6a1ef58431ca1 100644 (file)
@@ -17416,5 +17416,18 @@ Apologies for any names omitted.
        errors with opening a database.  Files: smtpd/smtpd.c,
        smtpd/smtpd_checks.c, smtpd/smtpd_error.in, smtpd/smtpd_error.ref.
 
-       Cleanup: memory leak testing of error handling. Files:
-       util/name_mask.c, util/cidr_mask.c.
+       Cleanup: memory leak testing of error handling. File:
+       util/name_mask.c.
+
+20111222
+
+       Cleanup: memory leak testing of error handling. File:
+        util/name_mask.c.
+
+       Cleanup: simplified the match_list error reporting, thereby
+       reducing the footprint of the changes to "catch" errors
+       with implicit database lookups in mynetworks, and other
+       lists.  Files: util/match_ops.[hc], util/match_list.c,
+       global/addr_list_match.c, domain_list.c, string_list.c,
+       namadr_list.c, trivial-rewrite/resolve.c, smtpd/smtpd.c,
+       smtpd/smtpd_check.c, global/flush_clnt.c, flush/flush.c.
index 349d3655a06e14cc5dd0f588a883f4ea26eda6bf..282edc1d494cfc3d6c1d8d917077020c084b1b69 100644 (file)
@@ -14,7 +14,7 @@ H\bHo\bow\bw P\bPo\bos\bst\btf\bfi\bix\bx u\bus\bse\bes\bs S\bSA\bAS\bSL\bL a\bau\but\bth\bhe\ben\bnt\bti
 
 SMTP servers need to decide whether an SMTP client is authorized to send mail
 to remote destinations, or only to destinations that the server itself is
-responsible for. Usually, SMTP servers allow mail to remote destinations when
+responsible for. Usually, SMTP servers accept mail to remote destinations when
 the client's IP address is in the "same network" as the server's IP address.
 
 SMTP clients outside the SMTP server's network need a different way to get
index c73dcecbf43888dc0720e7b61e9f2460fce0d9ea..f76ca860f0dbadadf5069dbfb7afced09d16de43 100644 (file)
@@ -28,7 +28,7 @@ considering. </p>
 
 <p> SMTP servers need to decide whether an SMTP client is authorized
 to send mail to remote destinations, or only to destinations that
-the server itself is responsible for.  Usually, SMTP servers allow
+the server itself is responsible for.  Usually, SMTP servers accept
 mail to remote destinations when the client's IP address is in the
 "same network" as the server's IP address.  </p>
 
index 1e685eba4d4ce70cfd9aaf341224515d6774cc2d..a3320be86e6e755e6c9d16a06f330e8eb43117a3 100644 (file)
@@ -28,7 +28,7 @@ considering. </p>
 
 <p> SMTP servers need to decide whether an SMTP client is authorized
 to send mail to remote destinations, or only to destinations that
-the server itself is responsible for.  Usually, SMTP servers allow
+the server itself is responsible for.  Usually, SMTP servers accept
 mail to remote destinations when the client's IP address is in the
 "same network" as the server's IP address.  </p>
 
index a87a0f18c664a55050fd73e0c5afa3d6f933abd3..9f2c5dbdb9ba40f063d2c2c371f9ef644b88356a 100644 (file)
@@ -280,7 +280,7 @@ static VSTRING *flush_site_to_path(VSTRING *path, const char *site)
 
 static int flush_policy_ok(const char *site)
 {
-    return (domain_list_match(flush_domains, site) > 0);
+    return (domain_list_match(flush_domains, site));
 }
 
 /* flush_add_service - append queue ID to per-site fast flush logfile */
index 379d0e50fff77cd1b8c13a14858e2f1561e5ec0a..6a4ee997eaf1ea11df4fdc930373115e33817ddb 100644 (file)
@@ -308,7 +308,7 @@ server_acl: server_acl.c $(LIB) $(LIBS)
 tests: tok822_test mime_tests strip_addr_test tok822_limit_test \
        xtext_test scache_multi_test ehlo_mask_test \
        namadr_list_test mail_conf_time_test header_body_checks_tests \
-       mail_version_test server_acl_test
+       mail_version_test server_acl_test resolve_local_test maps_test
 
 mime_tests: mime_test mime_nest mime_8bit mime_dom mime_trunc mime_cvt \
        mime_cvt2 mime_cvt3 mime_garb1 mime_garb2 mime_garb3 mime_garb4
@@ -410,6 +410,16 @@ server_acl_test: server_acl server_acl.in server_acl.ref
        diff  server_acl.ref server_acl.tmp
        rm -f server_acl.tmp
 
+resolve_local_test: resolve_local resolve_local.in resolve_local.ref
+       sh resolve_local.in >resolve_local.tmp 2>&1
+       diff  resolve_local.ref resolve_local.tmp
+       rm -f resolve_local.tmp
+
+maps_test: maps maps.in maps.ref
+       sh maps.in >maps.tmp 2>&1
+       diff  maps.ref maps.tmp
+       rm -f maps.tmp
+
 # Requires: Postfix running, root privileges
 
 rewrite_clnt_test: rewrite_clnt rewrite_clnt.in rewrite_clnt.ref
@@ -585,9 +595,14 @@ abounce.o: mail_params.h
 abounce.o: mail_proto.h
 abounce.o: msg_stats.h
 abounce.o: recipient_list.h
+addr_match_list.o: ../../include/argv.h
+addr_match_list.o: ../../include/dict.h
 addr_match_list.o: ../../include/match_list.h
 addr_match_list.o: ../../include/match_ops.h
 addr_match_list.o: ../../include/sys_defs.h
+addr_match_list.o: ../../include/vbuf.h
+addr_match_list.o: ../../include/vstream.h
+addr_match_list.o: ../../include/vstring.h
 addr_match_list.o: addr_match_list.c
 addr_match_list.o: addr_match_list.h
 anvil_clnt.o: ../../include/attr.h
@@ -738,10 +753,15 @@ db_common.o: cfg_parser.h
 db_common.o: db_common.c
 db_common.o: db_common.h
 db_common.o: string_list.h
+debug_peer.o: ../../include/argv.h
+debug_peer.o: ../../include/dict.h
 debug_peer.o: ../../include/match_list.h
 debug_peer.o: ../../include/match_ops.h
 debug_peer.o: ../../include/msg.h
 debug_peer.o: ../../include/sys_defs.h
+debug_peer.o: ../../include/vbuf.h
+debug_peer.o: ../../include/vstream.h
+debug_peer.o: ../../include/vstring.h
 debug_peer.o: debug_peer.c
 debug_peer.o: debug_peer.h
 debug_peer.o: mail_params.h
@@ -963,9 +983,15 @@ dict_sqlite.o: db_common.h
 dict_sqlite.o: dict_sqlite.c
 dict_sqlite.o: dict_sqlite.h
 dict_sqlite.o: string_list.h
+domain_list.cdebug_peer.o: domain_list.cdebug_peer.c
+domain_list.o: ../../include/argv.h
+domain_list.o: ../../include/dict.h
 domain_list.o: ../../include/match_list.h
 domain_list.o: ../../include/match_ops.h
 domain_list.o: ../../include/sys_defs.h
+domain_list.o: ../../include/vbuf.h
+domain_list.o: ../../include/vstream.h
+domain_list.o: ../../include/vstring.h
 domain_list.o: domain_list.c
 domain_list.o: domain_list.h
 dot_lockfile.o: ../../include/iostuff.h
@@ -1056,7 +1082,9 @@ file_id.o: file_id.c
 file_id.o: file_id.h
 file_id.o: mail_queue.h
 file_id.o: safe_ultostr.h
+flush_clnt.o: ../../include/argv.h
 flush_clnt.o: ../../include/attr.h
+flush_clnt.o: ../../include/dict.h
 flush_clnt.o: ../../include/iostuff.h
 flush_clnt.o: ../../include/match_list.h
 flush_clnt.o: ../../include/match_ops.h
@@ -1064,6 +1092,7 @@ flush_clnt.o: ../../include/msg.h
 flush_clnt.o: ../../include/sys_defs.h
 flush_clnt.o: ../../include/vbuf.h
 flush_clnt.o: ../../include/vstream.h
+flush_clnt.o: ../../include/vstring.h
 flush_clnt.o: domain_list.h
 flush_clnt.o: flush_clnt.c
 flush_clnt.o: flush_clnt.h
@@ -1516,9 +1545,14 @@ mark_corrupt.o: mark_corrupt.c
 mark_corrupt.o: mark_corrupt.h
 mark_corrupt.o: msg_stats.h
 mark_corrupt.o: recipient_list.h
+match_parent_style.o: ../../include/argv.h
+match_parent_style.o: ../../include/dict.h
 match_parent_style.o: ../../include/match_list.h
 match_parent_style.o: ../../include/match_ops.h
 match_parent_style.o: ../../include/sys_defs.h
+match_parent_style.o: ../../include/vbuf.h
+match_parent_style.o: ../../include/vstream.h
+match_parent_style.o: ../../include/vstring.h
 match_parent_style.o: mail_params.h
 match_parent_style.o: match_parent_style.c
 match_parent_style.o: match_parent_style.h
@@ -1578,15 +1612,7 @@ mime_state.o: mail_params.h
 mime_state.o: mime_state.c
 mime_state.o: mime_state.h
 mime_state.o: rec_type.h
-mkmap_cdb.o: ../../include/argv.h
-mkmap_cdb.o: ../../include/dict.h
-mkmap_cdb.o: ../../include/dict_cdb.h
-mkmap_cdb.o: ../../include/mymalloc.h
 mkmap_cdb.o: ../../include/sys_defs.h
-mkmap_cdb.o: ../../include/vbuf.h
-mkmap_cdb.o: ../../include/vstream.h
-mkmap_cdb.o: ../../include/vstring.h
-mkmap_cdb.o: mkmap.h
 mkmap_cdb.o: mkmap_cdb.c
 mkmap_db.o: ../../include/argv.h
 mkmap_db.o: ../../include/dict.h
@@ -1694,9 +1720,14 @@ mypwd.o: ../../include/mymalloc.h
 mypwd.o: ../../include/sys_defs.h
 mypwd.o: mypwd.c
 mypwd.o: mypwd.h
+namadr_list.o: ../../include/argv.h
+namadr_list.o: ../../include/dict.h
 namadr_list.o: ../../include/match_list.h
 namadr_list.o: ../../include/match_ops.h
 namadr_list.o: ../../include/sys_defs.h
+namadr_list.o: ../../include/vbuf.h
+namadr_list.o: ../../include/vstream.h
+namadr_list.o: ../../include/vstring.h
 namadr_list.o: namadr_list.c
 namadr_list.o: namadr_list.h
 off_cvt.o: ../../include/msg.h
@@ -1870,6 +1901,8 @@ resolve_clnt.o: mail_params.h
 resolve_clnt.o: mail_proto.h
 resolve_clnt.o: resolve_clnt.c
 resolve_clnt.o: resolve_clnt.h
+resolve_local.o: ../../include/argv.h
+resolve_local.o: ../../include/dict.h
 resolve_local.o: ../../include/inet_addr_list.h
 resolve_local.o: ../../include/match_list.h
 resolve_local.o: ../../include/match_ops.h
@@ -1878,6 +1911,9 @@ resolve_local.o: ../../include/myaddrinfo.h
 resolve_local.o: ../../include/mymalloc.h
 resolve_local.o: ../../include/sys_defs.h
 resolve_local.o: ../../include/valid_hostname.h
+resolve_local.o: ../../include/vbuf.h
+resolve_local.o: ../../include/vstream.h
+resolve_local.o: ../../include/vstring.h
 resolve_local.o: mail_params.h
 resolve_local.o: own_inet_addr.h
 resolve_local.o: resolve_local.c
@@ -1970,6 +2006,8 @@ sent.o: sent.c
 sent.o: sent.h
 sent.o: trace.h
 sent.o: verify.h
+server_acl.o: ../../include/argv.h
+server_acl.o: ../../include/dict.h
 server_acl.o: ../../include/match_list.h
 server_acl.o: ../../include/match_ops.h
 server_acl.o: ../../include/msg.h
@@ -1977,11 +2015,13 @@ server_acl.o: ../../include/mymalloc.h
 server_acl.o: ../../include/stringops.h
 server_acl.o: ../../include/sys_defs.h
 server_acl.o: ../../include/vbuf.h
+server_acl.o: ../../include/vstream.h
 server_acl.o: ../../include/vstring.h
 server_acl.o: addr_match_list.h
 server_acl.o: mail_params.h
 server_acl.o: match_parent_style.h
 server_acl.o: server_acl.c
+server_acl.o: server_acl.h
 smtp_reply_footer.o: ../../include/mac_expand.h
 smtp_reply_footer.o: ../../include/mac_parse.h
 smtp_reply_footer.o: ../../include/msg.h
@@ -2014,9 +2054,14 @@ stream2rec.o: rec_streamlf.h
 stream2rec.o: rec_type.h
 stream2rec.o: record.h
 stream2rec.o: stream2rec.c
+string_list.o: ../../include/argv.h
+string_list.o: ../../include/dict.h
 string_list.o: ../../include/match_list.h
 string_list.o: ../../include/match_ops.h
 string_list.o: ../../include/sys_defs.h
+string_list.o: ../../include/vbuf.h
+string_list.o: ../../include/vstream.h
+string_list.o: ../../include/vstring.h
 string_list.o: string_list.c
 string_list.o: string_list.h
 strip_addr.o: ../../include/mymalloc.h
index ad1a249e319c7259ba2ba0e41fe40648f59a6bb3..86cbe9c559d1c38131e80c133b4b91bf7663ddfa 100644 (file)
@@ -37,9 +37,8 @@
 /*     addr_match_list_init() performs initializations. The first
 /*     argument is the bit-wise OR of zero or more of the following:
 /* .IP MATCH_FLAG_RETURN
-/*      Request that addr_match_list_match() returns a negative result
-/*      (MATCH_ERR_TEMP or MATCH_ERR_PERM), instead of raising a fatal
-/*      error.
+/*     Request that addr_match_list_match() returns zero with
+/*     dict_errno != 0, instead of raising a fatal error.
 /* .PP
 /*     Specify MATCH_FLAG_NONE to request none of the above.
 /*     The second argument is a list of patterns, or the absolute
@@ -99,7 +98,6 @@ int     main(int argc, char **argv)
     ADDR_MATCH_LIST *list;
     char   *addr;
     int     ch;
-    int     rc;
 
     msg_vstream_init(argv[0], VSTREAM_ERR);
 
@@ -119,16 +117,15 @@ int     main(int argc, char **argv)
     if (strcmp(addr, "-") == 0) {
        VSTRING *buf = vstring_alloc(100);
 
-       while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
-           rc = addr_match_list_match(list, vstring_str(buf));
+       while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF)
            vstream_printf("%s: %s\n", vstring_str(buf),
-                          rc > 0 ? "YES" : rc == 0 ? "NO" : "ERROR");
-       }
+                          addr_match_list_match(list, vstring_str(buf)) ?
+                          "YES" : dict_errno == 0 ? "NO" : "ERROR");
        vstring_free(buf);
     } else {
-       rc = addr_match_list_match(list, addr);
        vstream_printf("%s: %s\n", addr,
-                      rc > 0 ? "YES" : rc == 0 ? "NO" : "ERROR");
+                      addr_match_list_match(list, addr) > 0 ?
+                      "YES" : dict_errno == 0 ? "NO" : "ERROR");
     }
     vstream_fflush(VSTREAM_OUT);
     addr_match_list_free(list);
index bdd623bebf6013a68d85f028f14da30bab993799..023e1ffda771a7e4d68a804d8e6567830530b4ec 100644 (file)
@@ -114,7 +114,7 @@ int     debug_peer_check(const char *name, const char *addr)
      */
     if (debug_peer_list != 0
        && saved_level == UNUSED_SAVED_LEVEL
-       && namadr_list_match(debug_peer_list, name, addr) > 0) {
+       && namadr_list_match(debug_peer_list, name, addr) != 0) {
        saved_level = msg_verbose;
        msg_verbose += var_debug_peer_level;
        return (1);
index 57c3c1d66143f0bac64e5a8751c13a0e0051401a..79139add50de56a3cdcf9922d69791198989f20b 100644 (file)
 /*     domain_list_init() performs initializations. The first argument
 /*     is the bit-wise OR of zero or more of the following:
 /* .IP MATCH_FLAG_PARENT
-/*      The hostname pattern foo.com matches itself and any name below
+/*     The hostname pattern foo.com matches itself and any name below
 /*      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 domain_list_match() returns a negative result
-/*     (MATCH_ERR_TEMP or MATCH_ERR_PERM), instead of raising a
-/*     fatal error.
+/*      Request that domain_list_match() returns zero with
+/*     dict_errno != 0, instead of raising a fatal error.
 /* .PP
 /*     Specify MATCH_FLAG_NONE to request none of the above.
 /*     The second argument is a list of domain patterns, or the name of
@@ -99,7 +98,6 @@ int     main(int argc, char **argv)
     DOMAIN_LIST *list;
     char   *host;
     int     ch;
-    int     rc;
 
     msg_vstream_init(argv[0], VSTREAM_ERR);
 
@@ -116,9 +114,8 @@ int     main(int argc, char **argv)
        usage(argv[0]);
     list = domain_list_init(MATCH_FLAG_PARENT | MATCH_FLAG_RETURN, argv[optind]);
     host = argv[optind + 1];
-    rc = domain_list_match(list, host);
-    vstream_printf("%s: %s\n", host,
-                  rc > 0 ? "YES" : rc == 0 ? "NO" : "ERROR");
+    vstream_printf("%s: %s\n", host, domain_list_match(list, host) ?
+                  "YES" : dict_errno == 0 ? "NO" : "ERROR");
     vstream_fflush(VSTREAM_OUT);
     domain_list_free(list);
     return (0);
index d7a51f9fec4163192d68a6cd88a125a8437684f0..e60a9e13a7ea15860a815bf8ba8521dd97de3b3e 100644 (file)
@@ -166,7 +166,6 @@ int     flush_send_site(const char *site)
 {
     const char *myname = "flush_send_site";
     int     status;
-    int     rc;
 
     if (msg_verbose)
        msg_info("%s: site %s", myname, site);
@@ -177,13 +176,13 @@ int     flush_send_site(const char *site)
      */
     if (flush_domains == 0)
        msg_panic("missing flush client initialization");
-    if ((rc = domain_list_match(flush_domains, site)) == 0)
-       status = FLUSH_STAT_DENY;
-    else if (rc > 0)
+    if (domain_list_match(flush_domains, site) != 0)
        status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
                          ATTR_TYPE_STR, MAIL_ATTR_REQ, FLUSH_REQ_SEND_SITE,
                                     ATTR_TYPE_STR, MAIL_ATTR_SITE, site,
                                     ATTR_TYPE_END);
+    else if (dict_errno == 0)
+       status = FLUSH_STAT_DENY;
     else
        status = FLUSH_STAT_FAIL;
 
@@ -223,7 +222,6 @@ int     flush_add(const char *site, const char *queue_id)
 {
     const char *myname = "flush_add";
     int     status;
-    int     rc;
 
     if (msg_verbose)
        msg_info("%s: site %s id %s", myname, site, queue_id);
@@ -234,14 +232,14 @@ int     flush_add(const char *site, const char *queue_id)
      */
     if (flush_domains == 0)
        msg_panic("missing flush client initialization");
-    if ((rc = domain_list_match(flush_domains, site)) == 0)
-       status = FLUSH_STAT_DENY;
-    else if (rc > 0)
+    if (domain_list_match(flush_domains, site) != 0)
        status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
                                ATTR_TYPE_STR, MAIL_ATTR_REQ, FLUSH_REQ_ADD,
                                     ATTR_TYPE_STR, MAIL_ATTR_SITE, site,
                                 ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
                                     ATTR_TYPE_END);
+    else if (dict_errno == 0)
+       status = FLUSH_STAT_DENY;
     else
        status = FLUSH_STAT_FAIL;
 
index 9e650de0b0ef961e5a25883056655752d13003c6..c7fa9b8fe50ca7dce4fb4131998112f763cf5b57 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      "20111221"
+#define MAIL_RELEASE_DATE      "20111222"
 #define MAIL_VERSION_NUMBER    "2.9"
 
 #ifdef SNAPSHOT
index f0cb35526d4bf42640a063ea230460156353ca8a..fea3a62411684b532a34404c4fa7637b8ff58a3b 100644 (file)
@@ -163,6 +163,11 @@ const char *maps_find(MAPS *maps, const char *name, int flags)
     const char *expansion;
     DICT   *dict;
 
+    /*
+     * In case of return without map lookup (empty name or no maps).
+     */
+    dict_errno = 0;
+
     /*
      * Temp. workaround, for buggy callers that pass zero-length keys when
      * given partial addresses.
@@ -233,10 +238,12 @@ int     main(int argc, char **argv)
     maps = maps_create("whatever", argv[1], DICT_FLAG_LOCK);
 
     while (vstring_fgets_nonl(buf, VSTREAM_IN)) {
+       dict_errno = 99;
+       vstream_printf("\"%s\": ", vstring_str(buf));
        if ((result = maps_find(maps, vstring_str(buf), 0)) != 0) {
            vstream_printf("%s\n", result);
        } else if (dict_errno != 0) {
-           msg_fatal("lookup error: %m");
+           vstream_printf("lookup error\n");
        } else {
            vstream_printf("not found\n");
        }
diff --git a/postfix/src/global/maps.in b/postfix/src/global/maps.in
new file mode 100644 (file)
index 0000000..511516e
--- /dev/null
@@ -0,0 +1,4 @@
+./maps fail:1maps <<EOF
+
+foobar
+EOF
diff --git a/postfix/src/global/maps.ref b/postfix/src/global/maps.ref
new file mode 100644 (file)
index 0000000..8591492
--- /dev/null
@@ -0,0 +1,7 @@
+unknown: dict_open: fail:1maps
+unknown: dict_register: fail:1maps(0,lock) 1
+"": not found
+unknown: maps_find: whatever: foobar: search aborted
+"foobar": lookup error
+unknown: maps_free: fail:1maps(0,lock)
+unknown: dict_unregister: fail:1maps(0,lock) 1
index 9dfc87f39ce1ec2dc1fc18874654bda889ae6f99..b3c42d41efbcb78234177636bf647c612c4a39bb 100644 (file)
@@ -46,9 +46,8 @@
 /*     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 namadr_list_match() returns a negative result
-/*     (MATCH_ERR_TEMP or MATCH_ERR_PERM), instead of raising a
-/*     fatal error.
+/*     Request that namadr_list_match() returns zero with
+/*     dict_errno != 0, instead of raising a fatal error.
 /* .PP
 /*     Specify MATCH_FLAG_NONE to request none of the above.
 /*     The second argument is a list of patterns, or the absolute
@@ -106,7 +105,6 @@ int     main(int argc, char **argv)
     char   *host;
     char   *addr;
     int     ch;
-    int     rc;
 
     msg_vstream_init(argv[0], VSTREAM_ERR);
 
@@ -124,9 +122,9 @@ int     main(int argc, char **argv)
     list = namadr_list_init(MATCH_FLAG_PARENT | MATCH_FLAG_RETURN, argv[optind]);
     host = argv[optind + 1];
     addr = argv[optind + 2];
-    rc = namadr_list_match(list, host, addr);
     vstream_printf("%s/%s: %s\n", host, addr,
-                  rc > 0 ? "YES" : rc == 0 ? "NO" : "ERROR");
+                  namadr_list_match(list, host, addr) ?
+                  "YES" : dict_errno == 0 ? "NO" : "ERROR");
     vstream_fflush(VSTREAM_OUT);
     namadr_list_free(list);
     return (0);
index 703ec07431b6409cfac24fd999190ec46de0bb81..09fcf94d1f25eefb019a7700cac3576dfcb481e5 100644 (file)
@@ -16,6 +16,9 @@
 /*     against the domains, files or tables listed in $mydestination,
 /*     or by a match of an [address-literal] against of the network
 /*     addresses listed in $inet_interfaces or in $proxy_interfaces.
+/*     The result is non-zero if the domain matches the list of local
+/*     domains and IP addresses, 0 when it does not match or in case
+/*     of error (in the latter case dict_errno is non-zero).
 /*
 /*     resolve_local_init() performs initialization. If this routine is
 /*     not called explicitly ahead of time, it will be called on the fly.
@@ -63,9 +66,10 @@ static STRING_LIST *resolve_local_list;
 
 void    resolve_local_init(void)
 {
+    /* Allow on-the-fly update to make testing easier. */
     if (resolve_local_list)
-       msg_panic("resolve_local_init: duplicate initialization");
-    resolve_local_list = string_list_init(MATCH_FLAG_NONE, var_mydest);
+       string_list_free(resolve_local_list);
+    resolve_local_list = string_list_init(MATCH_FLAG_RETURN, var_mydest);
 }
 
 /* resolve_local - match domain against list of local destinations */
@@ -92,6 +96,12 @@ int     resolve_local(const char *addr)
     if (resolve_local_list == 0)
        resolve_local_init();
 
+    /*
+     * In case of return without table lookup (empty address, malformed
+     * address, empty destination list)
+     */
+    dict_errno = 0;
+
     /*
      * Strip one trailing dot but not dot-dot.
      * 
@@ -113,6 +123,8 @@ int     resolve_local(const char *addr)
      */
     if (string_list_match(resolve_local_list, saved_addr))
        RETURN(1);
+    if (dict_errno != 0)
+       RETURN(0);
 
     /*
      * Compare the destination against the list of interface addresses that
@@ -168,10 +180,15 @@ int     resolve_local(const char *addr)
 
 int     main(int argc, char **argv)
 {
-    if (argc != 2)
-       msg_fatal("usage: %s domain", argv[0]);
+    if (argc != 3)
+       msg_fatal("usage: %s mydestination domain", argv[0]);
     mail_conf_read();
-    vstream_printf("%s\n", resolve_local(argv[1]) ? "yes" : "no");
+    myfree(var_mydest);
+    var_mydest = mystrdup(argv[1]);
+    dict_errno = 99;
+    vstream_printf("mydestination=%s destination=%s %s\n",
+                  argv[1], argv[2], resolve_local(argv[2]) ? "YES" :
+                  dict_errno == 0 ? "NO" : "ERROR");
     vstream_fflush(VSTREAM_OUT);
     return (0);
 }
index 53af376d0e91011e67cce3839b9b0f63901ef5be..c7ad5e040bf813ef26956244931551afcd4029d8 100644 (file)
 /* DESCRIPTION
 /* .nf
 
+ /*
+  * Utility library.
+  */
+#include <dict.h>
+
  /*
   * External interface.
   */
diff --git a/postfix/src/global/resolve_local.in b/postfix/src/global/resolve_local.in
new file mode 100644 (file)
index 0000000..1646fc5
--- /dev/null
@@ -0,0 +1,5 @@
+./resolve_local example.com example.com
+./resolve_local example.net example.com
+./resolve_local fail:1_resolve_local example.com
+./resolve_local fail:1_resolve_local example.com..
+./resolve_local fail:1_resolve_local ''
diff --git a/postfix/src/global/resolve_local.ref b/postfix/src/global/resolve_local.ref
new file mode 100644 (file)
index 0000000..7448d98
--- /dev/null
@@ -0,0 +1,6 @@
+mydestination=example.com destination=example.com YES
+mydestination=example.net destination=example.com NO
+unknown: warning: fail:1_resolve_local(0,lock|fold_fix): 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 8767fa47051d14ad7ca3a1c26e90f51937f18513..9d9fa495051e5d4cb81a578e965fe27a15296d15 100644 (file)
@@ -98,9 +98,9 @@ void    server_acl_pre_jail_init(const char *mynetworks, const char *origin)
 {
     if (server_acl_mynetworks)
        addr_match_list_free(server_acl_mynetworks);
-    server_acl_mynetworks = 
+    server_acl_mynetworks =
        addr_match_list_init(MATCH_FLAG_RETURN | match_parent_style(origin),
-                                                mynetworks);
+                            mynetworks);
 }
 
 /* server_acl_parse - parse access list */
@@ -131,7 +131,7 @@ SERVER_ACL *server_acl_parse(const char *extern_acl, const char *origin)
            } else {
                if (dict_handle(acl) == 0)
                    dict_register(acl, dict_open(acl, O_RDONLY, DICT_FLAG_LOCK
-                                                 | DICT_FLAG_FOLD_FIX));
+                                                | DICT_FLAG_FOLD_FIX));
            }
        }
        argv_add(intern_acl, acl, (char *) 0);
@@ -157,7 +157,6 @@ int     server_acl_eval(const char *client_addr, SERVER_ACL * intern_acl,
     const char *acl;
     const char *dict_val;
     int     ret;
-    int     rc;
 
     for (cpp = intern_acl->argv; (acl = *cpp) != 0; cpp++) {
        if (msg_verbose)
@@ -168,10 +167,9 @@ int     server_acl_eval(const char *client_addr, SERVER_ACL * intern_acl,
        } else if (STREQ(acl, SERVER_ACL_NAME_PERMIT)) {
            return (SERVER_ACL_ACT_PERMIT);
        } else if (STREQ(acl, SERVER_ACL_NAME_WL_MYNETWORKS)) {
-           rc = addr_match_list_match(server_acl_mynetworks, client_addr);
-           if (rc > 0)
+           if (addr_match_list_match(server_acl_mynetworks, client_addr))
                return (SERVER_ACL_ACT_PERMIT);
-           if (rc < 0) {
+           if (dict_errno != 0) {
                msg_warn("%s: %s: mynetworks lookup error -- ignoring the "
                         "remainder of this access list", origin, acl);
                return (SERVER_ACL_ACT_ERROR);
index 9de5a5429ce596423057bfa307d73f6baffe9253..4b84ace9f3449be95508b797f96dd7bc40bae4f5 100644 (file)
@@ -34,9 +34,8 @@
 /*     string_list_init() performs initializations. The first argument
 /*     is a bit-wise OR of zero or more of following:
 /* .IP MATCH_FLAG_RETURN
-/*      Request that string_list_match() returns a negative result
-/*      (MATCH_ERR_TEMP or MATCH_ERR_PERM), instead of raising a fatal
-/*      error.
+/*     Request that string_list_match() returns zero with
+/*     dict_errno != 0, instead of raising a fatal error.
 /* .PP
 /*     Specify MATCH_FLAG_NONE to request none of the above.
 /*     The second argument specifies a list of string patterns.
@@ -92,7 +91,6 @@ int     main(int argc, char **argv)
     STRING_LIST *list;
     char   *string;
     int     ch;
-    int     rc;
 
     msg_vstream_init(argv[0], VSTREAM_ERR);
 
@@ -109,9 +107,8 @@ int     main(int argc, char **argv)
        usage(argv[0]);
     list = string_list_init(MATCH_FLAG_NONE | MATCH_FLAG_RETURN, argv[optind]);
     string = argv[optind + 1];
-    rc = string_list_match(list, string);
-    vstream_printf("%s: %s\n", string,
-                  rc > 0 ? "YES" : rc == 0 ? "NO" : "ERROR");
+    vstream_printf("%s: %s\n", string, string_list_match(list, string) ?
+                  "YES" : dict_errno == 0 ? "NO" : "ERROR");
     vstream_fflush(VSTREAM_OUT);
     string_list_free(list);
     return (0);
index f7145fade2b94973a94e7629c01676913d2f082b..e9c33e80f626ad254179d7853be4263ab08b790b 100644 (file)
@@ -649,7 +649,6 @@ static void qmqpd_receive(QMQPD_STATE *state)
 static void qmqpd_proto(QMQPD_STATE *state)
 {
     int     status;
-    int     rc;
 
     netstring_setup(state->client, var_qmqpd_timeout);
 
@@ -687,10 +686,9 @@ static void qmqpd_proto(QMQPD_STATE *state)
        /*
         * See if we want to talk to this client at all.
         */
-       rc = namadr_list_match(qmqpd_clients, state->name, state->addr);
-       if (rc > 0) {
+       if (namadr_list_match(qmqpd_clients, state->name, state->addr) != 0) {
            qmqpd_receive(state);
-       } else if (rc == 0) {
+       } else if (dict_errno == 0) {
            qmqpd_reply(state, DONT_LOG, QMQPD_STAT_HARD,
                        "Error: %s is not authorized to use this service",
                        state->namaddr);
index 2a26b77c155f37e5815422b6aea5f54ab1e989cf..989c3c7caafb4838c8896ebd173978fe2590c8dd 100644 (file)
@@ -300,7 +300,6 @@ smtpd_check.o: ../../include/recipient_list.h
 smtpd_check.o: ../../include/record.h
 smtpd_check.o: ../../include/resolve_clnt.h
 smtpd_check.o: ../../include/resolve_local.h
-smtpd_check.o: ../../include/rewrite_clnt.h
 smtpd_check.o: ../../include/sock_addr.h
 smtpd_check.o: ../../include/split_at.h
 smtpd_check.o: ../../include/string_list.h
index f5beaf46c0349541170a2a723e2826980ea370fc..2000eb2d2b845bbe0c86253e484b5b856660144e 100644 (file)
@@ -1004,14 +1004,13 @@ static int permit_inet_interfaces(SMTPD_STATE *state)
 static int permit_mynetworks(SMTPD_STATE *state)
 {
     const char *myname = "permit_mynetworks";
-    int     rc;
 
     if (msg_verbose)
        msg_info("%s: %s %s", myname, state->name, state->addr);
 
-    if ((rc = namadr_list_match(mynetworks, state->name, state->addr)) > 0)
+    if (namadr_list_match(mynetworks, state->name, state->addr))
        return (SMTPD_CHECK_OK);
-    else if (rc == 0)
+    else if (dict_errno == 0)
        return (SMTPD_CHECK_DUNNO);
     else
        return (SMTPD_CHECK_ERROR);
@@ -1431,7 +1430,6 @@ static int all_auth_mx_addr(SMTPD_STATE *state, char *host,
     DNS_RR *rr;
     DNS_RR *addr_list;
     int     dns_status;
-    int     rc;
 
     if (msg_verbose)
        msg_info("%s: host %s", myname, host);
@@ -1463,26 +1461,26 @@ static int all_auth_mx_addr(SMTPD_STATE *state, char *host,
        if (msg_verbose)
            msg_info("%s: checking: %s", myname, hostaddr.buf);
 
-       rc = namadr_list_match(perm_mx_networks, host, hostaddr.buf);
-       if (rc == 0) {
+       if (!namadr_list_match(perm_mx_networks, host, hostaddr.buf)) {
+           if (dict_errno == 0) {
 
-           /*
-            * Reject: at least one IP address is not listed in
-            * permit_mx_backup_networks.
-            */
-           if (msg_verbose)
-               msg_info("%s: address %s for %s does not match %s",
-                        myname, hostaddr.buf, host, VAR_PERM_MX_NETWORKS);
+               /*
+                * Reject: at least one IP address is not listed in
+                * permit_mx_backup_networks.
+                */
+               if (msg_verbose)
+                   msg_info("%s: address %s for %s does not match %s",
+                         myname, hostaddr.buf, host, VAR_PERM_MX_NETWORKS);
+           } else {
+               msg_warn("%s: %s lookup error for address %s for %s",
+                        myname, VAR_PERM_MX_NETWORKS, hostaddr.buf, host);
+               DEFER_IF_REJECT3(state, MAIL_ERROR_POLICY,
+                                450, "4.4.4",
+                                "<%s>: %s rejected: Unable to verify host %s as mail exchanger",
+                                reply_name, reply_class, host);
+           }
            dns_rr_free(addr_list);
            return (NOPE);
-       } else if (rc < 0) {
-           msg_warn("%s: %s lookup error for address %s for %s",
-                    myname, VAR_PERM_MX_NETWORKS, hostaddr.buf, host);
-           DEFER_IF_REJECT3(state, MAIL_ERROR_POLICY,
-                            450, "4.4.4",
-           "<%s>: %s rejected: Unable to verify host %s as mail exchanger",
-                            reply_name, reply_class, host);
-           return (NOPE);
        }
     }
     dns_rr_free(addr_list);
@@ -1560,6 +1558,7 @@ static int i_am_mx(SMTPD_STATE *state, DNS_RR *mx_list,
            msg_info("%s: resolve hostname: %s", myname, (char *) mx->data);
        if (resolve_local((char *) mx->data))
            return (YUP);
+       /* if no match or error, match interface addresses instead. */
     }
 
     /*
@@ -5239,18 +5238,26 @@ void    resolve_clnt(const char *class, const char *unused_sender, const char *a
        reply->flags = RESOLVE_CLASS_LOCAL;
        vstring_strcpy(reply->transport, MAIL_SERVICE_LOCAL);
        vstring_strcpy(reply->nexthop, domain);
+    } else if (dict_errno) {
+       reply->flags = RESOLVE_FLAG_FAIL;
     } else if (string_list_match(virt_alias_doms, domain)) {
        reply->flags = RESOLVE_CLASS_ALIAS;
        vstring_strcpy(reply->transport, MAIL_SERVICE_ERROR);
        vstring_strcpy(reply->nexthop, "user unknown");
+    } else if (dict_errno) {
+       reply->flags = RESOLVE_FLAG_FAIL;
     } else if (string_list_match(virt_mailbox_doms, domain)) {
        reply->flags = RESOLVE_CLASS_VIRTUAL;
        vstring_strcpy(reply->transport, MAIL_SERVICE_VIRTUAL);
        vstring_strcpy(reply->nexthop, domain);
+    } else if (dict_errno) {
+       reply->flags = RESOLVE_FLAG_FAIL;
     } else if (domain_list_match(relay_domains, domain)) {
        reply->flags = RESOLVE_CLASS_RELAY;
        vstring_strcpy(reply->transport, MAIL_SERVICE_RELAY);
        vstring_strcpy(reply->nexthop, domain);
+    } else if (dict_errno) {
+       reply->flags = RESOLVE_FLAG_FAIL;
     } else {
        reply->flags = RESOLVE_CLASS_DEFAULT;
        vstring_strcpy(reply->transport, MAIL_SERVICE_SMTP);
@@ -5381,6 +5388,12 @@ int     main(int argc, char **argv)
          ptr = string_list_init(MATCH_FLAG_NONE, val); }
 
        case 2:
+           if (strcasecmp(args->argv[0], VAR_MYDEST) == 0) {
+               UPDATE_STRING(var_mydest, args->argv[1]);
+               resolve_local_init();
+               resp = 0;
+               break;
+           }
            if (strcasecmp(args->argv[0], VAR_VIRT_ALIAS_MAPS) == 0) {
                UPDATE_STRING(var_virt_alias_maps, args->argv[1]);
                UPDATE_MAPS(virt_alias_maps, VAR_VIRT_ALIAS_MAPS,
index 257a8952271e0c0cb9aa3735b35546de72b0efe5..c894b874a2673c5f582a3a250eb752cbd5ccfe0c 100644 (file)
@@ -65,3 +65,17 @@ local_header_rewrite_clients fail:1_rewrite
 # Expect: REJECT (temporary lookup failure)
 #
 rewrite
+#
+# Test resolve_local()
+#
+mydestination example.com
+recipient_restrictions reject_unauth_destination
+rcpt user@example.com
+mydestination fail:1_mydestination
+rcpt user@example.com
+#
+# Test virtual alias lookup.
+#
+mydestination example.com
+virtual_alias_maps fail:1_virtual
+rcpt user@example.com
index cb2448c39d63421cc31fc32768939df1b6b3e19a..99126290f8c0d242df78999ef0c882be075c0333 100644 (file)
@@ -106,3 +106,28 @@ OK
 ./smtpd_check: warning: local_header_rewrite_clients: fail:1_rewrite: lookup error
 ./smtpd_check: <queue id>: reject: RCPT from foo.dunno.com[131.155.210.17]: 451 4.3.0 Temporary lookup error; from=<> proto=SMTP helo=<foobar>
 451 4.3.0 Temporary lookup error
+>>> #
+>>> # Test resolve_local()
+>>> #
+>>> mydestination example.com
+OK
+>>> recipient_restrictions reject_unauth_destination
+OK
+>>> rcpt user@example.com
+OK
+>>> mydestination fail:1_mydestination
+OK
+>>> rcpt user@example.com
+./smtpd_check: warning: fail:1_mydestination(0,lock|fold_fix): 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
+>>> #
+>>> # Test virtual alias lookup.
+>>> #
+>>> mydestination example.com
+OK
+>>> virtual_alias_maps fail:1_virtual
+OK
+>>> rcpt user@example.com
+./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 2ed3955612ed699847708571507060b40a59086d..315799307cdf84c910c68395f92d9ae7d09c0e04 100644 (file)
@@ -155,7 +155,6 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
     const char *relay;
     const char *xport;
     const char *sender_key;
-    int     rc;
 
     *flags = 0;
     vstring_strcpy(channel, "CHANNEL NOT UPDATED");
@@ -216,21 +215,8 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
 #define RESOLVE_LOCAL(domain) \
     resolve_local(STR(tok822_internalize(addr_buf, domain, TOK822_STR_DEFL)))
 
-    dict_errno = 0;
-
     for (loop_count = 0, loop_max = addr_len + 100; /* void */ ; loop_count++) {
 
-       /*
-        * Grr. resolve_local() table lookups may fail. It may be OK for
-        * local file lookup code to abort upon failure, but with
-        * network-based tables it is preferable to return an error
-        * indication to the requestor.
-        */
-       if (dict_errno) {
-           *flags |= RESOLVE_FLAG_FAIL;
-           FREE_MEMORY_AND_RETURN;
-       }
-
        /*
         * XXX Should never happen, but if this happens with some
         * pathological address, then that is not sufficient reason to
@@ -264,10 +250,20 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
 
        /*
         * Strip (and save) @domain if local.
+        * 
+        * Grr. resolve_local() table lookups may fail. It may be OK for local
+        * file lookup code to abort upon failure, but with network-based
+        * tables it is preferable to return an error indication to the
+        * requestor.
         */
        if ((domain = tok822_rfind_type(tree->tail, '@')) != 0) {
-           if (domain->next && RESOLVE_LOCAL(domain->next) == 0)
+           if (domain->next && RESOLVE_LOCAL(domain->next) == 0) {
+               if (dict_errno != 0) {
+                   *flags |= RESOLVE_FLAG_FAIL;
+                   FREE_MEMORY_AND_RETURN;
+               }
                break;
+           }
            tok822_sub_keep_before(tree, domain);
            if (saved_domain)
                tok822_free_tree(saved_domain);
@@ -381,6 +377,8 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
            rcpt_domain = strrchr(STR(nextrcpt), '@') + 1;
            if (resolve_local(rcpt_domain))     /* XXX */
                domain = 0;
+           else if (dict_errno != 0)
+               *flags |= RESOLVE_FLAG_FAIL;
        } else {
            *flags |= RESOLVE_FLAG_ERROR;
        }
@@ -432,15 +430,15 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
         * Virtual alias domain.
         */
        if (virt_alias_doms
-           && (rc = string_list_match(virt_alias_doms, rcpt_domain)) > 0) {
+           && string_list_match(virt_alias_doms, rcpt_domain)) {
            if (var_helpful_warnings) {
                if (virt_mailbox_doms
-                   && string_list_match(virt_mailbox_doms, rcpt_domain) > 0)
+                   && string_list_match(virt_mailbox_doms, rcpt_domain))
                    msg_warn("do not list domain %s in BOTH %s and %s",
                             rcpt_domain, VAR_VIRT_ALIAS_DOMS,
                             VAR_VIRT_MAILBOX_DOMS);
                if (relay_domains
-                   && domain_list_match(relay_domains, rcpt_domain) > 0)
+                   && domain_list_match(relay_domains, rcpt_domain))
                    msg_warn("do not list domain %s in BOTH %s and %s",
                             rcpt_domain, VAR_VIRT_ALIAS_DOMS,
                             VAR_RELAY_DOMAINS);
@@ -455,7 +453,7 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
                            var_show_unk_rcpt_table ?
                            " in virtual alias table" : "");
            *flags |= RESOLVE_CLASS_ALIAS;
-       } else if (dict_errno != 0 || rc < 0) {
+       } else if (dict_errno != 0) {
            msg_warn("%s lookup failure", VAR_VIRT_ALIAS_DOMS);
            *flags |= RESOLVE_FLAG_FAIL;
            FREE_MEMORY_AND_RETURN;
@@ -465,10 +463,10 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
         * Virtual mailbox domain.
         */
        else if (virt_mailbox_doms
-        && (rc = string_list_match(virt_mailbox_doms, rcpt_domain)) > 0) {
+                && string_list_match(virt_mailbox_doms, rcpt_domain)) {
            if (var_helpful_warnings) {
                if (relay_domains
-                   && domain_list_match(relay_domains, rcpt_domain) > 0)
+                   && domain_list_match(relay_domains, rcpt_domain))
                    msg_warn("do not list domain %s in BOTH %s and %s",
                             rcpt_domain, VAR_VIRT_MAILBOX_DOMS,
                             VAR_RELAY_DOMAINS);
@@ -477,7 +475,7 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
            vstring_strcpy(nexthop, rcpt_domain);
            blame = rp->virt_transport_name;
            *flags |= RESOLVE_CLASS_VIRTUAL;
-       } else if (dict_errno != 0 || rc < 0) {
+       } else if (dict_errno != 0) {
            msg_warn("%s lookup failure", VAR_VIRT_MAILBOX_DOMS);
            *flags |= RESOLVE_FLAG_FAIL;
            FREE_MEMORY_AND_RETURN;
@@ -487,11 +485,11 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
             * Off-host relay destination.
             */
            if (relay_domains
-            && (rc = domain_list_match(relay_domains, rcpt_domain)) > 0) {
+               && domain_list_match(relay_domains, rcpt_domain)) {
                vstring_strcpy(channel, RES_PARAM_VALUE(rp->relay_transport));
                blame = rp->relay_transport_name;
                *flags |= RESOLVE_CLASS_RELAY;
-           } else if (dict_errno != 0 || rc < 0) {
+           } else if (dict_errno != 0) {
                msg_warn("%s lookup failure", VAR_RELAY_DOMAINS);
                *flags |= RESOLVE_FLAG_FAIL;
                FREE_MEMORY_AND_RETURN;
@@ -561,11 +559,11 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
     else {
        if (var_helpful_warnings) {
            if (virt_alias_doms
-               && string_list_match(virt_alias_doms, rcpt_domain) > 0)
+               && string_list_match(virt_alias_doms, rcpt_domain))
                msg_warn("do not list domain %s in BOTH %s and %s",
                         rcpt_domain, VAR_MYDEST, VAR_VIRT_ALIAS_DOMS);
            if (virt_mailbox_doms
-               && string_list_match(virt_mailbox_doms, rcpt_domain) > 0)
+               && string_list_match(virt_mailbox_doms, rcpt_domain))
                msg_warn("do not list domain %s in BOTH %s and %s",
                         rcpt_domain, VAR_MYDEST, VAR_VIRT_MAILBOX_DOMS);
        }
@@ -748,7 +746,7 @@ void    resolve_init(void)
 
     if (*var_relay_domains)
        relay_domains =
-           domain_list_init(MATCH_FLAG_RETURN 
+           domain_list_init(MATCH_FLAG_RETURN
                             | match_parent_style(VAR_RELAY_DOMAINS),
                             var_relay_domains);
 
index 9ca016b957eb318c43b61e65080f6115947248e8..b72b8db3e1555845d4497c040500a8c3d82d1527 100644 (file)
@@ -140,10 +140,6 @@ VSTRING *cidr_match_parse(CIDR_MATCH *ip, char *pattern, VSTRING *why)
     MAI_HOSTADDR_STR hostaddr;
     unsigned char *np;
     unsigned char *mp;
-    static VSTRING *buf;
-
-#define WHY_OR_BUF (why ? why : buf ? (why = buf) : \
-                   (why = buf = vstring_alloc(20)))
 
     /*
      * Strip [] from [addr/len] or [addr]/len, destroying the pattern. CIDR
@@ -154,12 +150,13 @@ VSTRING *cidr_match_parse(CIDR_MATCH *ip, char *pattern, VSTRING *why)
     if (*pattern == '[') {
        pattern++;
        if ((mask_search = split_at(pattern, ']')) == 0) {
-           vstring_sprintf(WHY_OR_BUF,
+           vstring_sprintf(why ? why : (why = vstring_alloc(20)),
                            "missing ']' character after \"[%s\"", pattern);
            return (why);
        } else if (*mask_search != '/') {
            if (*mask_search != 0) {
-               vstring_sprintf(WHY_OR_BUF, "garbage after \"[%s]\"", pattern);
+               vstring_sprintf(why ? why : (why = vstring_alloc(20)),
+                               "garbage after \"[%s]\"", pattern);
                return (why);
            }
            mask_search = pattern;
@@ -177,7 +174,7 @@ VSTRING *cidr_match_parse(CIDR_MATCH *ip, char *pattern, VSTRING *why)
        if (!alldig(mask)
            || (ip->mask_shift = atoi(mask)) > ip->addr_bit_count
            || inet_pton(ip->addr_family, pattern, ip->net_bytes) != 1) {
-           vstring_sprintf(WHY_OR_BUF,
+           vstring_sprintf(why ? why : (why = vstring_alloc(20)),
                          "bad net/mask pattern: \"%s/%s\"", pattern, mask);
            return (why);
        }
@@ -198,7 +195,7 @@ VSTRING *cidr_match_parse(CIDR_MATCH *ip, char *pattern, VSTRING *why)
                if (inet_ntop(ip->addr_family, ip->net_bytes, hostaddr.buf,
                              sizeof(hostaddr.buf)) == 0)
                    msg_fatal("inet_ntop: %m");
-               vstring_sprintf(WHY_OR_BUF,
+               vstring_sprintf(why ? why : (why = vstring_alloc(20)),
                                "non-null host address bits in \"%s/%s\", "
                                "perhaps you should use \"%s/%d\" instead",
                                pattern, mask, hostaddr.buf, ip->mask_shift);
@@ -215,7 +212,8 @@ VSTRING *cidr_match_parse(CIDR_MATCH *ip, char *pattern, VSTRING *why)
        ip->addr_bit_count = CIDR_MATCH_ADDR_BIT_COUNT(ip->addr_family);
        ip->addr_byte_count = CIDR_MATCH_ADDR_BYTE_COUNT(ip->addr_family);
        if (inet_pton(ip->addr_family, pattern, ip->net_bytes) != 1) {
-           vstring_sprintf(WHY_OR_BUF, "bad address pattern: \"%s\"", pattern);
+           vstring_sprintf(why ? why : (why = vstring_alloc(20)),
+                           "bad address pattern: \"%s\"", pattern);
            return (why);
        }
        ip->mask_shift = ip->addr_bit_count;
index ed08a9a3c650672d8cd54d95e81e2abbddeb5a66..b7811b7e234ca021f7d7692014d40f4e358ed0f1 100644 (file)
@@ -118,6 +118,7 @@ extern int dict_errno;
 
 #define DICT_ERR_NONE  0               /* no error */
 #define DICT_ERR_RETRY 1               /* soft error */
+#define DICT_ERR_CONFIG        2               /* configuration error */
 
  /*
   * Sequence function types.
index 6f76dafe77c3fd5ba920d89bdf49eae5a75925ed..195280f26d1f515ef7e6fbd6412f33da1176440b 100644 (file)
@@ -36,8 +36,8 @@
 /*     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
-/*     Return a negative result (MATCH_ERR_TEMP or MATCH_ERR_FAIL)
-/*     instead of raising a fatal run-time error.
+/*     Request that match_list_match() returns zero (with dict_errno
+/*     set) 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
@@ -199,7 +199,6 @@ int     match_list_match(MATCH_LIST *list,...)
     int     match;
     int     i;
     va_list ap;
-    int     rc;
 
     /*
      * Iterate over all patterns in the list, stop at the first match.
@@ -214,11 +213,10 @@ int     match_list_match(MATCH_LIST *list,...)
        for (match = 1; *pat == '!'; pat++)
            match = !match;
        for (i = 0; i < list->match_count; i++)
-           if ((rc = list->match_func[i] (list->flags,
-                                          list->match_args[i], pat)) > 0)
+           if (list->match_func[i] (list->flags, list->match_args[i], pat))
                return (match);
-           else if (rc < 0)
-               return (rc);
+           else if (dict_errno != 0)
+               return (0);
     }
     if (msg_verbose)
        for (i = 0; i < list->match_count; i++)
index d1cf850533d2e7a747e7057ba1662dca96178733..84c6cb322c2343943bd8ab144cea2c173291d21d 100644 (file)
@@ -38,7 +38,7 @@
 /*     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
-/*     Return MATCH_ERR_TEMP or MATCH_ERR_PERM, instead of raising
+/*     Return "not found" and set dict_errno, instead of raising
 /*     a fatal run-time error.
 /* .RE
 /*     Specify MATCH_FLAG_NONE to request none of the above.
 
 /* match_error - return or raise fatal error */
 
-static int match_error(int flags, int err_val, const char *fmt,...)
+static int match_error(int flags, const char *fmt,...)
 {
     VSTRING *buf = vstring_alloc(100);
     va_list ap;
 
-    /*
-     * In case arguments get swapped after some code change.
-     */
-    if (err_val >= 0)
-       msg_panic("match_error: bad error value: %d", err_val);
-
     /*
      * Report, and maybe return.
      */
@@ -109,7 +103,7 @@ static int match_error(int flags, int err_val, const char *fmt,...)
        msg_fatal("%s", vstring_str(buf));
     }
     vstring_free(buf);
-    return (err_val);
+    return (0);
 }
 
 /* match_string - match a string literal */
@@ -130,8 +124,7 @@ int     match_string(int flags, const char *string, const char *pattern)
        if (match != 0)
            return (1);
        if (dict_errno != 0)
-           return (match_error(flags, MATCH_ERR_TEMP,
-                               "%s: table lookup problem", pattern));
+           return (match_error(flags, "%s: table lookup problem", pattern));
        return (0);
     }
 
@@ -181,8 +174,8 @@ int     match_hostname(int flags, const char *name, const char *pattern)
                if (match != 0)
                    break;
                if (dict_errno != 0)
-                   return (match_error(flags, MATCH_ERR_TEMP,
-                                     "%s: table lookup problem", pattern));
+                   return (match_error(flags, "%s: table lookup problem", 
+pattern));
            }
            if ((next = strchr(entry + 1, '.')) == 0)
                break;
@@ -224,6 +217,7 @@ int     match_hostaddr(int flags, const char *addr, const char *pattern)
     char   *saved_patt;
     CIDR_MATCH match_info;
     VSTRING *err;
+    int     rc;
 
     if (msg_verbose)
        msg_info("%s: %s ~? %s", myname, addr, pattern);
@@ -241,8 +235,7 @@ int     match_hostaddr(int flags, const char *addr, const char *pattern)
        if (dict_lookup(pattern, addr) != 0)
            return (1);
        if (dict_errno != 0)
-           return (match_error(flags, MATCH_ERR_TEMP,
-                               "%s: table lookup problem", pattern));
+           return (match_error(flags, "%s: table lookup problem", pattern));
        return (0);
     }
 
@@ -296,7 +289,11 @@ int     match_hostaddr(int flags, const char *addr, const char *pattern)
     saved_patt = mystrdup(pattern);
     err = cidr_match_parse(&match_info, saved_patt, (VSTRING *) 0);
     myfree(saved_patt);
-    if (err != 0)
-       return (match_error(flags, MATCH_ERR_PERM, "%s", vstring_str(err)));
+    if (err != 0) {
+       rc = match_error(flags, "%s", vstring_str(err));
+       vstring_free(err);
+       dict_errno = DICT_ERR_CONFIG;
+       return (rc);
+    }
     return (cidr_match_execute(&match_info, addr) != 0);
 }
index a98b8c08903c4cb4cf7d45231622f61bbb766acf..055c4f7ddbcc98998abd82901209c023b51ffebf 100644 (file)
 /* .nf
 
  /*
-  * External interface.
+  * Utility library.
   */
+#include <dict.h>
 
  /*
-  * This is what the caller specifies.
+  * External interface.
   */
 #define MATCH_FLAG_NONE                0
 #define MATCH_FLAG_PARENT      (1<<0)
 #define MATCH_FLAG_RETURN      (1<<1)
-
- /*
-  * This is for internal use.
-  */
 #define MATCH_FLAG_ALL         (MATCH_FLAG_PARENT | MATCH_FLAG_RETURN)
 
- /*
-  * Some errors cannot be signaled as (result == 0, dict_errno > 0).
-  * Therefore we signal all errors as (result < 0).
-  */
-#define MATCH_ERR_TEMP         (-1)    /* e.g., database is down */
-#define MATCH_ERR_PERM         (-2)    /* e.g., net/mask syntax */
-
 extern int match_string(int, const char *, const char *);
 extern int match_hostname(int, const char *, const char *);
 extern int match_hostaddr(int, const char *, const char *);
index ee4615504bcaa22b367da93a53b80480e32b7a97..454e5bfd7a2490c0098338d19903c341f81ac1bb 100644 (file)
@@ -240,8 +240,8 @@ int     name_mask_delim_opt(const char *context, const NAME_MASK *table,
                } else if (flags & NAME_MASK_RETURN) {
                    msg_warn("unknown %s value \"%s\" in \"%s\"",
                             context, name, names);
-                   result = 0;
-                   break;
+                   myfree(saved_names);
+                   return (0);
                } else if (flags & NAME_MASK_WARN) {
                    msg_warn("unknown %s value \"%s\" in \"%s\"",
                             context, name, names);
@@ -354,6 +354,7 @@ long    long_name_mask_delim_opt(const char *context,
                } else if (flags & NAME_MASK_RETURN) {
                    msg_warn("unknown %s value \"%s\" in \"%s\"",
                             context, name, names);
+                   myfree(saved_names);
                    return (0);
                } else if (flags & NAME_MASK_WARN) {
                    msg_warn("unknown %s value \"%s\" in \"%s\"",