]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.9-20120110
authorWietse Venema <wietse@porcupine.org>
Tue, 10 Jan 2012 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:37:54 +0000 (06:37 +0000)
38 files changed:
postfix/HISTORY
postfix/RELEASE_NOTES
postfix/WISHLIST
postfix/src/cleanup/Makefile.in
postfix/src/cleanup/cleanup.h
postfix/src/cleanup/cleanup_addr.c
postfix/src/cleanup/cleanup_init.c
postfix/src/cleanup/cleanup_masq.ref
postfix/src/cleanup/cleanup_masquerade.c
postfix/src/cleanup/cleanup_message.c
postfix/src/cleanup/cleanup_milter.c
postfix/src/flush/flush.c
postfix/src/global/dict_memcache.c
postfix/src/global/header_body_checks.c
postfix/src/global/header_body_checks.h
postfix/src/global/mail_version.h
postfix/src/global/maps.c
postfix/src/global/smtp_stream.c
postfix/src/global/smtp_stream.h
postfix/src/local/Makefile.in
postfix/src/local/unknown.c
postfix/src/postalias/fail_test.ref
postfix/src/postalias/postalias.c
postfix/src/postmap/fail_test.in
postfix/src/postmap/fail_test.ref
postfix/src/postmap/postmap.c
postfix/src/postscreen/postscreen_dnsbl.c
postfix/src/postscreen/postscreen_smtpd.c
postfix/src/smtp/Makefile.in
postfix/src/smtp/smtp_chat.c
postfix/src/smtp/smtp_proto.c
postfix/src/smtp/smtp_sasl_auth_cache.c
postfix/src/smtp/smtp_sasl_glue.c
postfix/src/smtp/smtp_session.c
postfix/src/smtp/smtp_trouble.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_check.c
postfix/src/util/match_list.c

index d2ae3b1ef76f810bce847343bba347a682907149..9f3659ac18aedc482b298b9b2c33a5446ac41568 100644 (file)
@@ -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.
index ae73b501599b68c5f881b1f63dc8fff132511250..4492293bde4a0f2fdb8f1d78d12bc640c24b5b39 100644 (file)
@@ -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
index c201dae89bb888392fda4d050ec3ce8a969104f5..394eea47cd073f94a859bf972405d54514933856 100644 (file)
@@ -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,
index 0dbbc1be5bd7bb6403af1b408ba80ec9c721f694..c447f198bca9482bcad447d7cd744c2bf58a1d6a 100644 (file)
@@ -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
 
index a962f00786b187fd5c81db12a13a1ac505813c78..9b9d6279d2a92b775636a6d704c8e4b245428c3b 100644 (file)
@@ -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
index dc87f5c9529fecfc48d94e548eefc5b98861c6ce..233ba37caee8a8b1b67fb036ef12f0f02aeae314 100644 (file)
@@ -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));
index bc4eb9ffda1af45c61abaf9f91ce04d284d358c3..47ed5cf816193e86cf0af1d40af139142a6551ae 100644 (file)
@@ -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);
index 98dde745c6e615881c523ff405d498b77a1fb29c..80dd26fe5730736287603140140555a0f4a9bd43 100644 (file)
@@ -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
index 0a4fededb39efe6eb8fecefde9788be314bec668..70577da1ebfe60886bd08bcb61c1a5d78c084202 100644 (file)
@@ -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);
index 6e2b85a04738ab0c65c8a79c709d58cf0c70fc01..ffb5c7e527d74d09655fdf3e914b78d0a5f69c19 100644 (file)
@@ -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);
index e29feebed52ed6e6ae22d729a3e961950219b8f5..cc63313f1d9c1cdb783045ef8ecf9bd874441d4f 100644 (file)
@@ -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);
index 9f2c5dbdb9ba40f063d2c2c371f9ef644b88356a..22c1a83654c0d114eefe2a054015e6197d496b39 100644 (file)
@@ -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.
index a60a20e8dfa52eb0682ffcb381e631432e0d6149..d6df42996963e20193beb63172a4762ce197892e 100644 (file)
@@ -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);
     }
 }
