From d4d5071d75efb9d2cde28bc1a84776d904a300e4 Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Thu, 22 Dec 2011 00:00:00 -0500 Subject: [PATCH] postfix-2.9-20111222 --- postfix/HISTORY | 17 +++++++- postfix/README_FILES/SASL_README | 2 +- postfix/html/SASL_README.html | 2 +- postfix/proto/SASL_README.html | 2 +- postfix/src/flush/flush.c | 2 +- postfix/src/global/Makefile.in | 63 +++++++++++++++++++++++---- postfix/src/global/addr_match_list.c | 17 +++----- postfix/src/global/debug_peer.c | 2 +- postfix/src/global/domain_list.c | 13 +++--- postfix/src/global/flush_clnt.c | 14 +++--- postfix/src/global/mail_version.h | 2 +- postfix/src/global/maps.c | 9 +++- postfix/src/global/maps.in | 4 ++ postfix/src/global/maps.ref | 7 +++ postfix/src/global/namadr_list.c | 10 ++--- postfix/src/global/resolve_local.c | 27 +++++++++--- postfix/src/global/resolve_local.h | 5 +++ postfix/src/global/resolve_local.in | 5 +++ postfix/src/global/resolve_local.ref | 6 +++ postfix/src/global/server_acl.c | 12 +++-- postfix/src/global/string_list.c | 11 ++--- postfix/src/qmqpd/qmqpd.c | 6 +-- postfix/src/smtpd/Makefile.in | 1 - postfix/src/smtpd/smtpd_check.c | 55 ++++++++++++++--------- postfix/src/smtpd/smtpd_error.in | 14 ++++++ postfix/src/smtpd/smtpd_error.ref | 25 +++++++++++ postfix/src/trivial-rewrite/resolve.c | 52 +++++++++++----------- postfix/src/util/cidr_match.c | 16 +++---- postfix/src/util/dict.h | 1 + postfix/src/util/match_list.c | 12 +++-- postfix/src/util/match_ops.c | 31 ++++++------- postfix/src/util/match_ops.h | 16 ++----- postfix/src/util/name_mask.c | 5 ++- 33 files changed, 296 insertions(+), 170 deletions(-) create mode 100644 postfix/src/global/maps.in create mode 100644 postfix/src/global/maps.ref create mode 100644 postfix/src/global/resolve_local.in create mode 100644 postfix/src/global/resolve_local.ref diff --git a/postfix/HISTORY b/postfix/HISTORY index e68ebd443..14141d6ed 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -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. diff --git a/postfix/README_FILES/SASL_README b/postfix/README_FILES/SASL_README index 349d3655a..282edc1d4 100644 --- a/postfix/README_FILES/SASL_README +++ b/postfix/README_FILES/SASL_README @@ -14,7 +14,7 @@ HHooww PPoossttffiixx uusseess SSAASSLL aauutthheenntti 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 diff --git a/postfix/html/SASL_README.html b/postfix/html/SASL_README.html index c73dcecbf..f76ca860f 100644 --- a/postfix/html/SASL_README.html +++ b/postfix/html/SASL_README.html @@ -28,7 +28,7 @@ considering.

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.

diff --git a/postfix/proto/SASL_README.html b/postfix/proto/SASL_README.html index 1e685eba4..a3320be86 100644 --- a/postfix/proto/SASL_README.html +++ b/postfix/proto/SASL_README.html @@ -28,7 +28,7 @@ considering.

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.

