]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.7.5 v2.7.5
authorWietse Venema <wietse@porcupine.org>
Thu, 7 Jul 2011 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Sat, 10 Feb 2018 19:11:55 +0000 (14:11 -0500)
18 files changed:
postfix/HISTORY
postfix/makedefs
postfix/postfix-install
postfix/src/cleanup/cleanup_milter.c
postfix/src/global/abounce.c
postfix/src/global/abounce.h
postfix/src/global/mail_version.h
postfix/src/local/Makefile.in
postfix/src/local/bounce_workaround.c
postfix/src/local/mailbox.c
postfix/src/local/unknown.c
postfix/src/master/master_ent.c
postfix/src/milter/milter8.c
postfix/src/oqmgr/qmgr_active.c
postfix/src/postdrop/postdrop.c
postfix/src/qmgr/qmgr_active.c
postfix/src/smtpd/smtpd_check.c
postfix/src/util/sys_defs.h

index a4922c08e687beb3d3fc069e5b5a3f8d5fa843ee..8643ebb6749cf86361ae44d4f61c41f179dfd409 100644 (file)
@@ -15891,3 +15891,54 @@ Apologies for any names omitted.
        reuse a server SASL handle after authentication failure.
        Problem reported by Thomas Jarosch of Intra2net AG. File:
        smtpd/smtpd_proto.c.
+
+20110418
+
+       Bugfix (introduced Postfix 2.3 and Postfix 2.7): the Milter
+       client reported some "file too large" errors as temporary
+       errors. Problem reported by Michael Tokarev. Files:
+       milter/milter8.c, cleanup/cleanup_milter.c.
+
+20110420
+
+       Performance: a high load of DSN success notification requests
+       could slow down the queue manager. Solution: make the trace
+       client asynchronous, just like the bounce and defer clients.
+       Problem reported by Eduardo M. Stelmaszczyk of terra.com.br.
+       Files: global/abounce.[hc], *qmgr/qmgr_active.c (the
+       qmgr_active.c files are identical).
+
+20110426
+
+       Bugfix (introduced in Postfix 1.1, duplicated in Postfix
+       2.3, unrelated mistake in Postfix 2.7): the local(8) delivery
+       agent ignored table lookup errors in mailbox_command_maps,
+       mailbox_transport_maps, fallback_transport_maps and (while
+       bouncing mail to alias) alias owner lookup. Problem reported
+       by William Ono. Files: local/command.c, local/mailbox.c,
+       local/unknown.c, local/bounce_workaround.c.
+
+20110601
+
+       Bugfix (introduced Postfix 2.6 with master_service_disable)
+       loop control error when parsing a malformed master.cf file.
+       Found by Coverity. File: master/master_ent.c.
+
+20110602
+
+       Bugfix (introduced: Postfix 2.7): "sendmail -t" reported
+       "protocol error" after queue file write error.  File:
+       postdrop/postdrop.c.
+
+20110614
+
+       Linux kernel version 3 support. Linus Torvalds has reset
+       the counters for reasons not related to changes in code.
+       Files: makedefs, util/sys_defs.h.
+
+20110615
+
+       Workaround: some Spamhaus RHSBL rejects lookups with "No
+       IP queries" even if the name has an alphanumerical prefix.
+       We play safe, and skip RHSBL queries for names ending in a
+       numerical suffix.  File: smtpd/smtpd_check.c.
index e1e0882afd505d450d8d6b72b0af0c2fbddbd080..91f0b0373976097e53e432824f25c737118c3c33 100644 (file)
@@ -340,6 +340,33 @@ EOF
                       fi;;
                esac
                ;;