index c6c894e4d7399bf9b88b1fa024b80590a766a5b2..b423e8eb7c0b59313549a07de9b5dfe632235400 100644 (file)
 /*     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:
   * 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);
     }
index f397ae2a75ef57c1a0ef50273a387239fde6402f..f4c642bc432f26bc5dff92dc4c03b89be0eeaa2c 100644 (file)
@@ -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
index bcb8857fc758d60f6624e476d789afe9e7bd523a..a69bbad89481b916f34cf7828d35b17e9b261e59 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20120108"
+#define MAIL_RELEASE_DATE      "20120110"
 #define MAIL_VERSION_NUMBER    "2.9"
 
 #ifdef SNAPSHOT
index 6f19eb8fc7fd5d674fc2fde253855d2b3f7b3383..391a800190a1d21183493213837190c7c3400300 100644 (file)
@@ -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;
        }
     }
index 385a831d77d2bd68f0c7574a0f3bbb0f4f05117d..fb68e505775d8b1c6e3ddb3f5765b41edae88b98 100644 (file)
 /*     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.
index af8cdbe9ee862ebb36772b8574fd9e5d609a6728..599bcfa297c0f702fe8fa8874279ae77db0f3b27 100644 (file)
@@ -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 *,...);
index 503e502e66b4243ef39cc0fc4b4ab7df5ac22f79..42ce2dc501c3d7381265a85ec92f1969206bbc17 100644 (file)
@@ -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
index 91c338c1bc4c383dc1b089f7041dfa627eb59596..9c3d185f86f23a7b3695e0c76e75449202ce91e4 100644 (file)
@@ -72,6 +72,7 @@
 #include <mail_addr.h>
 #include <sent.h>
 #include <deliver_pass.h>
+#include <defer.h>
 
 /* Application-specific. */
 
index 64d2eef68bedf6ccb32934ab517905b2cc470a2d..37ebce6b3096d179d9a3f934551a8443f41a3c24 100644 (file)
@@ -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
index a031ef73d4787a46322e780073792a2cd9a287cf..cc190b4165623fa9fcabaa0fe7bf1957c0b4b039 100644 (file)
@@ -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);
 }
index b62c3c5d7530b4210c01251e263aab6a7e0239a5..a1c6b7c5867ec6e2b97722afcd0237bf1173a9aa 100644 (file)
@@ -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
index b9a92da078c33ead05136863eb95015dd972ed4b..eb3e5967ceb6959cb9d74ed414abd18c356a1959 100644 (file)
@@ -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
index 22718dd65c3d5bd22b025dce1c46e849164ef673..4781d52115efd0ca3dfa81a833fd1b61f099c332 100644 (file)
@@ -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);
 }
index a57f20ef42ac4151238f0f90ee43b3b53b608bdd..b85a9da93058769fa542bbf8600ec143999958af 100644 (file)
@@ -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;
     }
 
index 402d078fcbfb1fa21b1d06263efadb4ee6fc4792..406438b5569084f509bd207e4143f9bad631c1aa 100644 (file)
@@ -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);
            }
        }
 
index 0134a455dd917c91ff8af17843693af60597eeef..9f974f57ef0400d4207a675203f285832d2730d8 100644 (file)
@@ -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
index 213055e3d728cb2633f5ea6d189436df4d767b69..1aefaf41245ac0fb7ebfccdabacbf52b8e7227a9 100644 (file)
@@ -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) {
index 408c57ec30c35bea073029d9d32430a27357d0d3..e348da80fc91106c5ecd693ff4e49cd7f7ec3ecf 100644 (file)
@@ -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);
index 4f0d7e89af5adfae5d09cdc589f8acbb9cc2b900..562d6f3a5a85fe78121d4453eae8269c28b989e1 100644 (file)
@@ -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);
 }
index c7ca62abc68c86e0d57036a3ba353034a1872968..16fc940f4f665cbcc85730c4480ebd9715698398 100644 (file)
@@ -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
 #include <string_list.h>
 #include <maps.h>
 #include <mail_addr_find.h>
+#include <smtp_stream.h>
 
  /*
   * 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')",
index 1a0b15a75663a5f2f0857ed6d5d2f6ec2613ce09..4ee8e872a60b03b572696c087d8cc7795f5cd491 100644 (file)
 #include <debug_peer.h>
 #include <mail_params.h>
 #include <maps.h>
+#include <smtp_stream.h>
 
 /* 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);
 
index 30de87499dab2d0eab73ee68a581873d4d6ab3aa..706bc5d4da232667bc6d2cddde56cbf08c2f55eb 100644 (file)
@@ -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));
 }
index a489981fd0aa318fdca5d3a45d52fd4d49e38144..d4b30a6d20389c6237cd61c38d811df853ab9c30 100644 (file)
@@ -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) {
index 51616b616b6ee5e3e196b584c6ad3bfc415e9dff..5bfaf73571e286e02cbd3e788ce8ae39ec93f437 100644 (file)
@@ -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;
index c15f995aa5355c4251151c4eaef96ffa02671e84..f6f7fc34da68758c9c87ab72a08ae69dfb8a9d71 100644 (file)
@@ -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