diff --git a/postfix/src/flush/flush.c b/postfix/src/flush/flush.c index a87a0f18c..9f2c5dbdb 100644 --- a/postfix/src/flush/flush.c +++ b/postfix/src/flush/flush.c @@ -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 */ diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in index 379d0e50f..6a4ee997e 100644 --- a/postfix/src/global/Makefile.in +++ b/postfix/src/global/Makefile.in @@ -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 diff --git a/postfix/src/global/addr_match_list.c b/postfix/src/global/addr_match_list.c index ad1a249e3..86cbe9c55 100644 --- a/postfix/src/global/addr_match_list.c +++ b/postfix/src/global/addr_match_list.c @@ -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); diff --git a/postfix/src/global/debug_peer.c b/postfix/src/global/debug_peer.c index bdd623beb..023e1ffda 100644 --- a/postfix/src/global/debug_peer.c +++ b/postfix/src/global/debug_peer.c @@ -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); diff --git a/postfix/src/global/domain_list.c b/postfix/src/global/domain_list.c index 57c3c1d66..79139add5 100644 --- a/postfix/src/global/domain_list.c +++ b/postfix/src/global/domain_list.c @@ -36,13 +36,12 @@ /* 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); diff --git a/postfix/src/global/flush_clnt.c b/postfix/src/global/flush_clnt.c index d7a51f9fe..e60a9e13a 100644 --- a/postfix/src/global/flush_clnt.c +++ b/postfix/src/global/flush_clnt.c @@ -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; diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 9e650de0b..c7fa9b8fe 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 diff --git a/postfix/src/global/maps.c b/postfix/src/global/maps.c index f0cb35526..fea3a6241 100644 --- a/postfix/src/global/maps.c +++ b/postfix/src/global/maps.c @@ -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 index 000000000..511516e1e --- /dev/null +++ b/postfix/src/global/maps.in @@ -0,0 +1,4 @@ +./maps fail:1maps < 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); diff --git a/postfix/src/global/resolve_local.c b/postfix/src/global/resolve_local.c index 703ec0743..09fcf94d1 100644 --- a/postfix/src/global/resolve_local.c +++ b/postfix/src/global/resolve_local.c @@ -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); } diff --git a/postfix/src/global/resolve_local.h b/postfix/src/global/resolve_local.h index 53af376d0..c7ad5e040 100644 --- a/postfix/src/global/resolve_local.h +++ b/postfix/src/global/resolve_local.h @@ -11,6 +11,11 @@ /* DESCRIPTION /* .nf + /* + * Utility library. + */ +#include + /* * External interface. */ diff --git a/postfix/src/global/resolve_local.in b/postfix/src/global/resolve_local.in new file mode 100644 index 000000000..1646fc5c3 --- /dev/null +++ b/postfix/src/global/resolve_local.in @@ -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 index 000000000..7448d98a7 --- /dev/null +++ b/postfix/src/global/resolve_local.ref @@ -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 diff --git a/postfix/src/global/server_acl.c b/postfix/src/global/server_acl.c index 8767fa470..9d9fa4950 100644 --- a/postfix/src/global/server_acl.c +++ b/postfix/src/global/server_acl.c @@ -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); diff --git a/postfix/src/global/string_list.c b/postfix/src/global/string_list.c index 9de5a5429..4b84ace9f 100644 --- a/postfix/src/global/string_list.c +++ b/postfix/src/global/string_list.c @@ -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); diff --git a/postfix/src/qmqpd/qmqpd.c b/postfix/src/qmqpd/qmqpd.c index f7145fade..e9c33e80f 100644 --- a/postfix/src/qmqpd/qmqpd.c +++ b/postfix/src/qmqpd/qmqpd.c @@ -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); diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in index 2a26b77c1..989c3c7ca 100644 --- a/postfix/src/smtpd/Makefile.in +++ b/postfix/src/smtpd/Makefile.in @@ -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 diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index f5beaf46c..2000eb2d2 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -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, diff --git a/postfix/src/smtpd/smtpd_error.in b/postfix/src/smtpd/smtpd_error.in index 257a89522..c894b874a 100644 --- a/postfix/src/smtpd/smtpd_error.in +++ b/postfix/src/smtpd/smtpd_error.in @@ -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 diff --git a/postfix/src/smtpd/smtpd_error.ref b/postfix/src/smtpd/smtpd_error.ref index cb2448c39..99126290f 100644 --- a/postfix/src/smtpd/smtpd_error.ref +++ b/postfix/src/smtpd/smtpd_error.ref @@ -106,3 +106,28 @@ OK ./smtpd_check: warning: local_header_rewrite_clients: fail:1_rewrite: lookup error ./smtpd_check: : reject: RCPT from foo.dunno.com[131.155.210.17]: 451 4.3.0 Temporary lookup error; from=<> proto=SMTP helo= 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: : reject: RCPT from foo.dunno.com[131.155.210.17]: 451 4.3.0 : Temporary lookup failure; from=<> to= proto=SMTP helo= +451 4.3.0 : Temporary lookup failure +>>> # +>>> # Test virtual alias lookup. +>>> # +>>> mydestination example.com +OK +>>> virtual_alias_maps fail:1_virtual +OK +>>> rcpt user@example.com +./smtpd_check: : reject: RCPT from foo.dunno.com[131.155.210.17]: 451 4.3.0 : Temporary lookup failure; from=<> to= proto=SMTP helo= +451 4.3.0 : Temporary lookup failure diff --git a/postfix/src/trivial-rewrite/resolve.c b/postfix/src/trivial-rewrite/resolve.c index 2ed395561..315799307 100644 --- a/postfix/src/trivial-rewrite/resolve.c +++ b/postfix/src/trivial-rewrite/resolve.c @@ -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); diff --git a/postfix/src/util/cidr_match.c b/postfix/src/util/cidr_match.c index 9ca016b95..b72b8db3e 100644 --- a/postfix/src/util/cidr_match.c +++ b/postfix/src/util/cidr_match.c @@ -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; diff --git a/postfix/src/util/dict.h b/postfix/src/util/dict.h index ed08a9a3c..b7811b7e2 100644 --- a/postfix/src/util/dict.h +++ b/postfix/src/util/dict.h @@ -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. diff --git a/postfix/src/util/match_list.c b/postfix/src/util/match_list.c index 6f76dafe7..195280f26 100644 --- a/postfix/src/util/match_list.c +++ b/postfix/src/util/match_list.c @@ -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++) diff --git a/postfix/src/util/match_ops.c b/postfix/src/util/match_ops.c index d1cf85053..84c6cb322 100644 --- a/postfix/src/util/match_ops.c +++ b/postfix/src/util/match_ops.c @@ -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. @@ -86,17 +86,11 @@ /* 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); } diff --git a/postfix/src/util/match_ops.h b/postfix/src/util/match_ops.h index a98b8c089..055c4f7dd 100644 --- a/postfix/src/util/match_ops.h +++ b/postfix/src/util/match_ops.h @@ -12,28 +12,18 @@ /* .nf /* - * External interface. + * Utility library. */ +#include /* - * 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 *); diff --git a/postfix/src/util/name_mask.c b/postfix/src/util/name_mask.c index ee4615504..454e5bfd7 100644 --- a/postfix/src/util/name_mask.c +++ b/postfix/src/util/name_mask.c @@ -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\"",