+    Linux.3*)  SYSTYPE=LINUX3
+               if [ -f /usr/include/db.h ]
+               then
+                   : we are all set
+               elif [ -f /usr/include/db/db.h ]
+               then
+                   CCARGS="$CCARGS -I/usr/include/db"
+               else
+                   # On a properly installed system, Postfix builds
+                   # by including <db.h> and by linking with -ldb
+                   echo "No <db.h> include file found." 1>&2
+                   echo "Install the appropriate db*-devel package first." 1>&2
+                   echo "See the RELEASE_NOTES file for more information." 1>&2
+                   exit 1
+               fi
+               SYSLIBS="-ldb"
+               for name in nsl resolv
+               do
+                   for lib in /usr/lib64 /lib64 /usr/lib /lib
+                   do
+                       test -e $lib/lib$name.a -o -e $lib/lib$name.so && {
+                           SYSLIBS="$SYSLIBS -l$name"
+                           break
+                       }
+                   done
+               done
+               ;;
      GNU.0*|GNU/kFreeBSD.[567]*)
                SYSTYPE=GNU0
                # Postfix no longer needs DB 1.85 compatibility
index f936b81a02bcd8f1c2d0b5ec36c89600752683d4..775b0acfe383f365ca55d37bb06093ea2b842ef6 100644 (file)
@@ -305,7 +305,7 @@ esac
 
 install_root_prompt="the prefix for installed file names. Specify
 this ONLY if you are building ready-to-install packages for
-distribution to other machines."
+distribution to OTHER machines. See PACKAGE_README for instructions."
 
 tempdir_prompt="a directory for scratch files while installing
 Postfix.  You must have write permission in this directory."
index 05ded61672485fccd6c6e13d354493c2139d7524..9667dc72503cf2a2bfaed8b75cadef305abfaa98 100644 (file)
 
 /*#define msg_verbose  2*/
 
+static void cleanup_milter_set_error(CLEANUP_STATE *, int);
+
 #define STR(x)         vstring_str(x)
 #define LEN(x)         VSTRING_LEN(x)
 
@@ -431,8 +433,7 @@ static void cleanup_milter_hbc_add_meta_records(CLEANUP_STATE *state)
      * later.
      */
     if ((new_meta_offset = vstream_fseek(state->dst, (off_t) 0, SEEK_END)) < 0) {
-       msg_warn("%s: seek file %s: %m", myname, cleanup_path);
-       state->errs |= CLEANUP_STAT_WRITE;
+       cleanup_milter_set_error(state, errno);
        return;
     }
     if (state->filter != 0)
