From: Wietse Venema Date: Tue, 10 Jan 2012 05:00:00 +0000 (-0500) Subject: postfix-2.9-20120110 X-Git-Tag: v2.9.0-RC1~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c10338d5472ad8968afb61640a90559ae5eced49;p=thirdparty%2Fpostfix.git postfix-2.9-20120110 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index d2ae3b1ef..9f3659ac1 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -17499,3 +17499,15 @@ Apologies for any names omitted. operation, to avoid logging large numbers of warnings about a problem with low-value information. File: util/msg_rate_delay.c, util/dict_cache.c. + +20120110 + + Cleanup: added logging for failed table lookups and replaced + some "fatal" errors by warnings. Files: cleanup/cleanup_addr.c, + cleanup/cleanup_message.c, cleanup/cleanup_milter.c, + cleanup/cleanup_masquerade.c, global/header_body_checks.c, + global/smtp_stream.c, postscreen/postscreen_dnsbl.c, + postscreen/postscreen_smtpd.c, smtp/smtp_chat.c, + smtp/smtp_proto.c, smtp/smtp_sasl_auth_cache.c, + smtp/smtp_sasl_glue.c, smtp/smtp_session.c, smtp/smtp_trouble.c, + smtpd/smtpd.c, smtpd/smtpd_check.c. diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index ae73b5015..4492293bd 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -14,6 +14,43 @@ specifies the release date of a stable release or snapshot release. If you upgrade from Postfix 2.7 or earlier, read RELEASE_NOTES-2.8 before proceeding. +Major changes with snapshot 20111208 +==================================== + +The LDAP, *SQL and memcache clients now "catch" table lookup errors +in the "domain" feature, instead of terminating with a fatal error. + +Major changes with snapshot 20111202 +==================================== + +Degrade gracefully when some or all network protocols specified +with inet_protocols are unavailable, instead of terminating with a +fatal error. This eliminates build errors on non-standard systems +where opening an IPv4 socket results in an error, and on non-standard +systems where opening an IPv6 socket results in an error. In the +worst case, the master daemon will log a message that it disables +all type "inet" services. This will still allow local submission +and local delivery. + +Major changes with snapshot 20111222 +==================================== + +The Postfix SMTP server now "catches" errors with database lookups +in mynetworks, TLS client certificate tables, debug_peer_list, +smtpd_client_event_limit_exceptions, permit_mx_backup_networks and +local_header_rewrite_clients, and reports "server configuration +error" or "table lookup error" instead of terminating with a fatal +error. + +Major changes with snapshot 20111229 +==================================== + +The trivial-rewrite server now "catches" errors with database lookups +in virtual_alias_domains, relay_domains, virtual_mailbox_domains, +instead of terminating with a fatal error. This means fewer occasions +where trivial-rewrite clients (such as the SMTP server) will appear +to hang. + Incompatible changes with snapshot 20111218 =========================================== @@ -26,7 +63,7 @@ Major changes with snapshot 20111218 Support for external SASL authentication via the XCLIENT command. This is used to accept SASL authentication from an SMTP proxy such -as nginx. This support works even without having to specify +as NGINX. This support works even without having to specify "smtpd_sasl_auth_enable = yes" in main.cf. Major changes with snapshot 20111213 diff --git a/postfix/WISHLIST b/postfix/WISHLIST index c201dae89..394eea47c 100644 --- a/postfix/WISHLIST +++ b/postfix/WISHLIST @@ -4,6 +4,9 @@ Wish list: Remove this file from the stable release. + In daemons, open surrogate map when real map is unavailable, + effectively redirecting to fail:. + Things to do after the stable release: Before proxymap can be exposed to the network to share, diff --git a/postfix/src/cleanup/Makefile.in b/postfix/src/cleanup/Makefile.in index 0dbbc1be5..c447f198b 100644 --- a/postfix/src/cleanup/Makefile.in +++ b/postfix/src/cleanup/Makefile.in @@ -96,6 +96,7 @@ cleanup_masquerade_test: cleanup_masquerade cleanup_masq.ref ./cleanup_masquerade '' !a.b.c,b.c xxx@a.b.c >>cleanup_masq.tmp ./cleanup_masquerade '' a.b.c,b.c xxx@aaa.b.c >>cleanup_masq.tmp ./cleanup_masquerade '' a.b.c,b.c xxx@b.c >>cleanup_masq.tmp + ./cleanup_masquerade 'fail:whatever' xy xxx@b.c >>cleanup_masq.tmp diff cleanup_masq.ref cleanup_masq.tmp rm -f cleanup_masq.tmp diff --git a/postfix/src/cleanup/cleanup.h b/postfix/src/cleanup/cleanup.h index a962f0078..9b9d6279d 100644 --- a/postfix/src/cleanup/cleanup.h +++ b/postfix/src/cleanup/cleanup.h @@ -270,9 +270,9 @@ ARGV *cleanup_map1n_internal(CLEANUP_STATE *, const char *, MAPS *, int); /* * cleanup_masquerade.c */ -extern int cleanup_masquerade_external(VSTRING *, ARGV *); -extern int cleanup_masquerade_internal(VSTRING *, ARGV *); -extern int cleanup_masquerade_tree(TOK822 *, ARGV *); +extern int cleanup_masquerade_external(CLEANUP_STATE *, VSTRING *, ARGV *); +extern int cleanup_masquerade_internal(CLEANUP_STATE *, VSTRING *, ARGV *); +extern int cleanup_masquerade_tree(CLEANUP_STATE *, TOK822 *, ARGV *); /* * cleanup_recipient.c diff --git a/postfix/src/cleanup/cleanup_addr.c b/postfix/src/cleanup/cleanup_addr.c index dc87f5c95..233ba37ca 100644 --- a/postfix/src/cleanup/cleanup_addr.c +++ b/postfix/src/cleanup/cleanup_addr.c @@ -136,7 +136,7 @@ void cleanup_addr_sender(CLEANUP_STATE *state, const char *buf) cleanup_ext_prop_mask & EXT_PROP_CANONICAL); if (cleanup_masq_domains && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_FROM)) - cleanup_masquerade_internal(clean_addr, cleanup_masq_domains); + cleanup_masquerade_internal(state, clean_addr, cleanup_masq_domains); } CLEANUP_OUT_BUF(state, REC_TYPE_FROM, clean_addr); if (state->sender) /* XXX Can't happen */ @@ -144,10 +144,16 @@ void cleanup_addr_sender(CLEANUP_STATE *state, const char *buf) state->sender = mystrdup(STR(clean_addr)); /* Used by Milter client */ if ((state->flags & CLEANUP_FLAG_BCC_OK) && *STR(clean_addr) - && cleanup_send_bcc_maps - && (bcc = mail_addr_find(cleanup_send_bcc_maps, STR(clean_addr), - IGNORE_EXTENSION)) != 0) - cleanup_addr_bcc(state, bcc); + && cleanup_send_bcc_maps) { + if ((bcc = mail_addr_find(cleanup_send_bcc_maps, STR(clean_addr), + IGNORE_EXTENSION)) != 0) { + cleanup_addr_bcc(state, bcc); + } else if (cleanup_send_bcc_maps->error) { + msg_warn("%s: %s lookup problem", + state->queue_id, cleanup_send_bcc_maps->title); + state->errs |= CLEANUP_STAT_WRITE; + } + } vstring_free(clean_addr); } @@ -178,7 +184,7 @@ void cleanup_addr_recipient(CLEANUP_STATE *state, const char *buf) cleanup_ext_prop_mask & EXT_PROP_CANONICAL); if (cleanup_masq_domains && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT)) - cleanup_masquerade_internal(clean_addr, cleanup_masq_domains); + cleanup_masquerade_internal(state, clean_addr, cleanup_masq_domains); } cleanup_out_recipient(state, state->dsn_orcpt, state->dsn_notify, state->orig_rcpt, STR(clean_addr)); @@ -187,17 +193,23 @@ void cleanup_addr_recipient(CLEANUP_STATE *state, const char *buf) state->recip = mystrdup(STR(clean_addr)); /* Used by Milter client */ if ((state->flags & CLEANUP_FLAG_BCC_OK) && *STR(clean_addr) - && cleanup_rcpt_bcc_maps - && (bcc = mail_addr_find(cleanup_rcpt_bcc_maps, STR(clean_addr), - IGNORE_EXTENSION)) != 0) - cleanup_addr_bcc(state, bcc); + && cleanup_rcpt_bcc_maps) { + if ((bcc = mail_addr_find(cleanup_rcpt_bcc_maps, STR(clean_addr), + IGNORE_EXTENSION)) != 0) { + cleanup_addr_bcc(state, bcc); + } else if (cleanup_rcpt_bcc_maps->error) { + msg_warn("%s: %s lookup problem", + state->queue_id, cleanup_rcpt_bcc_maps->title); + state->errs |= CLEANUP_STAT_WRITE; + } + } vstring_free(clean_addr); } /* cleanup_addr_bcc_dsn - process automatic BCC recipient */ void cleanup_addr_bcc_dsn(CLEANUP_STATE *state, const char *bcc, - const char *dsn_orcpt, int dsn_notify) + const char *dsn_orcpt, int dsn_notify) { VSTRING *clean_addr = vstring_alloc(100); @@ -217,7 +229,7 @@ void cleanup_addr_bcc_dsn(CLEANUP_STATE *state, const char *bcc, cleanup_ext_prop_mask & EXT_PROP_CANONICAL); if (cleanup_masq_domains && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_ENV_RCPT)) - cleanup_masquerade_internal(clean_addr, cleanup_masq_domains); + cleanup_masquerade_internal(state, clean_addr, cleanup_masq_domains); } cleanup_out_recipient(state, dsn_orcpt, dsn_notify, STR(clean_addr), STR(clean_addr)); diff --git a/postfix/src/cleanup/cleanup_init.c b/postfix/src/cleanup/cleanup_init.c index bc4eb9ffd..47ed5cf81 100644 --- a/postfix/src/cleanup/cleanup_init.c +++ b/postfix/src/cleanup/cleanup_init.c @@ -375,7 +375,7 @@ void cleanup_pre_jail(char *unused_name, char **unused_argv) maps_create(VAR_BODY_CHECKS, var_body_checks, DICT_FLAG_LOCK); if (*var_masq_exceptions) cleanup_masq_exceptions = - string_list_init(MATCH_FLAG_NONE, var_masq_exceptions); + string_list_init(MATCH_FLAG_RETURN, var_masq_exceptions); if (*var_masq_classes) cleanup_masq_flags = name_mask(VAR_MASQ_CLASSES, masq_class_table, var_masq_classes); diff --git a/postfix/src/cleanup/cleanup_masq.ref b/postfix/src/cleanup/cleanup_masq.ref index 98dde745c..80dd26fe5 100644 --- a/postfix/src/cleanup/cleanup_masq.ref +++ b/postfix/src/cleanup/cleanup_masq.ref @@ -3,38 +3,52 @@ exceptions: masq_list: a.b.c,b.c address: xxx@aa.a.b.c result: xxx@a.b.c +errs: 0 ---------- exceptions: xxx masq_list: a.b.c,b.c address: xxx@aa.a.b.c result: xxx@aa.a.b.c +errs: 0 ---------- exceptions: yyy masq_list: a.b.c,b.c address: xxx@aa.a.b.c result: xxx@a.b.c +errs: 0 ---------- exceptions: masq_list: !a.b.c,b.c address: xxx@aa.a.b.c result: xxx@aa.a.b.c +errs: 0 ---------- exceptions: masq_list: a.b.c,b.c address: xxx@a.b.c result: xxx@a.b.c +errs: 0 ---------- exceptions: masq_list: !a.b.c,b.c address: xxx@a.b.c result: xxx@a.b.c +errs: 0 ---------- exceptions: masq_list: a.b.c,b.c address: xxx@aaa.b.c result: xxx@b.c +errs: 0 ---------- exceptions: masq_list: a.b.c,b.c address: xxx@b.c result: xxx@b.c +errs: 0 +---------- +exceptions: fail:whatever +masq_list: xy +address: xxx@b.c +result: xxx@b.c +errs: 2 diff --git a/postfix/src/cleanup/cleanup_masquerade.c b/postfix/src/cleanup/cleanup_masquerade.c index 0a4fededb..70577da1e 100644 --- a/postfix/src/cleanup/cleanup_masquerade.c +++ b/postfix/src/cleanup/cleanup_masquerade.c @@ -78,7 +78,8 @@ /* cleanup_masquerade_external - masquerade address external form */ -int cleanup_masquerade_external(VSTRING *addr, ARGV *masq_domains) +int cleanup_masquerade_external(CLEANUP_STATE *state, VSTRING *addr, + ARGV *masq_domains) { char *domain; ssize_t domain_len; @@ -108,6 +109,11 @@ int cleanup_masquerade_external(VSTRING *addr, ARGV *masq_domains) name = mystrndup(STR(addr), domain - 1 - STR(addr)); excluded = (string_list_match(cleanup_masq_exceptions, lowercase(name)) != 0); myfree(name); + if (cleanup_masq_exceptions->error) { + msg_info("%s: %s lookup error -- deferring delivery", + state->queue_id, VAR_MASQ_EXCEPTIONS); + state->errs |= CLEANUP_STAT_WRITE; + } if (excluded) return (0); } @@ -145,13 +151,14 @@ int cleanup_masquerade_external(VSTRING *addr, ARGV *masq_domains) /* cleanup_masquerade_tree - masquerade address node */ -int cleanup_masquerade_tree(TOK822 *tree, ARGV *masq_domains) +int cleanup_masquerade_tree(CLEANUP_STATE *state, TOK822 *tree, + ARGV *masq_domains) { VSTRING *temp = vstring_alloc(100); int did_rewrite; tok822_externalize(temp, tree->head, TOK822_STR_DEFL); - did_rewrite = cleanup_masquerade_external(temp, masq_domains); + did_rewrite = cleanup_masquerade_external(state, temp, masq_domains); tok822_free_tree(tree->head); tree->head = tok822_scan(STR(temp), &tree->tail); @@ -161,13 +168,14 @@ int cleanup_masquerade_tree(TOK822 *tree, ARGV *masq_domains) /* cleanup_masquerade_internal - masquerade address internal form */ -int cleanup_masquerade_internal(VSTRING *addr, ARGV *masq_domains) +int cleanup_masquerade_internal(CLEANUP_STATE *state, VSTRING *addr, + ARGV *masq_domains) { VSTRING *temp = vstring_alloc(100); int did_rewrite; quote_822_local(temp, STR(addr)); - did_rewrite = cleanup_masquerade_external(temp, masq_domains); + did_rewrite = cleanup_masquerade_external(state, temp, masq_domains); unquote_822_local(addr, STR(temp)); vstring_free(temp); @@ -190,13 +198,14 @@ int main(int argc, char **argv) { VSTRING *addr; ARGV *masq_domains; + CLEANUP_STATE state; if (argc != 4) msg_fatal("usage: %s exceptions masquerade_list address", argv[0]); var_masq_exceptions = argv[1]; cleanup_masq_exceptions = - string_list_init(MATCH_FLAG_NONE, var_masq_exceptions); + string_list_init(MATCH_FLAG_RETURN, var_masq_exceptions); masq_domains = argv_split(argv[2], " ,\t\r\n"); addr = vstring_alloc(1); if (strchr(argv[3], '@') == 0) @@ -208,9 +217,11 @@ int main(int argc, char **argv) vstream_printf("masq_list: %s\n", argv[2]); vstream_printf("address: %s\n", argv[3]); - cleanup_masquerade_external(addr, masq_domains); + state.errs = 0; + cleanup_masquerade_external(&state, addr, masq_domains); vstream_printf("result: %s\n", STR(addr)); + vstream_printf("errs: %d\n", state.errs); vstream_fflush(VSTREAM_OUT); vstring_free(addr); diff --git a/postfix/src/cleanup/cleanup_message.c b/postfix/src/cleanup/cleanup_message.c index 6e2b85a04..ffb5c7e52 100644 --- a/postfix/src/cleanup/cleanup_message.c +++ b/postfix/src/cleanup/cleanup_message.c @@ -169,7 +169,7 @@ static void cleanup_rewrite_sender(CLEANUP_STATE *state, if (cleanup_masq_domains && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_HDR_FROM)) did_rewrite |= - cleanup_masquerade_tree(*tpp, cleanup_masq_domains); + cleanup_masquerade_tree(state, *tpp, cleanup_masq_domains); } } if (did_rewrite) { @@ -226,7 +226,7 @@ static void cleanup_rewrite_recip(CLEANUP_STATE *state, if (cleanup_masq_domains && (cleanup_masq_flags & CLEANUP_MASQ_FLAG_HDR_RCPT)) did_rewrite |= - cleanup_masquerade_tree(*tpp, cleanup_masq_domains); + cleanup_masquerade_tree(state, *tpp, cleanup_masq_domains); } } if (did_rewrite) { @@ -498,6 +498,10 @@ static void cleanup_header_callback(void *context, int header_class, hdr_opts = header_opts_find(result); myfree((char *) result); } + } else if (checks->error) { + msg_warn("%s: %s map lookup problem -- deferring delivery", + state->queue_id, checks->title); + state->errs |= CLEANUP_STAT_WRITE; } } @@ -784,6 +788,10 @@ static void cleanup_body_callback(void *context, int type, myfree((char *) result); return; } + } else if (cleanup_body_checks->error) { + msg_warn("%s: %s map lookup problem -- deferring delivery", + state->queue_id, cleanup_body_checks->title); + state->errs |= CLEANUP_STAT_WRITE; } } cleanup_out(state, type, buf, len); diff --git a/postfix/src/cleanup/cleanup_milter.c b/postfix/src/cleanup/cleanup_milter.c index e29feebed..cc63313f1 100644 --- a/postfix/src/cleanup/cleanup_milter.c +++ b/postfix/src/cleanup/cleanup_milter.c @@ -391,6 +391,11 @@ static int cleanup_milter_header_checks(CLEANUP_STATE *state, VSTRING *buf) buf, (off_t) 0); if (ret == 0) { return (0); + } else if (ret == HBC_CHECKS_STAT_ERROR) { + msg_warn("%s: %s lookup error -- deferring delivery", + state->queue_id, VAR_MILT_HEAD_CHECKS); + state->errs |= CLEANUP_STAT_WRITE; + return (0); } else { if (ret != STR(buf)) { vstring_strcpy(buf, ret); diff --git a/postfix/src/flush/flush.c b/postfix/src/flush/flush.c index 9f2c5dbdb..22c1a8365 100644 --- a/postfix/src/flush/flush.c +++ b/postfix/src/flush/flush.c @@ -276,13 +276,6 @@ static VSTRING *flush_site_to_path(VSTRING *path, const char *site) return (path); } -/* flush_policy_ok - check logging policy */ - -static int flush_policy_ok(const char *site) -{ - return (domain_list_match(flush_domains, site)); -} - /* flush_add_service - append queue ID to per-site fast flush logfile */ static int flush_add_service(const char *site, const char *queue_id) @@ -297,8 +290,8 @@ static int flush_add_service(const char *site, const char *queue_id) /* * If this site is not eligible for logging, deny the request. */ - if (flush_policy_ok(site) == 0) - return (FLUSH_STAT_DENY); + if (domain_list_match(flush_domains, site) == 0) + return (flush_domains->error ? FLUSH_STAT_FAIL : FLUSH_STAT_DENY); /* * Map site to path and update log. @@ -373,8 +366,8 @@ static int flush_send_service(const char *site, int how) /* * If this site is not eligible for logging, deny the request. */ - if (flush_policy_ok(site) == 0) - return (FLUSH_STAT_DENY); + if (domain_list_match(flush_domains, site) == 0) + return (flush_domains->error ? FLUSH_STAT_FAIL : FLUSH_STAT_DENY); /* * Map site name to path name and flush the log. diff --git a/postfix/src/global/dict_memcache.c b/postfix/src/global/dict_memcache.c index a60a20e8d..d6df42996 100644 --- a/postfix/src/global/dict_memcache.c +++ b/postfix/src/global/dict_memcache.c @@ -463,10 +463,11 @@ static int dict_memcache_sequence(DICT *dict, int function, const char **key, DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, DICT_STAT_FAIL); } else { seq_res = backup->sequence(backup, function, key, value); - msg_info("%s: %s: key \"%s\" => %s", - myname, dict_mc->dict.name, *key ? *key : "(not found)", - *value ? *value : backup->error ? "(backup error)" : - "(not found)"); + if (msg_verbose) + msg_info("%s: %s: key \"%s\" => %s", + myname, dict_mc->dict.name, *key ? *key : "(not found)", + *value ? *value : backup->error ? "(backup error)" : + "(not found)"); DICT_ERR_VAL_RETURN(dict, backup->error, seq_res); } } diff --git a/postfix/src/global/header_body_checks.c b/postfix/src/global/header_body_checks.c index c6c894e4d..b423e8eb7 100644 --- a/postfix/src/global/header_body_checks.c +++ b/postfix/src/global/header_body_checks.c @@ -77,13 +77,14 @@ /* not be called. /* /* hbc_header_checks() inspects the specified logical header. -/* The result is either the original header, HBC_CHECK_STAT_IGNORE -/* (meaning: discard the header) or a new header (meaning: -/* replace the header and destroy the new header with myfree()). +/* The result is either the original header, HBC_CHECKS_STAT_IGNORE +/* (meaning: discard the header), HBC_CHECKS_STAT_ERROR, or a +/* new header (meaning: replace the header and destroy the new +/* header with myfree()). /* /* hbc_header_checks_free() returns memory to the pool. /* -/* hbc_body_checks_create(), dbhc_body_checks(), dbhc_body_free() +/* hbc_body_checks_create(), hbc_body_checks(), hbc_body_free() /* perform similar functions for body lines. /* /* Arguments: @@ -184,6 +185,7 @@ * Something that is guaranteed to be different from a real string result * from header/body_checks. */ +char hbc_checks_error; const char hbc_checks_unknown; /* @@ -318,6 +320,8 @@ char *hbc_header_checks(void *context, HBC_CHECKS *hbc, int header_class, return (hbc_action(context, hbc->call_backs, mp->map_class, HBC_CTXT_HEADER, action, STR(header), LEN(header), offset)); + } else if (mp->maps && mp->maps->error) { + return (HBC_CHECKS_STAT_ERROR); } else { return (STR(header)); } @@ -341,6 +345,8 @@ char *hbc_body_checks(void *context, HBC_CHECKS *hbc, const char *line, return (hbc_action(context, hbc->call_backs, mp->map_class, HBC_CTXT_BODY, action, line, len, offset)); + } else if (mp->maps->error) { + return (HBC_CHECKS_STAT_ERROR); } else { return ((char *) line); } diff --git a/postfix/src/global/header_body_checks.h b/postfix/src/global/header_body_checks.h index f397ae2a7..f4c642bc4 100644 --- a/postfix/src/global/header_body_checks.h +++ b/postfix/src/global/header_body_checks.h @@ -45,6 +45,7 @@ typedef struct { } HBC_CHECKS; #define HBC_CHECKS_STAT_IGNORE ((char *) 0) +#define HBC_CHECKS_STAT_ERROR (&hbc_checks_error) #define HBC_CHECKS_STAT_UNKNOWN (&hbc_checks_unknown) extern HBC_CHECKS *hbc_header_checks_create(const char *, const char *, @@ -65,6 +66,7 @@ extern char *hbc_body_checks(void *, HBC_CHECKS *, const char *, ssize_t, off_t) */ #define HBC_HEADER_SIZE (MIME_HDR_LAST - MIME_HDR_FIRST + 1) extern void _hbc_checks_free(HBC_CHECKS *, ssize_t); +extern char hbc_checks_error; extern const char hbc_checks_unknown; /* LICENSE diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index bcb8857fc..a69bbad89 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 "20120108" +#define MAIL_RELEASE_DATE "20120110" #define MAIL_VERSION_NUMBER "2.9" #ifdef SNAPSHOT diff --git a/postfix/src/global/maps.c b/postfix/src/global/maps.c index 6f19eb8fc..391a80019 100644 --- a/postfix/src/global/maps.c +++ b/postfix/src/global/maps.c @@ -126,6 +126,7 @@ MAPS *maps_create(const char *title, const char *map_names, int dict_flags) maps = (MAPS *) mymalloc(sizeof(*maps)); maps->title = mystrdup(title); maps->argv = argv_alloc(2); + maps->error = 0; /* * For each specified type:name pair, either register a new dictionary, @@ -195,7 +196,8 @@ const char *maps_find(MAPS *maps, const char *name, int flags) *map_name, name, expansion); return (expansion); } else if ((maps->error = dict->error) != 0) { - msg_warn("%s:%s lookup of %s failed", dict->type, dict->name, name); + msg_warn("%s:%s lookup error for \"%.100s\"", + dict->type, dict->name, name); break; } } diff --git a/postfix/src/global/smtp_stream.c b/postfix/src/global/smtp_stream.c index 385a831d7..fb68e5057 100644 --- a/postfix/src/global/smtp_stream.c +++ b/postfix/src/global/smtp_stream.c @@ -122,6 +122,9 @@ /* the application. /* This error is never generated by the smtp_stream(3) module, but /* is defined for application-specific use. +/* .IP SMTP_ERR_APPL +/* Application error - the program cannot proceed with this +/* SMTP session. /* .IP SMTP_ERR_NONE /* A non-error code that makes setjmp()/longjmp() convenient /* to use. diff --git a/postfix/src/global/smtp_stream.h b/postfix/src/global/smtp_stream.h index af8cdbe9e..599bcfa29 100644 --- a/postfix/src/global/smtp_stream.h +++ b/postfix/src/global/smtp_stream.h @@ -31,6 +31,7 @@ #define SMTP_ERR_TIME 2 /* time out */ #define SMTP_ERR_QUIET 3 /* silent cleanup (application) */ #define SMTP_ERR_NONE 4 /* non-error case */ +#define SMTP_ERR_APPL 5 /* application error - can't proceed */ extern void smtp_stream_setup(VSTREAM *, int, int); extern void PRINTFLIKE(2, 3) smtp_printf(VSTREAM *, const char *,...); diff --git a/postfix/src/local/Makefile.in b/postfix/src/local/Makefile.in index 503e502e6..42ce2dc50 100644 --- a/postfix/src/local/Makefile.in +++ b/postfix/src/local/Makefile.in @@ -591,6 +591,7 @@ unknown.o: ../../include/argv.h unknown.o: ../../include/attr.h unknown.o: ../../include/been_here.h unknown.o: ../../include/bounce.h +unknown.o: ../../include/defer.h unknown.o: ../../include/deliver_pass.h unknown.o: ../../include/deliver_request.h unknown.o: ../../include/delivered_hdr.h diff --git a/postfix/src/local/unknown.c b/postfix/src/local/unknown.c index 91c338c1b..9c3d185f8 100644 --- a/postfix/src/local/unknown.c +++ b/postfix/src/local/unknown.c @@ -72,6 +72,7 @@ #include #include #include +#include /* Application-specific. */ diff --git a/postfix/src/postalias/fail_test.ref b/postfix/src/postalias/fail_test.ref index 64d2eef68..37ebce6b3 100644 --- a/postfix/src/postalias/fail_test.ref +++ b/postfix/src/postalias/fail_test.ref @@ -1,7 +1,7 @@ -postalias: fatal: fail:aliases: query error: Unknown error: 0 -postalias: fatal: fail:aliases: query error: Unknown error: 0 -postalias: fatal: fail:aliases: delete error: Unknown error: 0 -postalias: fatal: fail:aliases: delete error: Unknown error: 0 -postalias: fatal: fail:aliases: sequence error: Unknown error: 0 -postalias: fatal: fail:aliases: write error: Unknown error: 0 -postalias: fatal: fail:aliases: write error: Unknown error: 0 +postalias: fatal: table fail:aliases: query error: Unknown error: 0 +postalias: fatal: table fail:aliases: query error: Unknown error: 0 +postalias: fatal: table fail:aliases: delete error: Unknown error: 0 +postalias: fatal: table fail:aliases: delete error: Unknown error: 0 +postalias: fatal: table fail:aliases: sequence error: Unknown error: 0 +postalias: fatal: table fail:aliases: write error: Unknown error: 0 +postalias: fatal: table fail:aliases: write error: Unknown error: 0 diff --git a/postfix/src/postalias/postalias.c b/postfix/src/postalias/postalias.c index a031ef73d..cc190b416 100644 --- a/postfix/src/postalias/postalias.c +++ b/postfix/src/postalias/postalias.c @@ -381,7 +381,7 @@ static void postalias(char *map_type, char *path_name, int postalias_flags, */ mkmap_append(mkmap, STR(key_buffer), STR(value_buffer)); if (mkmap->dict->error) - msg_fatal("%s:%s: write error: %m", + msg_fatal("table %s:%s: write error: %m", mkmap->dict->type, mkmap->dict->name); } @@ -398,7 +398,7 @@ static void postalias(char *map_type, char *path_name, int postalias_flags, */ mkmap_append(mkmap, "@", "@"); if (mkmap->dict->error) - msg_fatal("%s:%s: write error: %m", + msg_fatal("table %s:%s: write error: %m", mkmap->dict->type, mkmap->dict->name); /* @@ -477,7 +477,7 @@ static int postalias_queries(VSTREAM *in, char **maps, const int map_count, break; } if (dicts[n]->error) - msg_fatal("%s:%s: query error: %m", + msg_fatal("table %s:%s: query error: %m", dicts[n]->type, dicts[n]->name); } } @@ -515,7 +515,7 @@ static int postalias_query(const char *map_type, const char *map_name, vstream_printf("%s\n", value); } if (dict->error) - msg_fatal("%s:%s: query error: %m", dict->type, dict->name); + msg_fatal("table %s:%s: query error: %m", dict->type, dict->name); vstream_fflush(VSTREAM_OUT); dict_close(dict); return (value != 0); @@ -560,10 +560,10 @@ static int postalias_deletes(VSTREAM *in, char **maps, const int map_count, while (vstring_get_nonl(keybuf, in) != VSTREAM_EOF) { for (n = 0; n < map_count; n++) { found |= (dict_del(dicts[n], STR(keybuf)) == 0); - if (dicts[n]->error) - msg_fatal("%s:%s: delete error: %m", - dicts[n]->type, dicts[n]->name); - } + if (dicts[n]->error) + msg_fatal("table %s:%s: delete error: %m", + dicts[n]->type, dicts[n]->name); + } } /* @@ -594,7 +594,7 @@ static int postalias_delete(const char *map_type, const char *map_name, dict = dict_open3(map_type, map_name, open_flags, dict_flags); status = dict_del(dict, key); if (dict->error) - msg_fatal("%s:%s: delete error: %m", dict->type, dict->name); + msg_fatal("table %s:%s: delete error: %m", dict->type, dict->name); dict_close(dict); return (status == 0); } @@ -627,7 +627,7 @@ static void postalias_seq(const char *map_type, const char *map_name, vstream_printf("%s: %s\n", key, value); } if (dict->error) - msg_fatal("%s:%s: sequence error: %m", dict->type, dict->name); + msg_fatal("table %s:%s: sequence error: %m", dict->type, dict->name); vstream_fflush(VSTREAM_OUT); dict_close(dict); } diff --git a/postfix/src/postmap/fail_test.in b/postfix/src/postmap/fail_test.in index b62c3c5d7..a1c6b7c58 100644 --- a/postfix/src/postmap/fail_test.in +++ b/postfix/src/postmap/fail_test.in @@ -1,5 +1,6 @@ ./postmap -q xx fail:aliases echo xx | ./postmap -q - fail:aliases +echo xx | ./postmap -bq - fail:aliases ./postmap -d xx fail:aliases echo xx | ./postmap -d - fail:aliases ./postmap -s fail:aliases diff --git a/postfix/src/postmap/fail_test.ref b/postfix/src/postmap/fail_test.ref index b9a92da07..eb3e5967c 100644 --- a/postfix/src/postmap/fail_test.ref +++ b/postfix/src/postmap/fail_test.ref @@ -1,7 +1,8 @@ -postmap: fatal: fail:aliases: query error: Unknown error: 0 -postmap: fatal: fail:aliases: query error: Unknown error: 0 -postmap: fatal: fail:aliases: delete error: Unknown error: 0 -postmap: fatal: fail:aliases: delete error: Unknown error: 0 -postmap: fatal: fail:aliases: sequence error: Unknown error: 0 -postmap: fatal: fail:aliases: write error: Unknown error: 0 -postmap: fatal: fail:aliases: write error: Unknown error: 0 +postmap: fatal: table fail:aliases: query error: Unknown error: 0 +postmap: fatal: table fail:aliases: query error: Unknown error: 0 +postmap: fatal: table fail:aliases: query error: Unknown error: 0 +postmap: fatal: table fail:aliases: delete error: Unknown error: 0 +postmap: fatal: table fail:aliases: delete error: Unknown error: 0 +postmap: fatal: table fail:aliases: sequence error: Unknown error: 0 +postmap: fatal: table fail:aliases: write error: Unknown error: 0 +postmap: fatal: table fail:aliases: write error: Unknown error: 0 diff --git a/postfix/src/postmap/postmap.c b/postfix/src/postmap/postmap.c index 22718dd65..4781d5211 100644 --- a/postfix/src/postmap/postmap.c +++ b/postfix/src/postmap/postmap.c @@ -416,7 +416,7 @@ static void postmap(char *map_type, char *path_name, int postmap_flags, */ mkmap_append(mkmap, key, value); if (mkmap->dict->error) - msg_fatal("%s:%s: write error: %m", + msg_fatal("table %s:%s: write error: %m", mkmap->dict->type, mkmap->dict->name); } @@ -466,7 +466,7 @@ static void postmap_body(void *ptr, int unused_rec_type, break; } if (dicts[n]->error) - msg_fatal("%s:%s: query error: %m", + msg_fatal("table %s:%s: query error: %m", dicts[n]->type, dicts[n]->name); } } @@ -546,7 +546,7 @@ static int postmap_queries(VSTREAM *in, char **maps, const int map_count, break; } if (dicts[n]->error) - msg_fatal("%s:%s: query error: %m", + msg_fatal("table %s:%s: query error: %m", dicts[n]->type, dicts[n]->name); } } @@ -630,7 +630,7 @@ static int postmap_query(const char *map_type, const char *map_name, vstream_printf("%s\n", value); } if (dict->error) - msg_fatal("%s:%s: query error: %m", dict->type, dict->name); + msg_fatal("table %s:%s: query error: %m", dict->type, dict->name); vstream_fflush(VSTREAM_OUT); dict_close(dict); return (value != 0); @@ -676,7 +676,7 @@ static int postmap_deletes(VSTREAM *in, char **maps, const int map_count, for (n = 0; n < map_count; n++) { found |= (dict_del(dicts[n], STR(keybuf)) == 0); if (dicts[n]->error) - msg_fatal("%s:%s: delete error: %m", + msg_fatal("table %s:%s: delete error: %m", dicts[n]->type, dicts[n]->name); } } @@ -709,7 +709,7 @@ static int postmap_delete(const char *map_type, const char *map_name, dict = dict_open3(map_type, map_name, open_flags, dict_flags); status = dict_del(dict, key); if (dict->error) - msg_fatal("%s:%s: delete error: %m", dict->type, dict->name); + msg_fatal("table %s:%s: delete error: %m", dict->type, dict->name); dict_close(dict); return (status == 0); } @@ -742,7 +742,7 @@ static void postmap_seq(const char *map_type, const char *map_name, vstream_printf("%s %s\n", key, value); } if (dict->error) - msg_fatal("%s:%s: sequence error: %m", dict->type, dict->name); + msg_fatal("table %s:%s: sequence error: %m", dict->type, dict->name); vstream_fflush(VSTREAM_OUT); dict_close(dict); } diff --git a/postfix/src/postscreen/postscreen_dnsbl.c b/postfix/src/postscreen/postscreen_dnsbl.c index a57f20ef4..b85a9da93 100644 --- a/postfix/src/postscreen/postscreen_dnsbl.c +++ b/postfix/src/postscreen/postscreen_dnsbl.c @@ -261,6 +261,9 @@ static void psc_dnsbl_add_site(const char *site) if (psc_dnsbl_reply == 0 || (head->safe_dnsbl = dict_get(psc_dnsbl_reply, saved_site)) == 0) head->safe_dnsbl = ht->key; + if (psc_dnsbl_reply && psc_dnsbl_reply->error) + msg_fatal("%s:%s lookup error", psc_dnsbl_reply->type, + psc_dnsbl_reply->name); head->first = 0; } diff --git a/postfix/src/postscreen/postscreen_smtpd.c b/postfix/src/postscreen/postscreen_smtpd.c index 402d078fc..406438b55 100644 --- a/postfix/src/postscreen/postscreen_smtpd.c +++ b/postfix/src/postscreen/postscreen_smtpd.c @@ -365,6 +365,9 @@ static int psc_ehlo_cmd(PSC_STATE *state, char *args) psc_smtpd_format_ehlo_reply(psc_temp, discard_mask); reply = STR(psc_temp); state->ehlo_discard_mask = discard_mask; + } else if (psc_ehlo_discard_maps && psc_ehlo_discard_maps->error) { + msg_fatal("%s lookup error for %s", + psc_ehlo_discard_maps->title, state->smtp_client_addr); } else if (state->flags & PSC_STATE_FLAG_USING_TLS) { reply = psc_smtpd_ehlo_reply_tls; state->ehlo_discard_mask = psc_ehlo_discard_mask | EHLO_MASK_STARTTLS; @@ -875,7 +878,8 @@ static void psc_smtpd_read_event(int event, char *context) STR(state->cmd_buffer), cp); vstring_strcpy(state->cmd_buffer, cp); } else if (psc_cmd_filter->error != 0) { - /* XXX log something, even if regexps don't soft-fail. */ + msg_fatal("%s:%s lookup error for \"%.100s\"", + psc_cmd_filter->type, psc_cmd_filter->name, cp); } } diff --git a/postfix/src/smtp/Makefile.in b/postfix/src/smtp/Makefile.in index 0134a455d..9f974f57e 100644 --- a/postfix/src/smtp/Makefile.in +++ b/postfix/src/smtp/Makefile.in @@ -465,6 +465,7 @@ smtp_sasl_glue.o: ../../include/name_mask.h smtp_sasl_glue.o: ../../include/recipient_list.h smtp_sasl_glue.o: ../../include/resolve_clnt.h smtp_sasl_glue.o: ../../include/scache.h +smtp_sasl_glue.o: ../../include/smtp_stream.h smtp_sasl_glue.o: ../../include/split_at.h smtp_sasl_glue.o: ../../include/string_list.h smtp_sasl_glue.o: ../../include/stringops.h @@ -533,6 +534,7 @@ smtp_session.o: ../../include/name_mask.h smtp_session.o: ../../include/recipient_list.h smtp_session.o: ../../include/resolve_clnt.h smtp_session.o: ../../include/scache.h +smtp_session.o: ../../include/smtp_stream.h smtp_session.o: ../../include/string_list.h smtp_session.o: ../../include/stringops.h smtp_session.o: ../../include/sys_defs.h diff --git a/postfix/src/smtp/smtp_chat.c b/postfix/src/smtp/smtp_chat.c index 213055e3d..1aefaf412 100644 --- a/postfix/src/smtp/smtp_chat.c +++ b/postfix/src/smtp/smtp_chat.c @@ -165,7 +165,7 @@ void smtp_chat_reset(SMTP_SESSION *session) /* smtp_chat_append - append record to SMTP transaction log */ static void smtp_chat_append(SMTP_SESSION *session, const char *direction, - const char *data) + const char *data) { char *line; @@ -301,7 +301,12 @@ SMTP_RESP *smtp_chat_resp(SMTP_SESSION *session) smtp_chat_append(session, " ", new_reply); } } else if (smtp_chat_resp_filter->error != 0) { - /* XXX log something, even if regexps don't soft-fail. */ + msg_warn("%s: table %s:%s lookup error for %s", + session->state->request->queue_id, + smtp_chat_resp_filter->type, + smtp_chat_resp_filter->name, + printable(STR(session->buffer), '?')); + vstream_longjmp(session->stream, SMTP_ERR_APPL); } } if (chat_append_flag) { diff --git a/postfix/src/smtp/smtp_proto.c b/postfix/src/smtp/smtp_proto.c index 408c57ec3..e348da80f 100644 --- a/postfix/src/smtp/smtp_proto.c +++ b/postfix/src/smtp/smtp_proto.c @@ -342,6 +342,7 @@ int smtp_helo(SMTP_STATE *state) * is not on by default. */ if (resp->str[strspn(resp->str, "20 *\t\n")] == 0) { + /* Best effort only. Ignore errors. */ if (smtp_pix_bug_maps != 0 && (pix_bug_words = maps_find(smtp_pix_bug_maps, @@ -451,6 +452,12 @@ int smtp_helo(SMTP_STATE *state) || (ehlo_words = maps_find(smtp_ehlo_dis_maps, state->session->addr, 0)) == 0) ehlo_words = var_smtp_ehlo_dis_words; + if (smtp_ehlo_dis_maps && smtp_ehlo_dis_maps->error) { + msg_warn("%s: %s map lookup error for %s", + session->state->request->queue_id, + smtp_ehlo_dis_maps->title, state->session->addr); + vstream_longjmp(session->stream, SMTP_ERR_APPL); + } discard_mask = ehlo_mask(ehlo_words); if (discard_mask && !(discard_mask & EHLO_MASK_SILENT)) msg_info("discarding EHLO keywords: %s", @@ -986,6 +993,11 @@ static void smtp_header_rewrite(void *context, int header_class, header_info, buf, offset); if (result == 0) return; + if (result == HBC_CHECKS_STAT_ERROR) { + msg_warn("%s: smtp header checks lookup error", + state->request->queue_id); + vstream_longjmp(state->session->stream, SMTP_ERR_APPL); + } if (result != STR(buf)) { vstring_strcpy(buf, result); myfree(result); @@ -1083,6 +1095,10 @@ static void smtp_body_rewrite(void *context, int type, result = hbc_body_checks(context, smtp_body_checks, buf, len, offset); if (result == buf) { smtp_text_out(state, type, buf, len, offset); + } else if (result == HBC_CHECKS_STAT_ERROR) { + msg_warn("%s: smtp body checks lookup error", + state->request->queue_id); + vstream_longjmp(state->session->stream, SMTP_ERR_APPL); } else if (result != 0) { smtp_text_out(state, type, result, strlen(result), offset); myfree(result); diff --git a/postfix/src/smtp/smtp_sasl_auth_cache.c b/postfix/src/smtp/smtp_sasl_auth_cache.c index 4f0d7e89a..562d6f3a5 100644 --- a/postfix/src/smtp/smtp_sasl_auth_cache.c +++ b/postfix/src/smtp/smtp_sasl_auth_cache.c @@ -196,8 +196,8 @@ static char *smtp_sasl_auth_cache_make_value(const char *password, /* smtp_sasl_auth_cache_valid_value - validate auth failure cache value */ static int smtp_sasl_auth_cache_valid_value(SMTP_SASL_AUTH_CACHE *auth_cache, - const char *entry, - const char *password) + const char *entry, + const char *password) { ssize_t len = strlen(entry); char *cache_hash = mymalloc(len); @@ -242,6 +242,9 @@ int smtp_sasl_auth_cache_find(SMTP_SASL_AUTH_CACHE *auth_cache, if (dict_del(auth_cache->dict, key) != 0) msg_warn("SASL auth failure map %s: entry not deleted: %s", auth_cache->dict->name, key); + if (auth_cache->dict->error) + msg_warn("SASL auth failure map %s: lookup failed for %s", + auth_cache->dict->name, key); myfree(key); return (valid); } diff --git a/postfix/src/smtp/smtp_sasl_glue.c b/postfix/src/smtp/smtp_sasl_glue.c index c7ca62abc..16fc940f4 100644 --- a/postfix/src/smtp/smtp_sasl_glue.c +++ b/postfix/src/smtp/smtp_sasl_glue.c @@ -47,7 +47,7 @@ /* /* smtp_sasl_passwd_lookup() looks up the username/password /* for the current SMTP server. The result is zero in case -/* of failure. +/* of failure, a long jump in case of error. /* /* smtp_sasl_authenticate() implements the SASL authentication /* dialog. The result is < 0 in case of protocol failure, zero in @@ -113,6 +113,7 @@ #include #include #include +#include /* * XSASL library. @@ -179,12 +180,17 @@ int smtp_sasl_passwd_lookup(SMTP_SESSION *session) * but didn't canonicalize the TCP port, and did not append the port to * the MX hostname. */ + smtp_sasl_passwd_map->error = 0; if (((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0 && var_smtp_sender_auth && state->request->sender[0] && (value = mail_addr_find(smtp_sasl_passwd_map, state->request->sender, (char **) 0)) != 0) - || (value = maps_find(smtp_sasl_passwd_map, session->host, 0)) != 0 - || (value = maps_find(smtp_sasl_passwd_map, session->dest, 0)) != 0) { + || (smtp_sasl_passwd_map->error == 0 + && (value = maps_find(smtp_sasl_passwd_map, + session->host, 0)) != 0) + || (smtp_sasl_passwd_map->error == 0 + && (value = maps_find(smtp_sasl_passwd_map, + session->dest, 0)) != 0)) { if (session->sasl_username) myfree(session->sasl_username); session->sasl_username = mystrdup(value); @@ -197,6 +203,10 @@ int smtp_sasl_passwd_lookup(SMTP_SESSION *session) myname, session->host, session->sasl_username, session->sasl_passwd); return (1); + } else if (smtp_sasl_passwd_map->error) { + msg_warn("%s: %s lookup error", + state->request->queue_id, smtp_sasl_passwd_map->title); + vstream_longjmp(session->stream, SMTP_ERR_APPL); } else { if (msg_verbose) msg_info("%s: no auth info found (sender=`%s', host=`%s')", diff --git a/postfix/src/smtp/smtp_session.c b/postfix/src/smtp/smtp_session.c index 1a0b15a75..4ee8e872a 100644 --- a/postfix/src/smtp/smtp_session.c +++ b/postfix/src/smtp/smtp_session.c @@ -123,6 +123,7 @@ #include #include #include +#include /* Application-specific. */ @@ -196,6 +197,8 @@ static void tls_site_lookup(int *site_level, const char *site_name, msg_warn("Table %s: ignoring unknown TLS policy '%s' for %s %s", var_smtp_tls_per_site, lookup, site_class, site_name); } + } else if (tls_per_site->error) { + msg_fatal("%s lookup error for %s", tls_per_site->title, site_name); } } @@ -220,6 +223,12 @@ static int tls_policy_lookup_one(SMTP_SESSION *session, int *site_level, if ((lookup = maps_find(tls_policy, site_name, 0)) == 0) return (0); + if (tls_policy->error) { + msg_warn("%s: %s lookup error for %s", + session->state->request->queue_id, + tls_policy->title, site_name); + vstream_longjmp(session->stream, SMTP_ERR_APPL); + } if (cbuf == 0) cbuf = vstring_alloc(10); diff --git a/postfix/src/smtp/smtp_trouble.c b/postfix/src/smtp/smtp_trouble.c index 30de87499..706bc5d4d 100644 --- a/postfix/src/smtp/smtp_trouble.c +++ b/postfix/src/smtp/smtp_trouble.c @@ -431,6 +431,9 @@ int smtp_stream_except(SMTP_STATE *state, int code, const char *description) dsb_simple(why, "4.4.2", "conversation with %s timed out while %s", session->namaddr, description); break; + case SMTP_ERR_APPL: + dsb_simple(why, "4.3.0", "local data error while talking to %s", + session->namaddr); } return (smtp_bulk_fail(state, SMTP_THROTTLE)); } diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index a489981fd..d4b30a6d2 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -4429,6 +4429,16 @@ static void smtpd_proto(SMTPD_STATE *state) case SMTP_ERR_QUIET: break; + case SMTP_ERR_APPL: + msg_info("%s: reject: %s from %s: " + "421 4.3.0 %s Server configuration error", + (state->queue_id ? state->queue_id : "NOQUEUE"), + state->where, state->namaddr, var_myhostname); + if (vstream_setjmp(state->client) == 0) + smtpd_chat_reply(state, "421 4.3.0 %s Server configuration error", + var_myhostname); + break; + case 0: /* @@ -4519,6 +4529,19 @@ static void smtpd_proto(SMTPD_STATE *state) break; } } + + /* + * Determine what server ESMTP features to suppress, typically to + * avoid inter-operability problems. Moved up so we don't send 421 + * immediately after sending the initial server response. + */ + if (ehlo_discard_maps == 0 + || (ehlo_words = maps_find(ehlo_discard_maps, state->addr, 0)) == 0) + ehlo_words = var_smtpd_ehlo_dis_words; + if (ehlo_discard_maps && ehlo_discard_maps->error) + vstream_longjmp(state->client, SMTP_ERR_APPL); + state->ehlo_discard_mask = ehlo_mask(ehlo_words); + /* XXX We use the real client for connect access control. */ if (SMTPD_STAND_ALONE(state) == 0 && var_smtpd_delay_reject == 0 @@ -4565,49 +4588,11 @@ static void smtpd_proto(SMTPD_STATE *state) smtpd_chat_reply(state, "421 %s Service unavailable - try again later", var_myhostname); /* Not: state->error_count++; */ -#ifdef notdef - } else if (strcmp(state->name, "unknown") == 0) { - static char *greet_chunks[] = { - "220 ", 0, " ESMTP ", 0, 0, - }; - char **cpp; - char *cp; - - greet_chunks[1] = var_myhostname; - greet_chunks[3] = var_mail_name; - for (cpp = greet_chunks; *cpp; cpp++) { - for (cp = *cpp; *cp; cp++) - smtp_fputc(*(unsigned char *) cp, state->client); - smtp_flush(state->client); - if (read_wait(vstream_fileno(state->client), 2) == 0) { - smtpd_chat_query(state); - msg_info("PREGREET from %s: %s", - state->namaddr, vstring_str(state->buffer)); - state->error_mask |= MAIL_ERROR_POLICY; - smtpd_chat_reply(state, - "521 %s ESMTP not accepting connections", - var_myhostname); - /* Not: state->error_count++; */ - break; - } - } - smtp_fputs("", 0, state->client); - smtp_flush(state->client); -#endif } else { smtpd_chat_reply(state, "220 %s", var_smtpd_banner); } } - /* - * Determine what server ESMTP features to suppress, typically to - * avoid inter-operability problems. - */ - if (ehlo_discard_maps == 0 - || (ehlo_words = maps_find(ehlo_discard_maps, state->addr, 0)) == 0) - ehlo_words = var_smtpd_ehlo_dis_words; - state->ehlo_discard_mask = ehlo_mask(ehlo_words); - /* * SASL initialization for plaintext mode. * @@ -4650,7 +4635,10 @@ static void smtpd_proto(SMTPD_STATE *state) state->namaddr, STR(state->buffer), cp); vstring_strcpy(state->buffer, cp); } else if (smtpd_cmd_filter->error != 0) { - /* XXX log something, even if regexps don't soft-fail. */ + msg_warn("%s:%s lookup error for \"%.100s\"", + smtpd_cmd_filter->type, smtpd_cmd_filter->name, + printable(STR(state->buffer), '?')); + vstream_longjmp(state->client, SMTP_ERR_APPL); } } if ((argc = smtpd_token(vstring_str(state->buffer), &argv)) == 0) { diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index 51616b616..5bfaf7357 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -3026,6 +3026,8 @@ static int rbl_reject_reply(SMTPD_STATE *state, const SMTPD_RBL_STATE *rbl, */ if (*var_rbl_reply_maps) { template = maps_find(rbl_reply_maps, rbl_domain, DICT_FLAG_NONE); + if (rbl_reply_maps->error) + reject_server_error(state); } why = vstring_alloc(100); rbl_exp.state = state; diff --git a/postfix/src/util/match_list.c b/postfix/src/util/match_list.c index c15f995aa..f6f7fc34d 100644 --- a/postfix/src/util/match_list.c +++ b/postfix/src/util/match_list.c @@ -172,6 +172,7 @@ MATCH_LIST *match_list_init(int flags, const char *patterns, int match_count,... for (i = 0; i < match_count; i++) list->match_func[i] = va_arg(ap, MATCH_LIST_FN); va_end(ap); + list->error = 0; #define DO_MATCH 1