From: Arkadiusz Miśkiewicz Date: Tue, 8 Aug 2017 06:54:39 +0000 (+0200) Subject: - rel 6; fixes from upstream branch X-Git-Tag: auto/th/exim-4.89-6 X-Git-Url: http://git.pld-linux.org/?p=packages%2Fexim.git;a=commitdiff_plain;h=acfdf00 - rel 6; fixes from upstream branch --- diff --git a/branch.sh b/branch.sh new file mode 100755 index 0000000..4dbf809 --- /dev/null +++ b/branch.sh @@ -0,0 +1,32 @@ +#!/bin/sh +set -e +url=git://git.exim.org/exim.git +package=exim +tag=exim-4_89 +branch=exim-4_89+fixes +out=$package-git.patch +repo=$package.git + +# use filterdiff, etc to exclude bad chunks from diff +filter() { + cat +} + +if [ ! -d $repo ]; then + git clone --bare $url -b $branch $repo +fi + +cd $repo + git fetch origin +$branch:$branch +refs/tags/$tag:refs/tags/$tag + git log -p --reverse $tag..$branch ":(exclude)doc/doc-*" ":(exclude)test" ":(exclude).*" | filter > ../$out.tmp +cd .. + +if cmp -s $out{,.tmp}; then + echo >&2 "No new diffs..." + rm -f $out.tmp + exit 0 +fi +mv -f $out{.tmp,} + +../md5 $package.spec +../dropin $out diff --git a/exim-git.patch b/exim-git.patch deleted file mode 100644 index 915f246..0000000 --- a/exim-git.patch +++ /dev/null @@ -1,1394 +0,0 @@ -commit da1aecfce80fba32b9abb328cf78088d95b7700a -Author: Heiko Schlittermann (HS12-RIPE) -Date: Wed Aug 19 15:22:41 2015 +0200 - - Fix post-transport-crash. - - The crash probably was introduced in a39bd74d3e94 and - needs 'split_spool_directory=yes' to expose. - - Thanks to Wolfgang Breyha, who found the same fix. - - (cherry picked from commit 6b51df8340eacc95e3def9a4376506610e91996c) - -diff --git a/src/src/transport.c b/src/src/transport.c -index fa6f869..a6ad3ed 100644 ---- a/src/src/transport.c -+++ b/src/src/transport.c -@@ -1752,7 +1752,7 @@ while (1) - { - if (split_spool_directory) - sprintf(CS spool_file, "%s%c/%s-D", -- spool_dir, new_message_id[5], msgq[i].message_id); -+ spool_dir, msgq[i].message_id[5], msgq[i].message_id); - else - sprintf(CS spool_file, "%s%s-D", spool_dir, msgq[i].message_id); - - -commit d7168d8b112d3ba642a25ed04de36fb76d4a847d -Author: Heiko Schlittermann (HS12-RIPE) -Date: Thu Aug 20 13:58:06 2015 +0200 - - Fix post-transport-crash: safeguard for missing spool BUG 1671 - - Based on a proposal from Wolfgang Breyha. - - (cherry picked from commit dadff1d47e54962b0fdf98e8ce5cef42b6cb7fb5) - -diff --git a/src/src/deliver.c b/src/src/deliver.c -index 78f8f4b..4154ff7 100644 ---- a/src/src/deliver.c -+++ b/src/src/deliver.c -@@ -9,6 +9,7 @@ - - - #include "exim.h" -+#include - - - /* Data block for keeping track of subprocesses for parallel remote -@@ -7904,17 +7905,36 @@ if (!regex_IGNOREQUOTA) regex_IGNOREQUOTA = - uschar * - deliver_get_sender_address (uschar * id) - { -+int rc; -+uschar * new_sender_address, -+ * save_sender_address; -+ - if (!spool_open_datafile(id)) - return NULL; - -+/* Save and restore the global sender_address. I'm not sure if we should -+not save/restore all the other global variables too, because -+spool_read_header() may change all of them. But OTOH, when this -+deliver_get_sender_address() gets called, the current message is done -+already and nobody needs the globals anymore. (HS12, 2015-08-21) */ -+ - sprintf(CS spoolname, "%s-H", id); --if (spool_read_header(spoolname, TRUE, TRUE) != spool_read_OK) -+save_sender_address = sender_address; -+ -+rc = spool_read_header(spoolname, TRUE, TRUE); -+ -+new_sender_address = sender_address; -+sender_address = save_sender_address; -+ -+if (rc != spool_read_OK) - return NULL; - -+assert(new_sender_address); -+ - (void)close(deliver_datafile); - deliver_datafile = -1; - --return sender_address; -+return new_sender_address; - } - - /* vi: aw ai sw=2 -diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c -index a952413..5ac5533 100644 ---- a/src/src/transports/smtp.c -+++ b/src/src/transports/smtp.c -@@ -1274,14 +1274,19 @@ we will veto this new message. */ - static BOOL - smtp_are_same_identities(uschar * message_id, smtp_compare_t * s_compare) - { --uschar * save_sender_address = sender_address; --uschar * current_local_identity = -+ -+uschar * message_local_identity, -+ * current_local_identity, -+ * new_sender_address; -+ -+current_local_identity = - smtp_local_identity(s_compare->current_sender_address, s_compare->tblock); --uschar * new_sender_address = deliver_get_sender_address(message_id); --uschar * message_local_identity = -- smtp_local_identity(new_sender_address, s_compare->tblock); - --sender_address = save_sender_address; -+if (!(new_sender_address = deliver_get_sender_address(message_id))) -+ return 0; -+ -+message_local_identity = -+ smtp_local_identity(new_sender_address, s_compare->tblock); - - return Ustrcmp(current_local_identity, message_local_identity) == 0; - } - -commit 9e1acebc3fbb288da804ab9031c7c448dffd841a -Author: Heiko Schlittermann (HS12-RIPE) -Date: Tue Aug 11 17:36:29 2015 +0200 - - Fix ESMTP MAIL command option processing - - If the address containes spaces, the option processing - was confused. - - (cherry picked from commit 2ef7ed082481b2dccd3c2e0eae849b24bf0b172a) - -diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c -index cf0a5d6..980d54b 100644 ---- a/src/src/smtp_in.c -+++ b/src/src/smtp_in.c -@@ -9,6 +9,7 @@ - - - #include "exim.h" -+#include - - - /* Initialize for TCP wrappers if so configured. It appears that the macro -@@ -232,6 +233,7 @@ static uschar *protocols[] = { - - /* Sanity check and validate optional args to MAIL FROM: envelope */ - enum { -+ ENV_MAIL_OPT_NULL, - ENV_MAIL_OPT_SIZE, ENV_MAIL_OPT_BODY, ENV_MAIL_OPT_AUTH, - #ifndef DISABLE_PRDR - ENV_MAIL_OPT_PRDR, -@@ -240,7 +242,6 @@ enum { - #ifdef EXPERIMENTAL_INTERNATIONAL - ENV_MAIL_OPT_UTF8, - #endif -- ENV_MAIL_OPT_NULL - }; - typedef struct { - uschar * name; /* option requested during MAIL cmd */ -@@ -260,7 +261,8 @@ static env_mail_type_t env_mail_type_list[] = { - #ifdef EXPERIMENTAL_INTERNATIONAL - { US"SMTPUTF8",ENV_MAIL_OPT_UTF8, FALSE }, /* rfc6531 */ - #endif -- { US"NULL", ENV_MAIL_OPT_NULL, FALSE } -+ /* keep this the last entry */ -+ { US"NULL", ENV_MAIL_OPT_NULL, FALSE }, - }; - - /* When reading SMTP from a remote host, we have to use our own versions of the -@@ -3887,7 +3889,7 @@ while (done <= 0) - if (!extract_option(&name, &value)) break; - - for (mail_args = env_mail_type_list; -- (char *)mail_args < (char *)env_mail_type_list + sizeof(env_mail_type_list); -+ mail_args->value != ENV_MAIL_OPT_NULL; - mail_args++ - ) - if (strcmpic(name, mail_args->name) == 0) -@@ -4066,15 +4068,17 @@ while (done <= 0) - } - break; - #endif -- /* Unknown option. Stick back the terminator characters and break -+ /* No valid option. Stick back the terminator characters and break - the loop. Do the name-terminator second as extract_option sets -- value==name when it found no equal-sign. -- An error for a malformed address will occur. */ -- default: -+ value==name when it found no equal-sign. -+ An error for a malformed address will occur. */ -+ case ENV_MAIL_OPT_NULL: - value[-1] = '='; - name[-1] = ' '; - arg_error = TRUE; - break; -+ -+ default: assert(0); - } - /* Break out of for loop if switch() had bad argument or - when start of the email address is reached */ - -commit 22c82c48aa5d23c49d38e3581810ea54587df61b -Author: Jeremy Harris -Date: Tue Aug 25 10:36:27 2015 +0100 - - Close logs after daemon-process exceptional write. Bug 728 - - (cherry picked from commit c8899c20aa08c9ae6a4c291aad23ba90512bebe4) - -diff --git a/src/src/daemon.c b/src/src/daemon.c -index 894a96f..a7a49f0 100644 ---- a/src/src/daemon.c -+++ b/src/src/daemon.c -@@ -735,6 +735,7 @@ else (void)close(dup_accept_socket); - /* Release any store used in this process, including the store used for holding - the incoming host address and an expanded active_hostname. */ - -+log_close_all(); - store_reset(reset_point); - sender_host_address = NULL; - } - -commit 4d3b8805796ffa39889060d9f216bfaf7391c542 -Author: Jeremy Harris -Date: Thu Sep 17 13:35:16 2015 +0100 - - DNS: time-limit cached returns, using TTL. Bug 1395 - - This can matter for fast-changing data such as DNSBLs. - - (cherry picked from commit 14b3c5bc64a16df07583fe4b5ef2e0129d063893) - - DNS: avoid overflow in cache TTL for negative entries. Bug 1395 - - (cherry picked from commit e162fc9757d4b8cb41aca74214e968622d6c3dee) - -diff --git a/src/src/dns.c b/src/src/dns.c -index 64958d9..abed126 100644 ---- a/src/src/dns.c -+++ b/src/src/dns.c -@@ -390,7 +390,8 @@ from the following bytes. */ - - dnss->aptr += namelen; - GETSHORT(dnss->srr.type, dnss->aptr); /* Record type */ --dnss->aptr += 6; /* Don't want class or TTL */ -+dnss->aptr += 2; /* Don't want class */ -+GETLONG(dnss->srr.ttl, dnss->aptr); /* TTL */ - GETSHORT(dnss->srr.size, dnss->aptr); /* Size of data portion */ - dnss->srr.data = dnss->aptr; /* The record's data follows */ - dnss->aptr += dnss->srr.size; /* Advance to next RR */ -diff --git a/src/src/lookupapi.h b/src/src/lookupapi.h -index cdd1c85..03de8f6 100644 ---- a/src/src/lookupapi.h -+++ b/src/src/lookupapi.h -@@ -34,7 +34,7 @@ typedef struct lookup_info { - int, /* length of key or query */ - uschar **, /* for returning answer */ - uschar **, /* for error message */ -- BOOL *); /* to request cache cleanup */ -+ uint *); /* cache TTL, sconds */ - void (*close)( /* close function */ - void *); /* handle */ - void (*tidy)(void); /* tidy function */ -@@ -46,9 +46,10 @@ typedef struct lookup_info { - } lookup_info; - - /* This magic number is used by the following lookup_module_info structure -- for checking API compatibility. It's equivalent to the string"LMM2" */ --#define LOOKUP_MODULE_INFO_MAGIC 0x4c4d4d32 -+ for checking API compatibility. It used to be equivalent to the string"LMM3" */ -+#define LOOKUP_MODULE_INFO_MAGIC 0x4c4d4933 - /* Version 2 adds: version_report */ -+/* Version 3 change: non/cache becomes TTL in seconds */ - - typedef struct lookup_module_info { - uint magic; -diff --git a/src/src/lookups/README b/src/src/lookups/README -index 98905dc..31fea64 100644 ---- a/src/src/lookups/README -+++ b/src/src/lookups/README -@@ -122,12 +122,15 @@ DEFER. The arguments are: - uschar **errmsg where to put an error message on failure; - this is initially set to "", and should be left - as that for a standard "entry not found" error -- BOOL *do_cache the lookup should set this to FALSE when it changes data. -- This is TRUE by default. When set to FALSE the cache tree -+ uint *do_cache the lookup should set this to 0 when it changes data. -+ This is MAXINT by default. When set to 0 the cache tree - of the current search handle will be cleaned and the - current result will NOT be cached. Currently the mysql - and pgsql lookups use this when UPDATE/INSERT queries are - executed. -+ If set to a nonzero number of seconds, the cached value -+ becomes unusable after this time. Currently the dnsdb -+ lookup uses this to support the TTL value. - - Even though the key is zero-terminated, the length is passed because in the - common case it has been computed already and is often needed. -diff --git a/src/src/lookups/cdb.c b/src/src/lookups/cdb.c -index ea017de..ba925dc 100644 ---- a/src/src/lookups/cdb.c -+++ b/src/src/lookups/cdb.c -@@ -279,7 +279,7 @@ cdb_find(void *handle, - int key_len, - uschar **result, - uschar **errmsg, -- BOOL *do_cache) -+ uint *do_cache) - { - struct cdb_state * cdbp = handle; - uint32 item_key_len, -diff --git a/src/src/lookups/dbmdb.c b/src/src/lookups/dbmdb.c -index 03248e4..b8c42d5 100644 ---- a/src/src/lookups/dbmdb.c -+++ b/src/src/lookups/dbmdb.c -@@ -87,7 +87,7 @@ the keylength in order to include the terminating zero. */ - - static int - dbmdb_find(void *handle, uschar *filename, const uschar *keystring, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - EXIM_DB *d = (EXIM_DB *)handle; - EXIM_DATUM key, data; -@@ -120,7 +120,7 @@ return FAIL; - - int - static dbmnz_find(void *handle, uschar *filename, const uschar *keystring, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - return dbmdb_find(handle, filename, keystring, length-1, result, errmsg, - do_cache); -@@ -140,7 +140,7 @@ return dbmdb_find(handle, filename, keystring, length-1, result, errmsg, - - static int - dbmjz_find(void *handle, uschar *filename, const uschar *keystring, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - uschar *key_item, *key_buffer, *key_p; - const uschar *key_elems = keystring; -diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c -index e3de279..70e6c8c 100644 ---- a/src/src/lookups/dnsdb.c -+++ b/src/src/lookups/dnsdb.c -@@ -131,7 +131,7 @@ separator, as always, is colon. */ - - static int - dnsdb_find(void *handle, uschar *filename, const uschar *keystring, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - int rc; - int size = 256; -@@ -388,6 +388,9 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0))) - { - if (rr->type != searchtype) continue; - -+ if (*do_cache > rr->ttl) -+ *do_cache = rr->ttl; -+ - if (type == T_A || type == T_AAAA || type == T_ADDRESSES) - { - dns_address *da; -diff --git a/src/src/lookups/dsearch.c b/src/src/lookups/dsearch.c -index f8c592a..9f7dd8d 100644 ---- a/src/src/lookups/dsearch.c -+++ b/src/src/lookups/dsearch.c -@@ -67,7 +67,7 @@ for us. */ - - int - static dsearch_find(void *handle, uschar *dirname, const uschar *keystring, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - struct stat statbuf; - int save_errno; -diff --git a/src/src/lookups/ibase.c b/src/src/lookups/ibase.c -index 23e1dea..7fd53d0 100644 ---- a/src/src/lookups/ibase.c -+++ b/src/src/lookups/ibase.c -@@ -451,7 +451,7 @@ deferred with a retryable error. */ - - static int - ibase_find(void *handle, uschar * filename, uschar * query, int length, -- uschar ** result, uschar ** errmsg, BOOL *do_cache) -+ uschar ** result, uschar ** errmsg, uint *do_cache) - { - int sep = 0; - uschar *server; -diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c -index a56eff3..b870df1 100644 ---- a/src/src/lookups/ldap.c -+++ b/src/src/lookups/ldap.c -@@ -1339,7 +1339,7 @@ The handle and filename arguments are not used. */ - - static int - eldap_find(void *handle, uschar *filename, const uschar *ldap_url, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - /* Keep picky compilers happy */ - do_cache = do_cache; -@@ -1348,7 +1348,7 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_SINGLE, result, errmsg)); - - static int - eldapm_find(void *handle, uschar *filename, const uschar *ldap_url, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - /* Keep picky compilers happy */ - do_cache = do_cache; -@@ -1357,7 +1357,7 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_MULTIPLE, result, errmsg)); - - static int - eldapdn_find(void *handle, uschar *filename, const uschar *ldap_url, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - /* Keep picky compilers happy */ - do_cache = do_cache; -@@ -1366,7 +1366,7 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_DN, result, errmsg)); - - int - eldapauth_find(void *handle, uschar *filename, const uschar *ldap_url, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - /* Keep picky compilers happy */ - do_cache = do_cache; -diff --git a/src/src/lookups/lf_functions.h b/src/src/lookups/lf_functions.h -index 73e9303..d2487d3 100644 ---- a/src/src/lookups/lf_functions.h -+++ b/src/src/lookups/lf_functions.h -@@ -12,7 +12,7 @@ extern int lf_check_file(int, uschar *, int, int, uid_t *, gid_t *, - extern uschar *lf_quote(uschar *, uschar *, int, uschar *, int *, int *); - extern int lf_sqlperform(const uschar *, const uschar *, const uschar *, - const uschar *, uschar **, -- uschar **, BOOL *, int(*)(const uschar *, uschar *, uschar **, -- uschar **, BOOL *, BOOL *)); -+ uschar **, uint *, int(*)(const uschar *, uschar *, uschar **, -+ uschar **, BOOL *, uint *)); - - /* End of lf_functions.h */ -diff --git a/src/src/lookups/lf_sqlperform.c b/src/src/lookups/lf_sqlperform.c -index 2d7f326..6d4f7a7 100644 ---- a/src/src/lookups/lf_sqlperform.c -+++ b/src/src/lookups/lf_sqlperform.c -@@ -27,7 +27,7 @@ Arguments: - query the query - result where to pass back the result - errmsg where to pass back an error message -- do_cache to be set FALSE if data is changed -+ do_cache to be set zero if data is changed - func the lookup function to call - - Returns: the return from the lookup function, or DEFER -@@ -36,8 +36,8 @@ Returns: the return from the lookup function, or DEFER - int - lf_sqlperform(const uschar *name, const uschar *optionname, - const uschar *optserverlist, const uschar *query, -- uschar **result, uschar **errmsg, BOOL *do_cache, -- int(*fn)(const uschar *, uschar *, uschar **, uschar **, BOOL *, BOOL *)) -+ uschar **result, uschar **errmsg, uint *do_cache, -+ int(*fn)(const uschar *, uschar *, uschar **, uschar **, BOOL *, uint *)) - { - int sep, rc; - uschar *server; -diff --git a/src/src/lookups/lsearch.c b/src/src/lookups/lsearch.c -index 3883d4b..eb70a45 100644 ---- a/src/src/lookups/lsearch.c -+++ b/src/src/lookups/lsearch.c -@@ -323,7 +323,7 @@ return FAIL; - - static int - lsearch_find(void *handle, uschar *filename, const uschar *keystring, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - do_cache = do_cache; /* Keep picky compilers happy */ - return internal_lsearch_find(handle, filename, keystring, length, result, -@@ -340,7 +340,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result, - - static int - wildlsearch_find(void *handle, uschar *filename, const uschar *keystring, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - do_cache = do_cache; /* Keep picky compilers happy */ - return internal_lsearch_find(handle, filename, keystring, length, result, -@@ -357,7 +357,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result, - - static int - nwildlsearch_find(void *handle, uschar *filename, const uschar *keystring, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - do_cache = do_cache; /* Keep picky compilers happy */ - return internal_lsearch_find(handle, filename, keystring, length, result, -@@ -375,7 +375,7 @@ return internal_lsearch_find(handle, filename, keystring, length, result, - - static int - iplsearch_find(void *handle, uschar *filename, const uschar *keystring, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - do_cache = do_cache; /* Keep picky compilers happy */ - if ((length == 1 && keystring[0] == '*') || -diff --git a/src/src/lookups/mysql.c b/src/src/lookups/mysql.c -index 8dff86a..1ce8831 100644 ---- a/src/src/lookups/mysql.c -+++ b/src/src/lookups/mysql.c -@@ -74,7 +74,7 @@ Arguments: - resultptr where to store the result - errmsg where to point an error message - defer_break TRUE if no more servers are to be tried after DEFER -- do_cache set false if data is changed -+ do_cache set zero if data is changed - - The server string is of the form "host/dbname/user/password". The host can be - host:port. This string is in a nextinlist temporary buffer, so can be -@@ -85,7 +85,7 @@ Returns: OK, FAIL, or DEFER - - static int - perform_mysql_search(const uschar *query, uschar *server, uschar **resultptr, -- uschar **errmsg, BOOL *defer_break, BOOL *do_cache) -+ uschar **errmsg, BOOL *defer_break, uint *do_cache) - { - MYSQL *mysql_handle = NULL; /* Keep compilers happy */ - MYSQL_RES *mysql_result = NULL; -@@ -225,7 +225,7 @@ can be detected by calling mysql_field_count(). If its result is zero, no data - was expected (this is all explained clearly in the MySQL manual). In this case, - we return the number of rows affected by the command. In this event, we do NOT - want to cache the result; also the whole cache for the handle must be cleaned --up. Setting do_cache FALSE requests this. */ -+up. Setting do_cache zero requests this. */ - - if ((mysql_result = mysql_use_result(mysql_handle)) == NULL) - { -@@ -233,7 +233,7 @@ if ((mysql_result = mysql_use_result(mysql_handle)) == NULL) - { - DEBUG(D_lookup) debug_printf("MYSQL: query was not one that returns data\n"); - result = string_sprintf("%d", mysql_affected_rows(mysql_handle)); -- *do_cache = FALSE; -+ *do_cache = 0; - goto MYSQL_EXIT; - } - *errmsg = string_sprintf("MYSQL: lookup result failed: %s\n", -@@ -341,7 +341,7 @@ shared with other SQL lookups. */ - - static int - mysql_find(void *handle, uschar *filename, const uschar *query, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - return lf_sqlperform(US"MySQL", US"mysql_servers", mysql_servers, query, - result, errmsg, do_cache, perform_mysql_search); -diff --git a/src/src/lookups/nis.c b/src/src/lookups/nis.c -index 7b012b1..1faa884 100644 ---- a/src/src/lookups/nis.c -+++ b/src/src/lookups/nis.c -@@ -42,7 +42,7 @@ code. */ - - static int - nis_find(void *handle, uschar *filename, uschar *keystring, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - int rc; - uschar *nis_data; -@@ -68,7 +68,7 @@ return (rc == YPERR_KEY || rc == YPERR_MAP)? FAIL : DEFER; - - static int - nis0_find(void *handle, uschar *filename, uschar *keystring, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - int rc; - uschar *nis_data; -diff --git a/src/src/lookups/nisplus.c b/src/src/lookups/nisplus.c -index 8895cee..a4a7a2d 100644 ---- a/src/src/lookups/nisplus.c -+++ b/src/src/lookups/nisplus.c -@@ -43,7 +43,7 @@ equals sign. */ - - static int - nisplus_find(void *handle, uschar *filename, uschar *query, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - int i; - int ssize = 0; -diff --git a/src/src/lookups/oracle.c b/src/src/lookups/oracle.c -index 1f2520a..adb17b4 100644 ---- a/src/src/lookups/oracle.c -+++ b/src/src/lookups/oracle.c -@@ -517,7 +517,7 @@ deferred with a retryable error. */ - - static int - oracle_find(void *handle, uschar *filename, uschar *query, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - int sep = 0; - uschar *server; -diff --git a/src/src/lookups/passwd.c b/src/src/lookups/passwd.c -index e726f3e..315677f 100644 ---- a/src/src/lookups/passwd.c -+++ b/src/src/lookups/passwd.c -@@ -34,7 +34,7 @@ return (void *)(-1); /* Just return something non-null */ - - static int - passwd_find(void *handle, uschar *filename, const uschar *keystring, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - struct passwd *pw; - -diff --git a/src/src/lookups/pgsql.c b/src/src/lookups/pgsql.c -index c86ac23..4be3d98 100644 ---- a/src/src/lookups/pgsql.c -+++ b/src/src/lookups/pgsql.c -@@ -119,7 +119,7 @@ Returns: OK, FAIL, or DEFER - - static int - perform_pgsql_search(const uschar *query, uschar *server, uschar **resultptr, -- uschar **errmsg, BOOL *defer_break, BOOL *do_cache) -+ uschar **errmsg, BOOL *defer_break, uint *do_cache) - { - PGconn *pg_conn = NULL; - PGresult *pg_result = NULL; -@@ -290,10 +290,10 @@ else - /* The command was successful but did not return any data since it was - * not SELECT but either an INSERT, UPDATE or DELETE statement. Tell the - * high level code to not cache this query, and clean the current cache for -- * this handle by setting *do_cache FALSE. */ -+ * this handle by setting *do_cache zero. */ - result = string_copy(US PQcmdTuples(pg_result)); - offset = Ustrlen(result); -- *do_cache = FALSE; -+ *do_cache = 0; - DEBUG(D_lookup) debug_printf("PGSQL: command does not return any data " - "but was successful. Rows affected: %s\n", result); - -@@ -399,7 +399,7 @@ shared with other SQL lookups. */ - - static int - pgsql_find(void *handle, uschar *filename, const uschar *query, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - return lf_sqlperform(US"PostgreSQL", US"pgsql_servers", pgsql_servers, query, - result, errmsg, do_cache, perform_pgsql_search); -diff --git a/src/src/lookups/redis.c b/src/src/lookups/redis.c -index ac4d0ec..18cd3a0 100644 ---- a/src/src/lookups/redis.c -+++ b/src/src/lookups/redis.c -@@ -65,7 +65,7 @@ redis_tidy(void) - */ - static int - perform_redis_search(uschar *command, uschar *server, uschar **resultptr, -- uschar **errmsg, BOOL *defer_break, BOOL *do_cache) -+ uschar **errmsg, BOOL *defer_break, uint *do_cache) - { - redisContext *redis_handle = NULL; /* Keep compilers happy */ - redisReply *redis_reply = NULL; -@@ -197,7 +197,7 @@ perform_redis_search(uschar *command, uschar *server, uschar **resultptr, - case REDIS_REPLY_ERROR: - *errmsg = string_sprintf("REDIS: lookup result failed: %s\n", redis_reply->str); - *defer_break = FALSE; -- *do_cache = FALSE; -+ *do_cache = 0; - goto REDIS_EXIT; - /* NOTREACHED */ - -@@ -205,7 +205,7 @@ perform_redis_search(uschar *command, uschar *server, uschar **resultptr, - case REDIS_REPLY_NIL: - DEBUG(D_lookup) debug_printf("REDIS: query was not one that returned any data\n"); - result = string_sprintf(""); -- *do_cache = FALSE; -+ *do_cache = 0; - goto REDIS_EXIT; - /* NOTREACHED */ - -@@ -304,7 +304,7 @@ perform_redis_search(uschar *command, uschar *server, uschar **resultptr, - - static int - redis_find(void *handle __attribute__((unused)), uschar *filename __attribute__((unused)), -- uschar *command, int length, uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar *command, int length, uschar **result, uschar **errmsg, uint *do_cache) - { - return lf_sqlperform(US"Redis", US"redis_servers", redis_servers, command, - result, errmsg, do_cache, perform_redis_search); -diff --git a/src/src/lookups/spf.c b/src/src/lookups/spf.c -index 23ad2ad..2671fc9 100644 ---- a/src/src/lookups/spf.c -+++ b/src/src/lookups/spf.c -@@ -31,7 +31,9 @@ static void dummy(int x) { dummy2(x-1); } - #include - #include - --static void *spf_open(uschar *filename, uschar **errmsg) { -+static void * -+spf_open(uschar *filename, uschar **errmsg) -+{ - SPF_server_t *spf_server = NULL; - spf_server = SPF_server_new(SPF_DNS_CACHE, 0); - if (spf_server == NULL) { -@@ -41,13 +43,17 @@ static void *spf_open(uschar *filename, uschar **errmsg) { - return (void *) spf_server; - } - --static void spf_close(void *handle) { -+static void -+spf_close(void *handle) -+{ - SPF_server_t *spf_server = handle; - if (spf_server) SPF_server_free(spf_server); - } - --static int spf_find(void *handle, uschar *filename, uschar *keystring, int key_len, -- uschar **result, uschar **errmsg, BOOL *do_cache) { -+static int -+spf_find(void *handle, uschar *filename, uschar *keystring, int key_len, -+ uschar **result, uschar **errmsg, uint *do_cache) -+{ - SPF_server_t *spf_server = handle; - SPF_request_t *spf_request = NULL; - SPF_response_t *spf_response = NULL; -diff --git a/src/src/lookups/sqlite.c b/src/src/lookups/sqlite.c -index bb92c8c..e2330f9 100644 ---- a/src/src/lookups/sqlite.c -+++ b/src/src/lookups/sqlite.c -@@ -81,7 +81,7 @@ return 0; - - static int - sqlite_find(void *handle, uschar *filename, const uschar *query, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - int ret; - struct strbuf res = { NULL, 0, 0 }; -@@ -93,7 +93,7 @@ if (ret != SQLITE_OK) - return FAIL; - } - --if (res.string == NULL) *do_cache = FALSE; -+if (res.string == NULL) *do_cache = 0; - - *result = res.string; - return OK; -diff --git a/src/src/lookups/testdb.c b/src/src/lookups/testdb.c -index c82fa7f..401f7c8 100644 ---- a/src/src/lookups/testdb.c -+++ b/src/src/lookups/testdb.c -@@ -38,7 +38,7 @@ return (void *)(1); /* Just return something non-null */ - - static int - testdb_find(void *handle, uschar *filename, const uschar *query, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - handle = handle; /* Keep picky compilers happy */ - filename = filename; -@@ -57,7 +57,7 @@ if (Ustrcmp(query, "defer") == 0) - return DEFER; - } - --if (Ustrcmp(query, "nocache") == 0) *do_cache = FALSE; -+if (Ustrcmp(query, "nocache") == 0) *do_cache = 0; - - *result = string_copy(query); - return OK; -diff --git a/src/src/lookups/whoson.c b/src/src/lookups/whoson.c -index 4166089..9ac5a3a 100644 ---- a/src/src/lookups/whoson.c -+++ b/src/src/lookups/whoson.c -@@ -36,7 +36,7 @@ return (void *)(1); /* Just return something non-null */ - - static int - whoson_find(void *handle, uschar *filename, uschar *query, int length, -- uschar **result, uschar **errmsg, BOOL *do_cache) -+ uschar **result, uschar **errmsg, uint *do_cache) - { - uschar buffer[80]; - handle = handle; /* Keep picky compilers happy */ -diff --git a/src/src/search.c b/src/src/search.c -index a055291..cd522da 100644 ---- a/src/src/search.c -+++ b/src/src/search.c -@@ -466,6 +466,7 @@ internal_search_find(void *handle, uschar *filename, uschar *keystring) - { - tree_node *t = (tree_node *)handle; - search_cache *c = (search_cache *)(t->data.ptr); -+expiring_data *e; - uschar *data = NULL; - int search_type = t->name[0] - '0'; - int old_pool = store_pool; -@@ -491,18 +492,27 @@ store_pool = POOL_SEARCH; - /* Look up the data for the key, unless it is already in the cache for this - file. No need to check c->item_cache for NULL, tree_search will do so. */ - --if ((t = tree_search(c->item_cache, keystring)) == NULL) -+if ( (t = tree_search(c->item_cache, keystring)) -+ && (!(e = t->data.ptr)->expiry || e->expiry > time(NULL)) -+ ) -+ { /* Data was in the cache already; set the pointer from the tree node */ -+ data = e->ptr; -+ DEBUG(D_lookup) debug_printf("cached data used for lookup of %s%s%s\n", -+ keystring, -+ filename ? US"\n in " : US"", filename ? filename : US""); -+ } -+else - { -- BOOL do_cache = TRUE; -+ uint do_cache = UINT_MAX; - int keylength = Ustrlen(keystring); - - DEBUG(D_lookup) - { -- if (filename != NULL) -- debug_printf("file lookup required for %s\n in %s\n", -- keystring, filename); -- else -- debug_printf("database lookup required for %s\n", keystring); -+ if (t) debug_printf("cached data found but past valid time; "); -+ debug_printf("%s lookup required for %s%s%s\n", -+ filename ? US"file" : US"database", -+ keystring, -+ filename ? US"\n in " : US"", filename ? filename : US""); - } - - /* Call the code for the different kinds of search. DEFER is handled -@@ -511,9 +521,7 @@ if ((t = tree_search(c->item_cache, keystring)) == NULL) - - if (lookup_list[search_type]->find(c->handle, filename, keystring, keylength, - &data, &search_error_message, &do_cache) == DEFER) -- { - search_find_defer = TRUE; -- } - - /* A record that has been found is now in data, which is either NULL - or points to a bit of dynamic store. Cache the result of the lookup if -@@ -524,10 +532,22 @@ if ((t = tree_search(c->item_cache, keystring)) == NULL) - else if (do_cache) - { - int len = keylength + 1; -- t = store_get(sizeof(tree_node) + len); -- memcpy(t->name, keystring, len); -- t->data.ptr = data; -- tree_insertnode(&c->item_cache, t); -+ -+ if (t) /* Previous, out-of-date cache entry. Update with the */ -+ { /* new result and forget the old one */ -+ e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache; -+ e->ptr = data; -+ } -+ else -+ { -+ t = store_get(sizeof(tree_node) + len + sizeof(expiring_data)); -+ e = (expiring_data *)((char *)t + sizeof(tree_node) + len); -+ e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache; -+ e->ptr = data; -+ memcpy(t->name, keystring, len); -+ t->data.ptr = e; -+ tree_insertnode(&c->item_cache, t); -+ } - } - - /* If caching was disabled, empty the cache tree. We just set the cache -@@ -540,34 +560,19 @@ if ((t = tree_search(c->item_cache, keystring)) == NULL) - } - } - --/* Data was in the cache already; set the pointer from the tree node */ -- --else -- { -- data = US t->data.ptr; -- DEBUG(D_lookup) debug_printf("cached data used for lookup of %s%s%s\n", -- keystring, -- (filename == NULL)? US"" : US"\n in ", -- (filename == NULL)? US"" : filename); -- } -- --/* Debug: output the answer */ -- - DEBUG(D_lookup) - { -- if (data == NULL) -- { -- if (search_find_defer) debug_printf("lookup deferred: %s\n", -- search_error_message); -- else debug_printf("lookup failed\n"); -- } -- else debug_printf("lookup yielded: %s\n", data); -+ if (data) -+ debug_printf("lookup yielded: %s\n", data); -+ else if (search_find_defer) -+ debug_printf("lookup deferred: %s\n", search_error_message); -+ else debug_printf("lookup failed\n"); - } - - /* Return it in new dynamic store in the regular pool */ - - store_pool = old_pool; --return (data == NULL)? NULL : string_copy(data); -+return data ? string_copy(data) : NULL; - } - - -diff --git a/src/src/structs.h b/src/src/structs.h -index 6f143d6..d9da38b 100644 ---- a/src/src/structs.h -+++ b/src/src/structs.h -@@ -657,6 +657,16 @@ typedef struct tree_node { - uschar name[1]; /* node name - variable length */ - } tree_node; - -+/* Structure for holding time-limited data such as DNS returns. -+We use this rather than extending tree_node to avoid wasting -+space for most tree use (variables...) at the cost of complexity -+for the lookups cache */ -+ -+typedef struct expiring_data { -+ time_t expiry; /* if nonzero, data invalid after this time */ -+ void *ptr; /* pointer to data */ -+} expiring_data; -+ - /* Structure for holding the handle and the cached last lookup for searches. - This block is pointed to by the tree entry for the file. The file can get - closed if too many are opened at once. There is a LRU chain for deciding which -@@ -676,6 +686,7 @@ uncompressed, but the data pointer is into the raw data. */ - typedef struct { - uschar name[DNS_MAXNAME]; /* domain name */ - int type; /* record type */ -+ unsigned short ttl; /* time-to-live, seconds */ - int size; /* size of data */ - uschar *data; /* pointer to data */ - } dns_record; -diff --git a/src/src/verify.c b/src/src/verify.c -index e00e7b9..d392fda 100644 ---- a/src/src/verify.c -+++ b/src/src/verify.c -@@ -21,6 +21,7 @@ uschar ctbuffer[8192]; - /* Structure for caching DNSBL lookups */ - - typedef struct dnsbl_cache_block { -+ time_t expiry; - dns_address *rhs; - uschar *text; - int rc; -@@ -3584,21 +3585,37 @@ if (!string_format(query, sizeof(query), "%s.%s", prepend, domain)) - - /* Look for this query in the cache. */ - --t = tree_search(dnsbl_cache, query); -+if ( (t = tree_search(dnsbl_cache, query)) -+ && (cb = t->data.ptr)->expiry > time(NULL) -+ ) -+ -+/* Previous lookup was cached */ -+ -+ { -+ HDEBUG(D_dnsbl) debug_printf("using result of previous DNS lookup\n"); -+ } - - /* If not cached from a previous lookup, we must do a DNS lookup, and - cache the result in permanent memory. */ - --if (t == NULL) -+else - { -+ uint ttl = 3600; -+ - store_pool = POOL_PERM; - -- /* Set up a tree entry to cache the lookup */ -+ if (t) -+ { -+ HDEBUG(D_dnsbl) debug_printf("cached data found but past valid time; "); -+ } - -- t = store_get(sizeof(tree_node) + Ustrlen(query)); -- Ustrcpy(t->name, query); -- t->data.ptr = cb = store_get(sizeof(dnsbl_cache_block)); -- (void)tree_insertnode(&dnsbl_cache, t); -+ else -+ { /* Set up a tree entry to cache the lookup */ -+ t = store_get(sizeof(tree_node) + Ustrlen(query)); -+ Ustrcpy(t->name, query); -+ t->data.ptr = cb = store_get(sizeof(dnsbl_cache_block)); -+ (void)tree_insertnode(&dnsbl_cache, t); -+ } - - /* Do the DNS loopup . */ - -@@ -3616,7 +3633,10 @@ if (t == NULL) - - Quite apart from one A6 RR generating multiple addresses, there are DNS - lists that return more than one A record, so we must handle multiple -- addresses generated in that way as well. */ -+ addresses generated in that way as well. -+ -+ Mark the cache entry with the "now" plus the minimum of the address TTLs, -+ or some suitably far-future time if none were found. */ - - if (cb->rc == DNS_SUCCEED) - { -@@ -3634,6 +3654,7 @@ if (t == NULL) - *addrp = da; - while (da->next != NULL) da = da->next; - addrp = &(da->next); -+ if (ttl > rr->ttl) ttl = rr->ttl; - } - } - } -@@ -3645,17 +3666,10 @@ if (t == NULL) - if (cb->rhs == NULL) cb->rc = DNS_NODATA; - } - -+ cb->expiry = time(NULL)+ttl; - store_pool = old_pool; - } - --/* Previous lookup was cached */ -- --else -- { -- HDEBUG(D_dnsbl) debug_printf("using result of previous DNS lookup\n"); -- cb = t->data.ptr; -- } -- - /* We now have the result of the DNS lookup, either newly done, or cached - from a previous call. If the lookup succeeded, check against the address - list if there is one. This may be a positive equality list (introduced by - -commit c4dcf906ceb3a45c6b30f76476d73ca836b262cd -Author: Jeremy Harris -Date: Sat Sep 19 13:59:22 2015 +0100 - - Retry: always use interface, if set, for retry DB key. Bug 1678 - - Even constant values must be used, as multiple transports with - different values may be in play and should be kept distinct. - - (cherry picked from commit 6f6dedccb47f231a0712d882da20feffbac8d0bc) - -diff --git a/src/src/functions.h b/src/src/functions.h -index 0257904..94e3f5f 100644 ---- a/src/src/functions.h -+++ b/src/src/functions.h -@@ -374,7 +374,7 @@ extern int smtp_sock_connect(host_item *, int, int, uschar *, - extern int smtp_feof(void); - extern int smtp_ferror(void); - extern uschar *smtp_get_connection_info(void); --extern BOOL smtp_get_interface(uschar *, int, address_item *, BOOL *, -+extern BOOL smtp_get_interface(uschar *, int, address_item *, - uschar **, uschar *); - extern BOOL smtp_get_port(uschar *, address_item *, int *, uschar *); - extern int smtp_getc(void); -diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c -index c704a0b..2fdf38b 100644 ---- a/src/src/smtp_out.c -+++ b/src/src/smtp_out.c -@@ -26,7 +26,6 @@ Arguments: - which case the function does nothing - host_af AF_INET or AF_INET6 for the outgoing IP address - addr the mail address being handled (for setting errors) -- changed if not NULL, set TRUE if expansion actually changed istring - interface point this to the interface - msg to add to any error message - -@@ -36,7 +35,7 @@ Returns: TRUE on success, FALSE on failure, with error message - - BOOL - smtp_get_interface(uschar *istring, int host_af, address_item *addr, -- BOOL *changed, uschar **interface, uschar *msg) -+ uschar **interface, uschar *msg) - { - const uschar * expint; - uschar *iface; -@@ -54,8 +53,6 @@ if (expint == NULL) - return FALSE; - } - --if (changed != NULL) *changed = expint != istring; -- - while (isspace(*expint)) expint++; - if (*expint == 0) return TRUE; - -diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c -index 5ac5533..ba7fb5e 100644 ---- a/src/src/transports/smtp.c -+++ b/src/src/transports/smtp.c -@@ -3174,7 +3174,6 @@ for (cutoff_retry = 0; expired && - BOOL serialized = FALSE; - BOOL host_is_expired = FALSE; - BOOL message_defer = FALSE; -- BOOL ifchanges = FALSE; - BOOL some_deferred = FALSE; - address_item *first_addr = NULL; - uschar *interface = NULL; -@@ -3350,15 +3349,18 @@ for (cutoff_retry = 0; expired && - if (Ustrcmp(pistring, ":25") == 0) pistring = US""; - - /* Select IPv4 or IPv6, and choose an outgoing interface. If the interface -- string changes upon expansion, we must add it to the key that is used for -- retries, because connections to the same host from a different interface -- should be treated separately. */ -+ string is set, even if constant (as different transports can have different -+ constant settings), we must add it to the key that is used for retries, -+ because connections to the same host from a different interface should be -+ treated separately. */ - - host_af = (Ustrchr(host->address, ':') == NULL)? AF_INET : AF_INET6; -- if (!smtp_get_interface(ob->interface, host_af, addrlist, &ifchanges, -- &interface, tid)) -- return FALSE; -- if (ifchanges) pistring = string_sprintf("%s/%s", pistring, interface); -+ if ((rs = ob->interface) && *rs) -+ { -+ if (!smtp_get_interface(rs, host_af, addrlist, &interface, tid)) -+ return FALSE; -+ pistring = string_sprintf("%s/%s", pistring, interface); -+ } - - /* The first time round the outer loop, check the status of the host by - inspecting the retry data. The second time round, we are interested only -diff --git a/src/src/verify.c b/src/src/verify.c -index d392fda..6411c7e 100644 ---- a/src/src/verify.c -+++ b/src/src/verify.c -@@ -444,7 +444,7 @@ can do it there for the non-rcpt-verify case. For this we keep an addresscount. - - host_af = (Ustrchr(host->address, ':') == NULL)? AF_INET:AF_INET6; - -- if (!smtp_get_interface(tf->interface, host_af, addr, NULL, &interface, -+ if (!smtp_get_interface(tf->interface, host_af, addr, &interface, - US"callout") || - !smtp_get_port(tf->port, addr, &port, US"callout")) - log_write(0, LOG_MAIN|LOG_PANIC, "<%s>: %s", addr->address, -@@ -579,7 +579,7 @@ can do it there for the non-rcpt-verify case. For this we keep an addresscount. - deliver_domain = addr->domain; - transport_name = addr->transport->name; - -- if ( !smtp_get_interface(tf->interface, host_af, addr, NULL, &interface, -+ if ( !smtp_get_interface(tf->interface, host_af, addr, &interface, - US"callout") - || !smtp_get_port(tf->port, addr, &port, US"callout") - ) - -commit 1bd52978055bc07dfa150d296ffb344f10fff7fe -Author: Jeremy Harris -Date: Mon Nov 2 19:03:26 2015 +0000 - - Avoid misaligned access in cached lookup. Bug 1708 - - (cherry picked from commit 98b98887f926be87eabccc7919e57ce625c63c03) - -diff --git a/src/src/search.c b/src/src/search.c -index cd522da..ccad250 100644 ---- a/src/src/search.c -+++ b/src/src/search.c -@@ -540,10 +540,10 @@ else - } - else - { -- t = store_get(sizeof(tree_node) + len + sizeof(expiring_data)); -- e = (expiring_data *)((char *)t + sizeof(tree_node) + len); -+ e = store_get(sizeof(expiring_data) + sizeof(tree_node) + len); - e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache; - e->ptr = data; -+ t = (tree_node *)(e+1); - memcpy(t->name, keystring, len); - t->data.ptr = e; - tree_insertnode(&c->item_cache, t); - -commit e7c3de301824738c6f302e02e566f9da75d3130c -Author: Jeremy Harris -Date: Thu Oct 15 21:40:17 2015 +0100 - - DKIM: ignore space & tab embedded in base64 during decode. Bug 1700 - - (cherry picked from commit 0f557e9065b0bcfce38ee1fea5fc947bf0c5431c) - -diff --git a/src/src/pdkim/base64.c b/src/src/pdkim/base64.c -index a82fc2d..1395be4 100644 ---- a/src/src/pdkim/base64.c -+++ b/src/src/pdkim/base64.c -@@ -128,20 +128,22 @@ int base64_decode( unsigned char *dst, int *dlen, - - for( i = j = n = 0; i < slen; i++ ) - { -+ unsigned char c = src[i]; -+ - if( ( slen - i ) >= 2 && -- src[i] == '\r' && src[i + 1] == '\n' ) -+ c == '\r' && src[i + 1] == '\n' ) - continue; - -- if( src[i] == '\n' ) -+ if( c == '\n' || c == ' ' || c == '\t' ) - continue; - -- if( src[i] == '=' && ++j > 2 ) -+ if( c == '=' && ++j > 2 ) - return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); - -- if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) -+ if( c > 127 || base64_dec_map[src[i]] == 127 ) - return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); - -- if( base64_dec_map[src[i]] < 64 && j != 0 ) -+ if( base64_dec_map[c] < 64 && j != 0 ) - return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); - - n++; -@@ -160,11 +162,13 @@ int base64_decode( unsigned char *dst, int *dlen, - - for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) - { -- if( *src == '\r' || *src == '\n' ) -+ unsigned char c = *src; -+ -+ if( c == '\r' || c == '\n' || c == ' ' || c == '\t' ) - continue; - -- j -= ( base64_dec_map[*src] == 64 ); -- x = (x << 6) | ( base64_dec_map[*src] & 0x3F ); -+ j -= ( base64_dec_map[c] == 64 ); -+ x = (x << 6) | ( base64_dec_map[c] & 0x3F ); - - if( ++n == 4 ) - { - -commit a23a9d099ac9d112a6d961e00539bcf1bbb1ef7e -Author: Jeremy Harris -Date: Wed Nov 25 17:49:03 2015 +0000 - - MIME: fix crash on filenames having null charset. Bug 1730 - - (cherry picked from commit 622dbd6a512d2c7786125e3b80e96a43e54b8e90) - -diff --git a/src/src/mime.c b/src/src/mime.c -index 618364a..cc9ffb7 100644 ---- a/src/src/mime.c -+++ b/src/src/mime.c -@@ -550,7 +550,8 @@ int size = 0, ptr = 0; - uschar * val = string_cat(NULL, &size, &ptr, US"=?", 2); - uschar c; - --val = string_cat(val, &size, &ptr, charset, Ustrlen(charset)); -+if (charset) -+ val = string_cat(val, &size, &ptr, charset, Ustrlen(charset)); - val = string_cat(val, &size, &ptr, US"?Q?", 3); - - while ((c = *fname)) -@@ -607,7 +608,7 @@ while(1) - if (!fgets(CS header, MIME_MAX_HEADER_SIZE, f)) - { - /* Hit EOF or read error. Ugh. */ -- DEBUG(D_acl) debug_printf("Hit EOF ...\n"); -+ DEBUG(D_acl) debug_printf("MIME: Hit EOF ...\n"); - return rc; - } - -@@ -619,12 +620,12 @@ while(1) - if (Ustrncmp((header+2+Ustrlen(context->boundary)), "--", 2) == 0) - { - /* END boundary found */ -- DEBUG(D_acl) debug_printf("End boundary found %s\n", -+ DEBUG(D_acl) debug_printf("MIME: End boundary found %s\n", - context->boundary); - return rc; - } - -- DEBUG(D_acl) debug_printf("Next part with boundary %s\n", -+ DEBUG(D_acl) debug_printf("MIME: Next part with boundary %s\n", - context->boundary); - break; - } -@@ -648,7 +649,7 @@ while(1) - - for (q = p; *q != ';' && *q; q++) ; - *mh->value = string_copynlc(p, q-p); -- DEBUG(D_acl) debug_printf("found %s MIME header, value is '%s'\n", -+ DEBUG(D_acl) debug_printf("MIME: found %s header, value is '%s'\n", - mh->name, *mh->value); - - if (*(p = q)) p++; /* jump past the ; */ -@@ -666,7 +667,7 @@ while(1) - { - mime_parameter * mp; - -- DEBUG(D_acl) debug_printf(" considering paramlist '%s'\n", p); -+ DEBUG(D_acl) debug_printf("MIME: considering paramlist '%s'\n", p); - - if ( !mime_filename - && strncmpic(CUS"content-disposition:", header, 20) == 0 -@@ -700,22 +701,27 @@ while(1) - uschar * s = q; - - /* look for a ' in the "filename" */ -- while(*s != '\'' && *s) s++; /* s is ' or NUL */ -+ while(*s != '\'' && *s) s++; /* s is 1st ' or NUL */ - - if ((size = s-q) > 0) -- { - mime_filename_charset = string_copyn(q, size); -- p = s; - -- while(*p == '\'' && *p) p++; /* p is after ' */ -- } -+ if (*(p = s)) p++; -+ while(*p == '\'') p++; /* p is after 2nd ' */ - } - else - p = q; - -+ DEBUG(D_acl) debug_printf("MIME: charset %s fname '%s'\n", -+ mime_filename_charset ? mime_filename_charset : US"", p); -+ - temp_string = rfc2231_to_2047(p, mime_filename_charset, &slen); -- temp_string = rfc2047_decode(temp_string, FALSE, NULL, 32, -+ DEBUG(D_acl) debug_printf("MIME: 2047-name %s\n", temp_string); -+ -+ temp_string = rfc2047_decode(temp_string, FALSE, NULL, ' ', - NULL, &err_msg); -+ DEBUG(D_acl) debug_printf("MIME: plain-name %s\n", temp_string); -+ - size = Ustrlen(temp_string); - - if (size == slen) -@@ -750,7 +756,7 @@ while(1) - &dummy_errstr) - : NULL; - DEBUG(D_acl) debug_printf( -- " found %s MIME parameter in %s header, value '%s'\n", -+ "MIME: found %s parameter in %s header, value '%s'\n", - mp->name, mh->name, *mp->value); - - break; /* done matching param names */ -@@ -768,7 +774,7 @@ while(1) - if (decoding_failed) mime_filename = mime_fname_rfc2231; - - DEBUG(D_acl) debug_printf( -- " found %s MIME parameter in %s header, value is '%s'\n", -+ "MIME: found %s parameter in %s header, value is '%s'\n", - "filename", mh->name, mime_filename); - } - } -@@ -809,8 +815,9 @@ while(1) - (nested_context.boundary != NULL) && - (Ustrncmp(mime_content_type,"multipart",9) == 0) ) - { -- DEBUG(D_acl) debug_printf("Entering multipart recursion, boundary '%s'\n", -- nested_context.boundary); -+ DEBUG(D_acl) -+ debug_printf("MIME: Entering multipart recursion, boundary '%s'\n", -+ nested_context.boundary); - - nested_context.context = - context && context->context == MBC_ATTACHMENT - -commit 8d58e3501ce731c5d6d5efc9e76058832d4bc941 -Author: Jeremy Harris -Date: Thu Jan 21 15:37:08 2016 +0000 - - Cutthrough: Fix bug with dot-only line - - (cherry picked from commit 1bc460a64a0de0766d21f4f8660c6597bc410cbc) - -diff --git a/src/src/receive.c b/src/src/receive.c -index 64cf1ae..d1f81d3 100644 ---- a/src/src/receive.c -+++ b/src/src/receive.c -@@ -835,7 +835,15 @@ while ((ch = (receive_getc)()) != EOF) - ch_state = 4; - continue; - } -- ch_state = 1; /* The dot itself is removed */ -+ /* The dot was removed at state 3. For a doubled dot, here, reinstate -+ it to cutthrough. The current ch, dot or not, is passed both to cutthrough -+ and to file below. */ -+ if (ch == '.') -+ { -+ uschar c= ch; -+ (void) cutthrough_puts(&c, 1); -+ } -+ ch_state = 1; - break; - - case 4: /* After [CR] LF . CR */ diff --git a/exim-memleak.patch b/exim-memleak.patch deleted file mode 100644 index 8fd83ec..0000000 --- a/exim-memleak.patch +++ /dev/null @@ -1,43 +0,0 @@ -commit 65e061b76867a9ea7aeeb535341b790b90ae6c21 -Author: Heiko Schlittermann (HS12-RIPE) -Date: Wed May 31 23:08:56 2017 +0200 - - Cleanup (prevent repeated use of -p/-oMr to avoid mem leak) - -diff --git a/src/src/exim.c b/src/src/exim.c -index 67583e58..88e11977 100644 ---- a/src/src/exim.c -+++ b/src/src/exim.c -@@ -3106,7 +3106,14 @@ for (i = 1; i < argc; i++) - - /* -oMr: Received protocol */ - -- else if (Ustrcmp(argrest, "Mr") == 0) received_protocol = argv[++i]; -+ else if (Ustrcmp(argrest, "Mr") == 0) -+ -+ if (received_protocol) -+ { -+ fprintf(stderr, "received_protocol is set already\n"); -+ exit(EXIT_FAILURE); -+ } -+ else received_protocol = argv[++i]; - - /* -oMs: Set sender host name */ - -@@ -3202,7 +3209,15 @@ for (i = 1; i < argc; i++) - - if (*argrest != 0) - { -- uschar *hn = Ustrchr(argrest, ':'); -+ uschar *hn; -+ -+ if (received_protocol) -+ { -+ fprintf(stderr, "received_protocol is set already\n"); -+ exit(EXIT_FAILURE); -+ } -+ -+ hn = Ustrchr(argrest, ':'); - if (hn == NULL) - { - received_protocol = argrest; diff --git a/exim.spec b/exim.spec index 4d771ef..d079188 100644 --- a/exim.spec +++ b/exim.spec @@ -24,7 +24,7 @@ Summary(pl.UTF-8): Agent Transferu Poczty Uniwersytetu w Cambridge Summary(pt_BR.UTF-8): Servidor de correio eletrônico exim Name: exim Version: 4.89 -Release: 5 +Release: 6 Epoch: 2 License: GPL Group: Networking/Daemons/SMTP @@ -50,6 +50,7 @@ Source15: %{name}4-smtp.pamd Source16: %{name}on.png # git log -p exim-4_87..exim-4_87+fixes --reverse -- . ":(exclude)doc/doc-*" ":(exclude)test" ":(exclude).*" > exim-git.patch Patch100: %{name}-git.patch +# Patch100-md5: a57cd93f4d57b26258aab2670668497e Patch0: %{name}4-EDITME.patch Patch1: %{name}4-monitor-EDITME.patch Patch2: %{name}4-cflags.patch @@ -58,7 +59,7 @@ Patch4: %{name}4-Makefile-Default.patch # http://marc.merlins.org/linux/exim/files/sa-exim-cvs/localscan_dlopen_exim_4.20_or_better.patch Patch5: localscan_dlopen_%{name}_4.20_or_better.patch Patch6: exim-commandline_checks_require_admin.patch -Patch7: exim-memleak.patch + Patch8: %{name}-spam-timeout.patch Patch10: %{name}-force-sigalrm.patch @@ -176,7 +177,7 @@ Pliki nagłówkowe dla Exima. %prep %setup -q -a1 -a7 -#%patch100 -p2 +%patch100 -p2 %patch0 -p1 %patch1 -p1 @@ -185,7 +186,7 @@ Pliki nagłówkowe dla Exima. %patch4 -p1 %patch5 -p1 %patch6 -p2 -%patch7 -p2 + %patch8 -p1 %patch10 -p1