@@ -452,8 +453,7 @@ static void cleanup_milter_hbc_add_meta_records(CLEANUP_STATE *state)
      * value with the location of the new meta record.
      */
     if (vstream_fseek(state->dst, state->append_meta_pt_offset, SEEK_SET) < 0) {
-       msg_warn("%s: seek file %s: %m", myname, cleanup_path);
-       state->errs |= CLEANUP_STAT_WRITE;
+       cleanup_milter_set_error(state, errno);
        return;
     }
     cleanup_out_format(state, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT,
index 8c31694265aebbab6f26e49cff91f31f97684e8c..105b9f6b8b5cf252fd46cfb9a1791a7a95130cae 100644 (file)
 /*     int     dsn_ret;
 /*     void    (*callback)(int status, char *context);
 /*     char    *context;
+/*
+/*     void    atrace_flush(flags, queue, id, encoding, sender,
+/*                             dsn_envid, dsn_ret, callback, context)
+/*     int     flags;
+/*     const char *queue;
+/*     const char *id;
+/*     const char *encoding;
+/*     const char *sender;
+/*     const char *dsn_envid;
+/*     int     dsn_ret;
+/*     void    (*callback)(int status, char *context);
+/*     char    *context;
 /* DESCRIPTION
 /*     This module implements an asynchronous interface to the
-/*     bounce/defer service for submitting sender notifications
+/*     bounce/defer/trace service for submitting sender notifications
 /*     without waiting for completion of the request.
 /*
 /*     abounce_flush() bounces the specified message to
 /*     the specified sender, including the defer log that was
 /*     built with defer_append().
 /*
+/*     atrace_flush() returns the specified message to the specified
+/*     sender, including the message delivery record log that was
+/*     built with vtrace_append().
+/*
 /*     Arguments:
 /* .IP flags
 /*     The bitwise OR of zero or more of the following (specify
@@ -359,3 +375,15 @@ void    adefer_warn(int flags, const char *queue, const char *id,
                    flags, queue, id, encoding, sender, dsn_envid, dsn_ret,
                    callback, context);
 }
+
+/* atrace_flush - asynchronous trace flush */
+
+void    atrace_flush(int flags, const char *queue, const char *id,
+                            const char *encoding, const char *sender,
+                            const char *dsn_envid, int dsn_ret,
+                            ABOUNCE_FN callback, char *context)
+{
+    abounce_request(MAIL_CLASS_PRIVATE, var_trace_service, BOUNCE_CMD_TRACE,
+                   flags, queue, id, encoding, sender, dsn_envid, dsn_ret,
+                   callback, context);
+}
index 521499cf38e04ec6af790c95d4e386c2c7deb789..dc4264b6b871efff7e87b45aa02ee82d2754e2a8 100644 (file)
@@ -24,6 +24,7 @@ typedef void (*ABOUNCE_FN) (int, char *);
 extern void abounce_flush(int, const char *, const char *, const char *, const char *, const char *, int, ABOUNCE_FN, char *);
 extern void adefer_flush(int, const char *, const char *, const char *, const char *, const char *, int, ABOUNCE_FN, char *);
 extern void adefer_warn(int, const char *, const char *, const char *, const char *, const char *, int, ABOUNCE_FN, char *);
+extern void atrace_flush(int, const char *, const char *, const char *, const char *, const char *, int, ABOUNCE_FN, char *);
 
 extern void abounce_flush_verp(int, const char *, const char *, const char *, const char *, const char *, int, const char *, ABOUNCE_FN, char *);
 extern void adefer_flush_verp(int, const char *, const char *, const char *, const char *, const char *, int, const char *, ABOUNCE_FN, char *);
index 8e3f5d5b65c20327c13000a333721d434f5b018e..c59aefb85ea4727d215446f0ec636f64966ba33b 100644 (file)
@@ -20,8 +20,8 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20110509"
-#define MAIL_VERSION_NUMBER    "2.7.4"
+#define MAIL_RELEASE_DATE      "20110707"
+#define MAIL_VERSION_NUMBER    "2.7.5"
 
 #ifdef SNAPSHOT
 # define MAIL_VERSION_DATE     "-" MAIL_RELEASE_DATE
index 544993de52dc4390b00a7324cb2c6c83f94b2414..291664b5aab7bae35163c558147cc6e8af8d577d 100644 (file)
@@ -106,6 +106,7 @@ bounce_workaround.o: ../../include/attr.h
 bounce_workaround.o: ../../include/been_here.h
 bounce_workaround.o: ../../include/bounce.h
 bounce_workaround.o: ../../include/canon_addr.h
+bounce_workaround.o: ../../include/defer.h
 bounce_workaround.o: ../../include/deliver_request.h
 bounce_workaround.o: ../../include/delivered_hdr.h
 bounce_workaround.o: ../../include/dict.h
index 13af3434e1c66586bb39ae41c7941793c3892a3e..6938f3d509739dcc348a727f7d5a10aed4ed2158 100644 (file)
@@ -77,6 +77,7 @@
 #include <strip_addr.h>
 #include <stringops.h>
 #include <bounce.h>
+#include <defer.h>
 #include <split_addr.h>
 #include <canon_addr.h>
 
@@ -97,6 +98,7 @@ int     bounce_workaround(LOCAL_STATE state)
        char   *stripped_recipient;
        char   *owner_alias;
        const char *owner_expansion;
+       int     saved_dict_errno;
 
 #define FIND_OWNER(lhs, rhs, addr) { \
        lhs = concatenate("owner-", addr, (char *) 0); \
@@ -104,8 +106,9 @@ int     bounce_workaround(LOCAL_STATE state)
        rhs = maps_find(alias_maps, lhs, DICT_FLAG_NONE); \
     }
 
+       dict_errno = 0;
        FIND_OWNER(owner_alias, owner_expansion, state.msg_attr.rcpt.address);
-       if (owner_expansion == 0
+       if ((saved_dict_errno = dict_errno) == 0 && owner_expansion == 0
            && (stripped_recipient = strip_addr(state.msg_attr.rcpt.address,
                                                (char **) 0,
                                                *var_rcpt_delim)) != 0) {
@@ -113,13 +116,17 @@ int     bounce_workaround(LOCAL_STATE state)
            FIND_OWNER(owner_alias, owner_expansion, stripped_recipient);
            myfree(stripped_recipient);
        }
-       if (owner_expansion != 0) {
+       if ((saved_dict_errno = dict_errno) == 0 && owner_expansion != 0) {
            canon_owner = canon_addr_internal(vstring_alloc(10),
                                              var_exp_own_alias ?
                                              owner_expansion : owner_alias);
            SET_OWNER_ATTR(state.msg_attr, STR(canon_owner), state.level);
        }
        myfree(owner_alias);
+       if (saved_dict_errno != 0)
+           /* At this point, canon_owner == 0. */
+           return (defer_append(BOUNCE_FLAGS(state.request),
+                                BOUNCE_ATTR(state.msg_attr)));
     }
 
     /*
index d35ef66b4cf33f5b6564135c96f325ecd5cb333f..58b01f79f2fb8f14fdab84ccf42ed893d9d66302 100644 (file)
@@ -278,6 +278,7 @@ int     deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp)
        transp_maps = maps_create(VAR_MBOX_TRANSP_MAPS, var_mbox_transp_maps,
                                  DICT_FLAG_LOCK | DICT_FLAG_NO_REGSUB);
     /* The -1 is a hint for the down-stream deliver_completed() function. */
+    dict_errno = 0;
     if (*var_mbox_transp_maps
        && (map_transport = maps_find(transp_maps, state.msg_attr.user,
                                      DICT_FLAG_NONE)) != 0) {
@@ -285,6 +286,11 @@ int     deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp)
        *statusp = deliver_pass(MAIL_CLASS_PRIVATE, map_transport,
                                state.request, &state.msg_attr.rcpt);
        return (YES);
+    } else if (dict_errno != 0) {
+       /* Details in the logfile. */
+       dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure");
+       *statusp = DEL_STAT_DEFER;
+       return (YES);
     }
     if (*var_mailbox_transport) {
        state.msg_attr.rcpt.offset = -1L;
@@ -319,10 +325,15 @@ int     deliver_mailbox(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp)
        cmd_maps = maps_create(VAR_MAILBOX_CMD_MAPS, var_mailbox_cmd_maps,
                               DICT_FLAG_LOCK | DICT_FLAG_PARANOID);
 
+    dict_errno = 0;
     if (*var_mailbox_cmd_maps
        && (map_command = maps_find(cmd_maps, state.msg_attr.user,
                                    DICT_FLAG_NONE)) != 0) {
        status = deliver_command(state, usr_attr, map_command);
+    } else if (dict_errno != 0) {
+       /* Details in the logfile. */
+       dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure");
+       status = DEL_STAT_DEFER;
     } else if (*var_mailbox_command) {
        status = deliver_command(state, usr_attr, var_mailbox_command);
     } else if (*var_home_mailbox && LAST_CHAR(var_home_mailbox) == '/') {
index 068f9eed2683ca44e59e069861112e9a2e5c42e8..eb5bbf25054ef29e75512f0b08d0dd60b59c0e01 100644 (file)
@@ -110,12 +110,17 @@ int     deliver_unknown(LOCAL_STATE state, USER_ATTR usr_attr)
        transp_maps = maps_create(VAR_FBCK_TRANSP_MAPS, var_fbck_transp_maps,
                                  DICT_FLAG_LOCK | DICT_FLAG_NO_REGSUB);
     /* The -1 is a hint for the down-stream deliver_completed() function. */
+    dict_errno = 0;
     if (*var_fbck_transp_maps
        && (map_transport = maps_find(transp_maps, state.msg_attr.user,
                                      DICT_FLAG_NONE)) != 0) {
        state.msg_attr.rcpt.offset = -1L;
        return (deliver_pass(MAIL_CLASS_PRIVATE, map_transport,
                             state.request, &state.msg_attr.rcpt));
+    } else if (dict_errno != 0) {
+       /* Details in the logfile. */
+       dsb_simple(state.msg_attr.why, "4.3.0", "table lookup failure");
+       return (DEL_STAT_DEFER);
     }
     if (*var_fallback_transport) {
        state.msg_attr.rcpt.offset = -1L;
index 4723251bdedaf508c56e7bd1aaa6139c96875901..cc0bb56d72902a2d27edaafbcfa2be6e11863851 100644 (file)
@@ -272,7 +272,7 @@ MASTER_SERV *get_master_ent()
     /*
      * Skip blank lines and comment lines.
      */
-    do {
+    for (;;) {
        if (readlline(buf, master_fp, &master_line) == 0) {
            vstring_free(buf);
            vstring_free(junk);
@@ -284,7 +284,9 @@ MASTER_SERV *get_master_ent()
        name = cp;
        transport = get_str_ent(&bufp, "transport type", (char *) 0);
        vstring_sprintf(junk, "%s.%s", name, transport);
-    } while (match_service_match(master_disable, vstring_str(junk)) != 0);
+       if (match_service_match(master_disable, vstring_str(junk)) == 0)
+           break;
+    }
 
     /*
      * Parse one logical line from the configuration file. Initialize service
index 6fea0f06a18d03cea3d932f2f29bec34cd93e5d5..21776ca8d6f53b0db31771b115078f42f56f8320 100644 (file)
@@ -2462,6 +2462,7 @@ static const char *milter8_message(MILTER *m, VSTREAM *qfile,
     int     mime_errs = 0;
     MILTER_MSG_CONTEXT msg_ctx;
     VSTRING *buf;
+    int     saved_errno;
 
     switch (milter->state) {
     case MILTER8_STAT_ERROR:
@@ -2475,8 +2476,12 @@ static const char *milter8_message(MILTER *m, VSTREAM *qfile,
        if (msg_verbose)
            msg_info("%s: message to milter %s", myname, milter->m.name);
        if (vstream_fseek(qfile, data_offset, SEEK_SET) < 0) {
+           saved_errno = errno;
            msg_warn("%s: vstream_fseek %s: %m", myname, VSTREAM_PATH(qfile));
-           return ("450 4.3.0 Queue file write error");
+           /* XXX This should be available from cleanup_strerror.c. */
+           return (saved_errno == EFBIG ?
+                   "552 5.3.4 Message file too big" :
+                   "451 4.3.0 Queue file write error");
        }
        msg_ctx.milter = milter;
        msg_ctx.eoh_macros = eoh_macros;
index eeec88d3b40d81dbc4f57d157af5db7bd799dd70..eea9d71d0c6c3e1604736ef2fcd1a2320d745583 100644 (file)
   */
 static void qmgr_active_done_2_bounce_flush(int, char *);
 static void qmgr_active_done_2_generic(QMGR_MESSAGE *);
+static void qmgr_active_done_25_trace_flush(int, char *);
+static void qmgr_active_done_25_generic(QMGR_MESSAGE *);
 static void qmgr_active_done_3_defer_flush(int, char *);
 static void qmgr_active_done_3_defer_warn(int, char *);
 static void qmgr_active_done_3_generic(QMGR_MESSAGE *);
@@ -336,10 +338,8 @@ static void qmgr_active_done_2_bounce_flush(int status, char *context)
 
 static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
 {
-    const char *myname = "qmgr_active_done_2_generic";
     const char *path;
     struct stat st;
-    int     status;
 
     /*
      * A delivery agent marks a queue file as corrupt by changing its
@@ -372,10 +372,6 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
     }
 
     /*
-     * As a temporary implementation, synchronously inform the sender of
-     * trace information. This will block for 10 seconds when the qmgr FIFO
-     * is full.
-     * 
      * XXX With multi-recipient mail, some recipients may have NOTIFY=SUCCESS
      * and others not. Depending on what subset of recipients are delivered,
      * a trace file may or may not be created. Even when the last partial
@@ -388,18 +384,45 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
      */
     if ((message->tflags & (DEL_REQ_FLAG_USR_VRFY | DEL_REQ_FLAG_RECORD))
        || (message->rflags & QMGR_READ_FLAG_NOTIFY_SUCCESS)) {
-       status = trace_flush(message->tflags,
-                            message->queue_name,
-                            message->queue_id,
-                            message->encoding,
-                            message->sender,
-                            message->dsn_envid,
-                            message->dsn_ret);
-       if (status == 0 && message->tflags_offset)
-           qmgr_message_kill_record(message, message->tflags_offset);
-       message->flags |= status;
+       atrace_flush(message->tflags,
+                    message->queue_name,
+                    message->queue_id,
+                    message->encoding,
+                    message->sender,
+                    message->dsn_envid,
+                    message->dsn_ret,
+                    qmgr_active_done_25_trace_flush,
+                    (char *) message);
+       return;
     }
 
+    /*
+     * Asynchronous processing does not reach this point.
+     */
+    qmgr_active_done_25_generic(message);
+}
+
+/* qmgr_active_done_25_trace_flush - continue after atrace_flush() completion */
+
+static void qmgr_active_done_25_trace_flush(int status, char *context)
+{
+    QMGR_MESSAGE *message = (QMGR_MESSAGE *) context;
+
+    /*
+     * Process atrace_flush() status and continue processing.
+     */
+    if (status == 0 && message->tflags_offset)
+       qmgr_message_kill_record(message, message->tflags_offset);
+    message->flags |= status;
+    qmgr_active_done_25_generic(message);
+}
+
+/* qmgr_active_done_25_generic - continue processing */
+
+static void qmgr_active_done_25_generic(QMGR_MESSAGE *message)
+{
+    const char *myname = "qmgr_active_done_25_generic";
+
     /*
      * If we get to this point we have tried all recipients for this message.
      * If the message is too old, try to bounce it.
index 34e4fdf8ea1b784a4fdd3bc088fdfb53d7c098fe..a2df01ecec9ea7e5eee987f920d753e7541e8336 100644 (file)
@@ -235,6 +235,7 @@ int     main(int argc, char **argv)
     int     saved_errno;
     int     from_count = 0;
     int     rcpt_count = 0;
+    int     validate_input = 1;
 
     /*
      * Fingerprint executables and core dumps.
@@ -453,6 +454,7 @@ int     main(int argc, char **argv)
                   && rec_type != REC_TYPE_EOF)
                if (rec_type == REC_TYPE_ERROR)
                    msg_fatal("uid=%ld: malformed input", (long) uid);
+           validate_input = 0;
            errno = saved_errno;
            break;
        }
@@ -478,7 +480,7 @@ int     main(int argc, char **argv)
      * the segment terminator records, there aren't any other mandatory
      * records in a Postfix submission queue file.
      */
-    if (from_count == 0 || rcpt_count == 0) {
+    if (validate_input && (from_count == 0 || rcpt_count == 0)) {
        status = CLEANUP_STAT_BAD;
        mail_stream_cleanup(dst);
     }
index eeec88d3b40d81dbc4f57d157af5db7bd799dd70..eea9d71d0c6c3e1604736ef2fcd1a2320d745583 100644 (file)
   */
 static void qmgr_active_done_2_bounce_flush(int, char *);
 static void qmgr_active_done_2_generic(QMGR_MESSAGE *);
+static void qmgr_active_done_25_trace_flush(int, char *);
+static void qmgr_active_done_25_generic(QMGR_MESSAGE *);
 static void qmgr_active_done_3_defer_flush(int, char *);
 static void qmgr_active_done_3_defer_warn(int, char *);
 static void qmgr_active_done_3_generic(QMGR_MESSAGE *);
@@ -336,10 +338,8 @@ static void qmgr_active_done_2_bounce_flush(int status, char *context)
 
 static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
 {
-    const char *myname = "qmgr_active_done_2_generic";
     const char *path;
     struct stat st;
-    int     status;
 
     /*
      * A delivery agent marks a queue file as corrupt by changing its
@@ -372,10 +372,6 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
     }
 
     /*
-     * As a temporary implementation, synchronously inform the sender of
-     * trace information. This will block for 10 seconds when the qmgr FIFO
-     * is full.
-     * 
      * XXX With multi-recipient mail, some recipients may have NOTIFY=SUCCESS
      * and others not. Depending on what subset of recipients are delivered,
      * a trace file may or may not be created. Even when the last partial
@@ -388,18 +384,45 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
      */
     if ((message->tflags & (DEL_REQ_FLAG_USR_VRFY | DEL_REQ_FLAG_RECORD))
        || (message->rflags & QMGR_READ_FLAG_NOTIFY_SUCCESS)) {
-       status = trace_flush(message->tflags,
-                            message->queue_name,
-                            message->queue_id,
-                            message->encoding,
-                            message->sender,
-                            message->dsn_envid,
-                            message->dsn_ret);
-       if (status == 0 && message->tflags_offset)
-           qmgr_message_kill_record(message, message->tflags_offset);
-       message->flags |= status;
+       atrace_flush(message->tflags,
+                    message->queue_name,
+                    message->queue_id,
+                    message->encoding,
+                    message->sender,
+                    message->dsn_envid,
+                    message->dsn_ret,
+                    qmgr_active_done_25_trace_flush,
+                    (char *) message);
+       return;
     }
 
+    /*
+     * Asynchronous processing does not reach this point.
+     */
+    qmgr_active_done_25_generic(message);
+}
+
+/* qmgr_active_done_25_trace_flush - continue after atrace_flush() completion */
+
+static void qmgr_active_done_25_trace_flush(int status, char *context)
+{
+    QMGR_MESSAGE *message = (QMGR_MESSAGE *) context;
+
+    /*
+     * Process atrace_flush() status and continue processing.
+     */
+    if (status == 0 && message->tflags_offset)
+       qmgr_message_kill_record(message, message->tflags_offset);
+    message->flags |= status;
+    qmgr_active_done_25_generic(message);
+}
+
+/* qmgr_active_done_25_generic - continue processing */
+
+static void qmgr_active_done_25_generic(QMGR_MESSAGE *message)
+{
+    const char *myname = "qmgr_active_done_25_generic";
+
     /*
      * If we get to this point we have tried all recipients for this message.
      * If the message is too old, try to bounce it.
index c31e608c5392b10a59be51c2377b7a37e9f2f169..73b9536607fa217915dd17f5cceba33967c44413 100644 (file)
@@ -3224,6 +3224,7 @@ static int reject_rbl_domain(SMTPD_STATE *state, const char *rbl_domain,
     SMTPD_RBL_STATE *rbl;
     const char *domain;
     const char *reply_addr;
+    const char *suffix;
 
     if (msg_verbose)
        msg_info("%s: %s %s", myname, reply_class, what);
@@ -3238,7 +3239,16 @@ static int reject_rbl_domain(SMTPD_STATE *state, const char *rbl_domain,
            return (SMTPD_CHECK_DUNNO);
     } else
        domain = what;
-    if (domain[0] == 0)
+
+    /*
+     * XXX Some Spamhaus RHSBL rejects lookups with "No IP queries" even if
+     * the name has an alphanumerical prefix. We play safe, and skip RHSBL
+     * queries for names ending in a numerical suffix.
+     */
+    if (domain[0] == 0 || valid_hostname(domain, DONT_GRIPE) == 0)
+       return (SMTPD_CHECK_DUNNO);
+    suffix = strrchr(domain, '.');
+    if (alldig(suffix == 0 ? domain : suffix + 1))
        return (SMTPD_CHECK_DUNNO);
 
     query = vstring_alloc(100);
@@ -3789,8 +3799,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
                         name);
            else {
                cpp += 1;
-               if (state->helo_name
-                   && valid_hostname(state->helo_name, DONT_GRIPE))
+               if (state->helo_name)
                    status = reject_rbl_domain(state, *cpp, state->helo_name,
                                               SMTPD_NAME_HELO);
            }
index 1054b3e68860b707a772be13b0802d8634bd1f1e..a14ae67564f2c4a027463d2062e44b8cbd9d46ad 100644 (file)
@@ -703,7 +703,7 @@ extern int initgroups(const char *, int);
  /*
   * LINUX.
   */
-#ifdef LINUX2
+#if defined(LINUX2) || defined(LINUX3)
 #define SUPPORTED
 #include <sys/types.h>
 #define UINT32_TYPE    unsigned int