Merge branch '4.next'
authorJeremy Harris <jgh146exb@wizmail.org>
Mon, 1 Jun 2020 16:07:44 +0000 (17:07 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Mon, 1 Jun 2020 16:15:31 +0000 (17:15 +0100)
80 files changed:
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
doc/doc-txt/OptionLists.txt
doc/doc-txt/experimental-spec.txt
src/OS/Makefile-Darwin
src/src/EDITME
src/src/acl.c
src/src/auths/gsasl_exim.c
src/src/child.c
src/src/config.h.defaults
src/src/configure.default
src/src/daemon.c
src/src/deliver.c
src/src/drtables.c
src/src/exim.c
src/src/exim.h
src/src/expand.c
src/src/functions.h
src/src/globals.c
src/src/globals.h
src/src/lookups/lmdb.c
src/src/macro_predef.c
src/src/macros.h
src/src/queue.c
src/src/readconf.c
src/src/receive.c
src/src/routers/queryprogram.c
src/src/routers/redirect.c
src/src/routers/redirect.h
src/src/search.c
src/src/smtp_in.c
src/src/spool_in.c
src/src/spool_out.c
src/src/srs.c
src/src/srs.h
src/src/structs.h
src/src/tls-gnu.c
src/src/tls-openssl.c
src/src/transport.c
src/src/transports/appendfile.c
src/src/transports/smtp.c
src/src/transports/smtp.h
src/src/verify.c
test/confs/0588 [new file with mode: 0644]
test/confs/0589 [new file with mode: 0644]
test/log/0588 [new file with mode: 0644]
test/log/0589 [new file with mode: 0644]
test/rejectlog/0589 [new file with mode: 0644]
test/runtest
test/scripts/0000-Basic/0588 [new file with mode: 0644]
test/scripts/0000-Basic/0589 [new file with mode: 0644]
test/scripts/2500-dsearch/2500
test/scripts/4620-SRS/REQUIRES
test/scripts/5890-Resume-GnuTLS/REQUIRES
test/scripts/5891-Resume-OpenSSL/REQUIRES
test/stderr/0002
test/stderr/0085
test/stderr/0123
test/stderr/0387
test/stderr/0398
test/stderr/0403
test/stderr/0414
test/stderr/0432
test/stderr/0437
test/stderr/0464
test/stderr/0471
test/stderr/0484
test/stderr/2200
test/stderr/2201
test/stderr/2202
test/stderr/2600
test/stderr/2610
test/stderr/2620
test/stderr/3201
test/stderr/3212
test/stdout/0572
test/stdout/0588 [new file with mode: 0644]
test/stdout/0589 [new file with mode: 0644]
test/stdout/2500

index b154743c2c768ec2a37fde97040e96f7846a68d1..28c8b14626e0a59ee0297c98a58b17160788ffe5 100644 (file)
@@ -3902,6 +3902,13 @@ together with the file descriptor number of an open pipe. Closure of the pipe
 signals the final completion of the sequence of processes that are passing
 messages through the same SMTP connection.
 
+.new
+.vitem &%-MCq%&&~<&'recipient&~address'&>&~<&'size'&>
+.oindex "&%-MCq%&"
+This option is not intended for use by external callers. It is used internally
+by Exim to implement quota checking for local users.
+.wen
+
 .vitem &%-MCS%&
 .oindex "&%-MCS%&"
 This option is not intended for use by external callers. It is used internally
@@ -4512,12 +4519,17 @@ appear in the correct order. Each flag is described in a separate item below.
 .cindex "queue" "routing"
 .cindex "routing" "whole queue before delivery"
 .cindex "first pass routing"
+.cindex "queue runner" "two phase"
 An option starting with &%-qq%& requests a two-stage queue run. In the first
 stage, the queue is scanned as if the &%queue_smtp_domains%& option matched
 every domain. Addresses are routed, local deliveries happen, but no remote
 transports are run.
 
 Performance will be best if the &%queue_run_in_order%& option is false.
+If that is so and the &%queue_fast_ramp%& option is true then
+in the first phase of the run,
+once a threshold number of messages are routed for a given host,
+a delivery process is forked in parallel with the rest of the scan.
 
 .cindex "hints database" "remembering routing"
 The hints database that remembers which messages are waiting for specific hosts
@@ -6653,11 +6665,18 @@ If the value of &$sender_host_address$& is 192.168.5.6, expansion of the
 first &%domains%& setting above generates the second setting, which therefore
 causes a second lookup to occur.
 
+.new
 The lookup type may optionally be followed by a comma
 and a comma-separated list of options.
 Each option is a &"name=value"& pair.
 Whether an option is meaningful depands on the lookup type.
 
+All lookups support the option &"cache=no_rd"&.
+If this is given then the cache that Exim manages for lookup results
+is not checked before diong the lookup.
+The result of the lookup is still written to the cache.
+.wen
+
 The rest of this chapter describes the different lookup types that are
 available. Any of them can be used in any part of the configuration where a
 lookup is permitted.
@@ -6681,6 +6700,7 @@ If this is given and the lookup
 (either underlying implementation or cached value)
 returns data, the result is replaced with a non-tainted
 version of the lookup key.
+.cindex "tainted data" "de-tainting"
 .next
 .cindex "query-style lookup" "definition of"
 The &'query-style'& type accepts a generalized database query. No particular
@@ -6854,6 +6874,29 @@ The final resulting element can be a simple JSON type or a JSON object
 or array; for the latter two a string-representation of the JSON
 is returned.
 For elements of type string, the returned value is de-quoted.
+
+
+.new
+.next
+.cindex LMDB
+.cindex lookup lmdb
+.cindex database lmdb
+&(lmdb)&: The given file is an LMDB database.
+LMDB is a memory-mapped key-value store,
+with API modeled loosely on that of BerkeleyDB.
+See &url(https://symas.com/products/lightning-memory-mapped-database/)
+for the feature set and operation modes.
+
+Exim provides read-only access via the LMDB C library.
+The library can be obtained from &url(https://github.com/LMDB/lmdb)
+or your operating system package repository.
+To enable LMDB support in Exim set LOOKUP_LMDB=yes in &_Local/Makefile_&.
+
+You will need to separately create the LMDB database file,
+possibly using the &"mdb_load"& utility.
+.wen
+
+
 .next
 .cindex "linear search"
 .cindex "lookup" "lsearch"
@@ -10564,6 +10607,14 @@ ${sort {${lookup dnsdb{>:,,mx=example.com}}} {<} {${listextract{1}{<,$item}}}}
 will sort an MX lookup into priority order.
 
 
+
+.new
+.vitem &*${srs_encode&~{*&<&'secret'&>&*}{*&<&'return&~path'&>&*}{*&<&'original&~domain'&>&*}}*&
+SRS encoding.  See SECT &<<SECTSRS>>& for details.
+.wen
+
+
+
 .vitem &*${substr{*&<&'string1'&>&*}{*&<&'string2'&>&*}{*&<&'string3'&>&*}}*&
 .cindex "&%substr%& expansion item"
 .cindex "substring extraction"
@@ -11626,6 +11677,13 @@ includes the case of letters, whereas for &%gti%& the comparison is
 case-independent.
 Case and collation order are defined per the system C locale.
 
+
+.new
+.vitem &*inbound_srs&~{*&<&'local&~part'&>&*}{*&<&'secret'&>&*}*&
+SRS decode.  See SECT &<<SECTSRS>>& for details.
+.wen
+
+
 .vitem &*inlist&~{*&<&'string1'&>&*}{*&<&'string2'&>&*}*& &&&
        &*inlisti&~{*&<&'string1'&>&*}{*&<&'string2'&>&*}*&
 .cindex "string" "comparison"
@@ -13708,6 +13766,17 @@ the value of the Distinguished Name of the certificate is made available in the
 If certificate verification fails it may refer to a failing chain element
 which is not the leaf.
 
+
+.new
+.vitem &$tls_in_resumption$& &&&
+       &$tls_out_resumption$&
+.vindex &$tls_in_resumption$&
+.vindex &$tls_out_resumption$&
+.cindex TLS resumption
+Observability for TLS session resumption.  See &<<SECTresumption>>& for details.
+.wen
+
+
 .vitem &$tls_in_sni$&
 .vindex "&$tls_in_sni$&"
 .vindex "&$tls_sni$&"
@@ -14712,6 +14781,7 @@ See also the &'Policy controls'& section above.
 .row &%hold_domains%&                "hold delivery for these domains"
 .row &%local_interfaces%&            "for routing checks"
 .row &%queue_domains%&               "no immediate delivery for these"
+.row &%queue_fast_ramp%&             "parallel delivery with 2-phase queue run"
 .row &%queue_only%&                  "no immediate delivery at all"
 .row &%queue_only_file%&             "no immediate delivery if file exists"
 .row &%queue_only_load%&             "no immediate delivery if load is high"
@@ -16884,6 +16954,17 @@ domains that do not match are processed. All other deliveries wait until the
 next queue run. See also &%hold_domains%& and &%queue_smtp_domains%&.
 
 
+.new
+.option queue_fast_ramp main boolean false
+.cindex "queue runner" "two phase"
+.cindex "queue" "double scanning"
+If set to true, two-phase queue runs, initiated using &%-qq%& on the
+command line, may start parallel delivery processes during their first
+phase.  This will be done when a threshold number of messages have been
+routed for a single host.
+.wen
+
+
 .option queue_list_requires_admin main boolean true
 .cindex "restricting access to features"
 .oindex "&%-bp%&"
@@ -18254,6 +18335,14 @@ preference order of the available ciphers. Details are given in sections
 &<<SECTreqciphssl>>& and &<<SECTreqciphgnu>>&.
 
 
+.new
+.option tls_resumption_hosts main "host list&!!" unset
+.cindex TLS resumption
+This option controls which connections to offer the TLS resumption feature.
+See &<<SECTresumption>>& for details.
+.wen
+
+
 .option tls_try_verify_hosts main "host list&!!" unset
 .cindex "TLS" "client certificate verification"
 .cindex "certificate" "verification of client"
@@ -25375,6 +25464,20 @@ so can cause parallel connections to the same host if &%remote_max_parallel%&
 permits this.
 
 
+.new
+.option message_linelength_limit smtp integer 998
+.cindex "line length" limit
+This option sets the maximum line length, in bytes, that the transport
+will send.  Any messages with lines exceeding the given value
+will fail and a failure-DSN ("bounce") message will if possible be returned
+to the sender.
+The default value is that defined by the SMTP standards.
+
+It is generally wise to also check in the data ACL so that messages
+received via SMTP can be refused without producing a bounce.
+.wen
+
+
 .option multi_domain smtp boolean&!! true
 .vindex "&$domain$&"
 When this option is set, the &(smtp)& transport can handle a number of
@@ -25556,6 +25659,14 @@ is used in different ways by OpenSSL and GnuTLS (see sections
 ciphers is a preference order.
 
 
+.new
+.option tls_resumption_hosts smtp "host list&!!" unset
+.cindex TLS resumption
+This option controls which connections to use the TLS resumption feature.
+See &<<SECTresumption>>& for details.
+.wen
+
+
 
 .option tls_sni smtp string&!! unset
 .cindex "TLS" "Server Name Indication"
@@ -29372,6 +29483,100 @@ Open-source PKI book, available online at
 .ecindex IIDencsmtp2
 
 
+.new
+.section "TLS Resumption" "SECTresumption"
+.cindex TLS resumption
+TLS Session Resumption for TLS 1.2 and TLS 1.3 connections can be used (defined
+in RFC 5077 for 1.2).  The support for this requires GnuTLS 3.6.3 or OpenSSL 1.1.1
+(or later).
+
+Session resumption (this is the "stateless" variant) involves the server sending
+a "session ticket" to the client on one connection, which can be stored by the
+client and used for a later session.  The ticket contains sufficient state for
+the server to reconstruct the TLS session, avoiding some expensive crypto
+calculation and (on TLS1.2) one full packet roundtrip time.
+
+.ilist
+Operational cost/benefit:
+
+ The extra data being transmitted costs a minor amount, and the client has
+ extra costs in storing and retrieving the data.
+
+ In the Exim/Gnutls implementation the extra cost on an initial connection
+ which is TLS1.2 over a loopback path is about 6ms on 2017-laptop class hardware.
+ The saved cost on a subsequent connection is about 4ms; three or more
+ connections become a net win.  On longer network paths, two or more
+ connections will have an average lower startup time thanks to the one
+ saved packet roundtrip.  TLS1.3 will save the crypto cpu costs but not any
+ packet roundtrips.
+
+.cindex "hints database" tls
+ Since a new hints DB is used on the TLS client,
+ the hints DB maintenance should be updated to additionally handle "tls".
+
+.next
+Security aspects:
+
+ The session ticket is encrypted, but is obviously an additional security
+ vulnarability surface.  An attacker able to decrypt it would have access
+ all connections using the resumed session.
+ The session ticket encryption key is not committed to storage by the server
+ and is rotated regularly (OpenSSL: 1hr, and one previous key is used for
+ overlap; GnuTLS 6hr but does not specify any overlap).
+ Tickets have limited lifetime (2hr, and new ones issued after 1hr under
+ OpenSSL.  GnuTLS 2hr, appears to not do overlap).
+
+ There is a question-mark over the security of the Diffie-Helman parameters
+ used for session negotiation.
+
+.next
+Observability:
+
+ The &%log_selector%& "tls_resumption" appends an asterisk to the tls_cipher "X="
+ element.
+
+ The variables &$tls_in_resumption$& and &$tls_out_resumption$&
+ have bits 0-4 indicating respectively
+ support built, client requested ticket, client offered session,
+ server issued ticket, resume used.  A suitable decode list is provided
+ in the builtin macro _RESUME_DECODE for in &%listextract%& expansions.
+
+.next
+Control:
+
+The &%tls_resumption_hosts%& main option specifies a hostlist for which
+exim, operating as a server, will offer resumption to clients.
+Current best practice is to not offer the feature to MUA connection.
+Commonly this can be done like this:
+.code
+tls_resumption_hosts = ${if inlist {$received_port}{587:465} {:}{*}}
+.endd
+If the peer host matches the list after expansion then resumption
+is offered and/or accepted.
+
+The &%tls_resumption_hosts%& smtp transport option performs the
+equivalent function for operation as a client.
+If the peer host matches the list after expansion then resumption
+is attempted (if a stored session is available) or the information
+stored (if supplied by the peer).
+
+
+.next
+Issues:
+
+ In a resumed session:
+.ilist
+  The variables &$tls_{in,out}_cipher$& will have values different
+ to the original (under GnuTLS).
+.next
+  The variables &$tls_{in,out}_ocsp$& will be "not requested" or "no response",
+ and the &%hosts_require_ocsp%& smtp trasnport option will fail.
+. XXX need to do something with that hosts_require_ocsp
+.endlist
+
+.endlist
+.wen
+
 
 .section DANE "SECDANE"
 .cindex DANE
@@ -32492,6 +32697,15 @@ The &%success_on_redirect%& option causes verification always to succeed
 immediately after a successful redirection. By default, if a redirection
 generates just one address, that address is also verified. See further
 discussion in section &<<SECTredirwhilveri>>&.
+.new
+.next
+If the &%quota%& option is specified for recipient verify,
+successful routing to an appendfile transport is followed by a call into
+the transport to evaluate the quota status for the recipient.
+No actual delivery is done, but verification will succeed if the quota
+is sufficient for the message (if the sender gave a message size) or
+not already exceeded (otherwise).
+.wen
 .endlist
 
 .cindex "verifying address" "differentiating failures"
@@ -32525,6 +32739,9 @@ connection, HELO, or MAIL).
 &%recipient%&: The RCPT command in a callout was rejected.
 .next
 &%postmaster%&: The postmaster check in a callout was rejected.
+.new
+.next
+&%quota%&: The quota check for a local recipient did non pass.
 .endlist
 
 The main use of these variables is expected to be to distinguish between
@@ -32854,6 +33071,38 @@ behaviour will be the same.
 
 
 
+.new
+.section "Quota caching" "SECTquotacache"
+.cindex "hints database" "quota cache"
+.cindex "quota" "cache, description of"
+.cindex "caching" "quota"
+Exim caches the results of quota verification
+in order to reduce the amount of resources used.
+The &"callout"& hints database is used.
+
+The default cache periods are five minutes for a positive (good) result
+and one hour for a negative result.
+To change the periods the &%quota%& option can be followed by an equals sign
+and a number of optional paramemters, separated by commas.
+For example:
+.code
+verify = recipient/quota=cachepos=1h,cacheneg=1d
+.endd
+Possible parameters are:
+.vlist
+.vitem &*cachepos&~=&~*&<&'time&~interval'&>
+.cindex "quota cache" "positive entry expiry, specifying"
+Set the lifetime for a positive cache entry.
+A value of zero seconds is legitimate.
+
+.vitem &*cacheneg&~=&~*&<&'time&~interval'&>
+.cindex "quota cache" "negative entry expiry, specifying"
+As above, for a negative entry.
+
+.vitem &*no_cache*&
+Set both positive and negative lifetimes to zero.
+.wen
+
 .section "Sender address verification reporting" "SECTsenaddver"
 .cindex "verifying" "suppressing error details"
 See section &<<SECTaddressverification>>& for a general discussion of
@@ -37983,6 +38232,7 @@ selection marked by asterisks:
 &`*tls_certificate_verified   `&  certificate verification status
 &`*tls_cipher                 `&  TLS cipher suite on <= and => lines
 &` tls_peerdn                 `&  TLS peer DN on <= and => lines
+&` tls_resumption             `&  append * to cipher field
 &` tls_sni                    `&  TLS SNI on <= lines
 &` unknown_in_list            `&  DNS lookup failed in list match
 
@@ -38384,6 +38634,14 @@ connection, the cipher suite used is added to the log line, preceded by X=.
 connection, and a certificate is supplied by the remote host, the peer DN is
 added to the log line, preceded by DN=.
 .next
+.cindex "log" "TLS resumption"
+.cindex "TLS" "logging session resumption"
+.new
+&%tls_resumption%&: When a message is sent or received over an encrypted
+connection and the TLS session resumed one used on a previous TCP connection,
+an asterisk is appended to the X= cipher field in the log line.
+.wen
+.next
 .cindex "log" "TLS SNI"
 .cindex "TLS" "logging SNI"
 &%tls_sni%&: When a message is received over an encrypted connection, and
@@ -38929,6 +39187,10 @@ for remote hosts
 .next
 &'ratelimit'&: the data for implementing the ratelimit ACL condition
 .next
+.new
+&'tls'&: TLS session resumption data
+.wen
+.next
 &'misc'&: other hints data
 .endlist
 
@@ -40342,8 +40604,8 @@ There is no dot-stuffing (and no dot-termination).
 . ////////////////////////////////////////////////////////////////////////////
 . ////////////////////////////////////////////////////////////////////////////
 
-.chapter "DKIM, SPF and DMARC" "CHAPdkim" &&&
-         "DKIM, SPF and DMARC Support"
+.chapter "DKIM, SPF, SRS and DMARC" "CHAPdkim" &&&
+         "DKIM, SPF, SRS and DMARC Support"
 
 .section "DKIM (DomainKeys Identified Mail)" SECDKIM
 .cindex "DKIM"
@@ -41035,6 +41297,108 @@ The lookup will return the same result strings as can appear in
 
 
 
+.section "SRS (Sender Rewriting Scheme)" SECTSRS
+.cindex SRS "sender rewriting scheme"
+
+.new
+SRS can be used to modify sender addresses when forwarding so that
+SPF verification does not object to them.
+It operates by encoding the original envelope sender in a new
+sender local part and using a domain run by the forwarding site
+as the new domain for the sender.  Any DSN message should be returned
+to this new sender at the forwarding site, which can extract the
+original sender from the coded local part and forward the DSN to
+the originator.
+
+This is a way of avoiding the breakage that SPF does to forwarding.
+The constructed local-part will be longer than the original,
+leading to possible problems with very long addresses.
+The changing of the sender address also hinders the tracing of mail
+problems.
+
+Exim can be built to include native SRS support.  To do this
+SUPPORT_SRS=yes must be defined in &_Local/Makefile_&.
+If this has been done, the macros _HAVE_SRS and _HAVE_NATIVE_SRS
+will be defined.
+The support is limited to SRS0-encoding; SRS1 is not supported.
+
+.cindex SRS excoding
+To encode an address use this expansion item:
+.vlist
+.vitem &*${srs_encode&~{*&<&'secret'&>&*}{*&<&'return&~path'&>&*}{*&<&'original&~domain'&>&*}}*&
+.cindex "&%srs_encode%& expansion item"
+.cindex SRS "expansion item"
+The first argument should be a secret known and used by all systems
+handling the recipient domain for the original message.
+There is no need to periodically change this key; a timestamp is also
+encoded.
+The second argument should be given as the envelope sender address before this
+encoding operation.
+The third argument should be the recipient domain of the message when
+it arrived at this system.
+.endlist
+
+.cindex SRS decoding
+To decode an address use this expansion condition:
+.vlist
+.vitem &*inbound_srs&~{*&<&'local&~part'&>&*}{*&<&'secret'&>&*}*&
+The first argument should be the recipient local prt as is was received.
+The second argument is the site secret.
+
+If the messages is not for an SRS-encoded recipient the condition will
+return false.  If it is, the condition will return true and the variable
+&$srs_recipient$& will be set to the decoded (original) value.
+.endlist
+
+Example usage:
+.code
+  #macro
+  SRS_SECRET = <pick something unique for your site for this. Use on all MXs.>
+  
+  #routers
+
+  outbound:
+    driver =    dnslookup
+    # if outbound, and forwarding has been done, use an alternate transport
+    domains =   ! +my_domains
+    transport = ${if eq {$local_part@$domain} \
+                        {$original_local_part@$original_domain} \
+                     {remote_smtp} {remote_forwarded_smtp}}
+  
+  inbound_srs:
+    driver =    redirect
+    senders =   :
+    domains =   +my_domains
+    # detect inbound bounces which are SRS'd, and decode them
+    condition = ${if inbound_srs {$local_part} {SRS_SECRET}}
+    data =      $srs_recipient
+  
+  inbound_srs_failure:
+    driver =    redirect
+    senders =   :
+    domains =   +my_domains
+    # detect inbound bounces which look SRS'd but are invalid
+    condition = ${if inbound_srs {$local_part} {}}
+    allow_fail
+    data =      :fail: Invalid SRS recipient address
+
+  #... further routers here
+
+  
+  # transport; should look like the non-forward outbound
+  # one, plus the max_rcpt and return_path options
+  remote_forwarded_smtp:
+    driver =              smtp
+    # modify the envelope from, for mails that we forward
+    max_rcpt =            1
+    return_path =         ${srs_encode {SRS_SECRET} {$return_path} {$original_domain}}
+.endd
+
+
+.wen
+
+
+
 .section DMARC SECDMARC
 .cindex DMARC verification
 
index 585deb04241b5dfbf16458285e3fed49ed8d896a..a4526ca5cc1b55768100285da6f1476b094620b1 100644 (file)
@@ -3,6 +3,14 @@ affect Exim's operation, with an unchanged configuration file.  For new
 options, and new features, see the NewStuff file next to this ChangeLog.
 
 
+Exim version 4.95
+-----------------
+
+JH/01 Bug 1329: Fix format of Maildir-format filenames to match other mail-
+      related applications.  Previously an "H" was used where available info
+      says that "M" should be, so change to match.
+
+
 Exim version 4.94
 -----------------
 
index 43e170e116fab87a381cf8ba78ac3d78b5d4d386..5769a9733f264d024a19409dc7e0624620d1f0fb 100644 (file)
@@ -6,6 +6,30 @@ Before a formal release, there may be quite a lot of detail so that people can
 test from the snapshots or the Git before the documentation is updated. Once
 the documentation is updated, this file is reduced to a short list.
 
+Version 4.95
+------------
+
+ 1. The fast-ramp two phase queue run support, previously experimental, is
+    now supported by default.
+
+ 2. The native SRS support, previously experimental, is now supported. It is
+    not built unless specified in the Local/Makefile.
+
+ 3. TLS resumption support, previously experimental, is now supported and
+    included in default builds.
+
+ 4. Single-key LMDB lookups, previously experimental, are now supported.
+    The support is not built unless specified in the Local/Makefile.
+
+ 5. Option "message_linelength_limit" on the smtp transport to enforce (by
+    default) the RFC 998 character limit.
+
+ 6. An option to ignore the cache on a lookup.
+
+ 7. Quota checking during reception (i.e. at SMTP time) for appendfile-
+    transport-managed quotas.
+
+
 Version 4.94
 ------------
 
index 8b2dee352806369f46e9cc711e38abaa38a62883..183f6b7220e3c0e12ab6e328709972bc26bb3408 100644 (file)
@@ -382,6 +382,7 @@ message_body_newlines                boolean         false         main
 message_body_visible                 integer         500           main
 message_id_header_domain             string*         unset         main              4.11
 message_id_header_text               string*         unset         main
+message_linelength_limit             integer         998           smtp              4.94
 message_logs                         boolean         true          main              4.10
 message_prefix                       string*         +             appendfile        4.00 replaces prefix
                                      string*         unset         pipe              4.00 replaces prefix
@@ -443,6 +444,7 @@ qualify_recipient                    string          +             main
 qualify_single                       boolean         true          dnslookup         4.00
 query                                string*         +             iplookup          4.00
 queue_domains                        domain list     unset         main              4.00
+queue_fasst_ramp                     boolean         false         main              4.95
 queue_list_requires_admin            boolean         true          main              1.95
 queue_only                           boolean         false         main
 queue_only_file                      string          unset         main              2.05
@@ -606,6 +608,8 @@ tls_privatekey                       string*         unset         main
 tls_remember_emstp                   boolean         false         main              4.21
 tls_require_ciphers                  string*         unset         smtp              4.00 replaces tls_verify_ciphers
                                      string*         unset         main              4.33
+tls_resumption_hosts                 host list*      unset         main              4.95
+                                     host list*      unset         smtp              4.95
 tls_sni                              string*         unset         main              4.80
 tls_tempfail_tryclear                boolean         true          smtp              4.05
 tls_try_verify_hosts                 host list       unset         main              4.00
index 3beab4b9c9e86d5192a0f3c995e03272d23c68a6..68366a4a944bcf5f15d7f241b6b51a45af8b4ddf 100644 (file)
@@ -294,9 +294,9 @@ These four steps are explained in more details below.
 
 SRS (Sender Rewriting Scheme) Support (using libsrs_alt)
 --------------------------------------------------------------
-See also below, for an alternative native support implementation.
+See also the main docs, for an alternative native support implementation.
 
-Exim  currently  includes SRS  support  via Miles  Wilton's
+Exim can be built with SRS support using Miles  Wilton's
 libsrs_alt library. The current version of the supported
 library is 0.5, there are reports of 1.0 working.
 
@@ -309,10 +309,14 @@ https://opsec.eu/src/srs/
 Unpack the tarball, then refer to MTAs/README.EXIM
 to proceed. You need to set
 
-EXPERIMENTAL_SRS=yes
+EXPERIMENTAL_SRS_ALT=yes
 
 in your Local/Makefile.
 
+The built-in support, included by SUPPORT_SRS,
+shuold *not* be enabled if you wish to use the libsrs_alt
+version.
+
 The following main-section options become available:
        srs_config              string
        srs_hashlength          int
@@ -344,76 +348,6 @@ For configuration information see https://github.com/Exim/exim/wiki/SRS .
 
 
 
-SRS (Sender Rewriting Scheme) Support (native)
---------------------------------------------------------------
-This is less full-featured than the libsrs_alt version above.
-
-The Exim build needs to be done with this in Local/Makefile:
-EXPERIMENTAL_SRS_NATIVE=yes
-
-The following are provided:
-- an expansion item "srs_encode"
-  This takes three arguments:
-  - a site SRS secret
-  - the return_path
-  - the pre-forwarding domain
-
-- an expansion condition "inbound_srs"
-  This takes two arguments: the local_part to check, and a site SRS secret.
-  If the secret is zero-length, only the pattern of the local_part is checked.
-  The $srs_recipient variable is set as a side-effect.
-
-- an expansion variable $srs_recipient
-  This gets the original return_path encoded in the SRS'd local_part
-
-- predefined macros _HAVE_SRS and _HAVE_NATIVE_SRS
-
-Sample usage:
-
-  #macro
-  SRS_SECRET = <pick something unique for your site for this>
-  
-  #routers
-
-  outbound:
-    driver =    dnslookup
-    # if outbound, and forwarding has been done, use an alternate transport
-    domains =   ! +my_domains
-    transport = ${if eq {$local_part@$domain} \
-                        {$original_local_part@$original_domain} \
-                     {remote_smtp} {remote_forwarded_smtp}}
-  
-  inbound_srs:
-    driver =    redirect
-    senders =   :
-    domains =   +my_domains
-    # detect inbound bounces which are SRS'd, and decode them
-    condition = ${if inbound_srs {$local_part} {SRS_SECRET}}
-    data =      $srs_recipient
-  
-  inbound_srs_failure:
-    driver =    redirect
-    senders =   :
-    domains =   +my_domains
-    # detect inbound bounces which look SRS'd but are invalid
-    condition = ${if inbound_srs {$local_part} {}}
-    allow_fail
-    data =      :fail: Invalid SRS recipient address
-
-  #... further routers here
-
-  
-  # transport; should look like the non-forward outbound
-  # one, plus the max_rcpt and return_path options
-  remote_forwarded_smtp:
-    driver =              smtp
-    # modify the envelope from, for mails that we forward
-    max_rcpt =            1
-    return_path =         ${srs_encode {SRS_SECRET} {$return_path} {$original_domain}}
-
-
-
-
 DCC Support
 --------------------------------------------------------------
 Distributed Checksum Clearinghouse; http://www.rhyolite.com/dcc/
@@ -532,52 +466,6 @@ Rationale:
 Note that non-RFC-documented field names and data types are used.
 
 
-LMDB Lookup support
--------------------
-LMDB is an ultra-fast, ultra-compact, crash-proof key-value embedded data store.
-It is modeled loosely on the BerkeleyDB API. You should read about the feature
-set as well as operation modes at https://symas.com/products/lightning-memory-mapped-database/
-
-LMDB single key lookup support is provided by linking to the LMDB C library.
-The current implementation does not support writing to the LMDB database.
-
-Visit https://github.com/LMDB/lmdb to download the library or find it in your
-operating systems package repository.
-
-If building from source, this description assumes that headers will be in
-/usr/local/include, and that the libraries are in /usr/local/lib.
-
-1. In order to build exim with LMDB lookup support add or uncomment
-
-EXPERIMENTAL_LMDB=yes
-
-to your Local/Makefile. (Re-)build/install exim. exim -d should show
-Experimental_LMDB in the line "Support for:".
-
-EXPERIMENTAL_LMDB=yes
-LDFLAGS += -llmdb
-# CFLAGS += -I/usr/local/include
-# LDFLAGS += -L/usr/local/lib
-
-The first line sets the feature to include the correct code, and
-the second line says to link the LMDB libraries into the
-exim binary.  The commented out lines should be uncommented if you
-built LMDB from source and installed in the default location.
-Adjust the paths if you installed them elsewhere, but you do not
-need to uncomment them if an rpm (or you) installed them in the
-package controlled locations (/usr/include and /usr/lib).
-
-2. Create your LMDB files, you can use the mdb_load utility which is
-part of the LMDB distribution our your favourite language bindings.
-
-3. Add the single key lookups to your exim.conf file, example lookups
-are below.
-
-${lookup{$sender_address_domain}lmdb{/var/lib/baruwa/data/db/relaydomains.mdb}{$value}}
-${lookup{$sender_address_domain}lmdb{/var/lib/baruwa/data/db/relaydomains.mdb}{$value}fail}
-${lookup{$sender_address_domain}lmdb{/var/lib/baruwa/data/db/relaydomains.mdb}}
-
-
 Queuefile transport
 -------------------
 Queuefile is a pseudo transport which does not perform final delivery.
@@ -750,67 +638,8 @@ used via the transport in question.
 
 
 
-
-TLS Session Resumption
-----------------------
-TLS Session Resumption for TLS 1.2 and TLS 1.3 connections can be used (defined
-in RFC 5077 for 1.2).  The support for this can be included by building with
-EXPERIMENTAL_TLS_RESUME defined.  This requires GnuTLS 3.6.3 or OpenSSL 1.1.1
-(or later).
-
-Session resumption (this is the "stateless" variant) involves the server sending
-a "session ticket" to the client on one connection, which can be stored by the
-client and used for a later session.  The ticket contains sufficient state for
-the server to reconstruct the TLS session, avoiding some expensive crypto
-calculation and one full packet roundtrip time.
-
-Operational cost/benefit:
- The extra data being transmitted costs a minor amount, and the client has
- extra costs in storing and retrieving the data.
-
- In the Exim/Gnutls implementation the extra cost on an initial connection
- which is TLS1.2 over a loopback path is about 6ms on 2017-laptop class hardware.
- The saved cost on a subsequent connection is about 4ms; three or more
- connections become a net win.  On longer network paths, two or more
- connections will have an average lower startup time thanks to the one
- saved packet roundtrip.  TLS1.3 will save the crypto cpu costs but not any
- packet roundtrips.
-
- Since a new hints DB is used, the hints DB maintenance should be updated
- to additionally handle "tls".
-
-Security aspects:
- The session ticket is encrypted, but is obviously an additional security
- vulnarability surface.  An attacker able to decrypt it would have access
- all connections using the resumed session.
- The session ticket encryption key is not committed to storage by the server
- and is rotated regularly (OpenSSL: 1hr, and one previous key is used for
- overlap; GnuTLS 6hr but does not specify any overlap).
- Tickets have limited lifetime (2hr, and new ones issued after 1hr under
- OpenSSL.  GnuTLS 2hr, appears to not do overlap).
-
- There is a question-mark over the security of the Diffie-Helman parameters
- used for session negotiation. TBD.  q-value; cf bug 1895
-
-Observability:
- New log_selector "tls_resumption", appends an asterisk to the tls_cipher "X="
- element.
-
- Variables $tls_{in,out}_resumption have bits 0-4 indicating respectively
- support built, client requested ticket, client offered session,
- server issued ticket, resume used.  A suitable decode list is provided
- in the builtin macro _RESUME_DECODE for ${listextract {}{}}.
-
-Issues:
- In a resumed session:
-  $tls_{in,out}_cipher will have values different to the original (under GnuTLS)
-  $tls_{in,out}_ocsp will be "not requested" or "no response", and
-   hosts_require_ocsp will fail
-
-
-
 Dovecot authenticator via inet socket
-------------------------------------
+--------------------------------------------------------------
 If Dovecot is configured similar to :-
 
 service auth {
@@ -837,30 +666,6 @@ and a whitespace-separated port number must be given.
 
 
 
-Twophase queue run fast ramp
-----------------------------
-To include this feature, add to Local/Makefile:
-  EXPERIMENTAL_QUEUE_RAMP=yes
-
-If the (added for this feature) main-section option "queue_fast_ramp" (boolean)
-is set, and a two-phase ("-qq") queue run finds, during the first phase, a
-suitably large number of message routed for a given host - then (subject to
-the usual queue-runner resource limits) delivery for that host is initiated
-immediately, overlapping with the remainder of the first phase.
-
-This is incompatible with queue_run_in_order.
-
-The result should be a faster startup of deliveries when a large queue is
-present and reasonable numbers of messages are routed to common hosts; this
-could be a smarthost case, or delivery onto the Internet where a large proportion
-of recipients hapen to be on a Gorilla-sized provider.
-
-As usual, the presence of a configuration option is associated with a
-predefined macro, making it possible to write portable configurations.
-For this one, the macro is _OPT_MAIN_QUEUE_FAST_RAMP.
-
-
-
 --------------------------------------------------------------
 End of file
 --------------------------------------------------------------
index be0d9520bef0dfa2c438ef752b910f514d15f66d..517bbc4938b4038fec729c2f523605bfe53e2795 100644 (file)
@@ -10,8 +10,12 @@ HAVE_SA_LEN=YES
 
 # Removed -DBIND_8_COMPAT for 4.61
 # CFLAGS=-O -no-cpp-precomp -DBIND_8_COMPAT
+#
+# 2020/05/12 disable TLS resume support; it results in
+# "1 select() failure: No such file or directory"
+# being logged by the daeomn (sending the testsuite red...)
 
-CFLAGS=-O -no-cpp-precomp
+CFLAGS=-O -no-cpp-precomp -DDISABLE_TLS_RESUME
 LIBRESOLV=-lresolv
 
 USE_DB = yes
index e568bdbb1a8cd99b2f0ac7c3b230b14171b2c0d9..13dc494144151e30344423a5c193d801f64ba2e5 100644 (file)
@@ -276,6 +276,9 @@ SPOOL_DIRECTORY=/var/spool/exim
 # specified in INCLUDE.
 
 
+# Uncomment the following line to remove support for TLS Resumption
+# DISABLE_TLS_RESUME=yes
+
 
 ###############################################################################
 #           THESE ARE THINGS YOU PROBABLY WANT TO SPECIFY                     #
@@ -411,6 +414,8 @@ LOOKUP_DNSDB=yes
 # LOOKUP_IBASE=yes
 # LOOKUP_JSON=yes
 # LOOKUP_LDAP=yes
+# LOOKUP_LMDB=yes
+
 # LOOKUP_MYSQL=yes
 # LOOKUP_MYSQL_PC=mariadb
 # LOOKUP_NIS=yes
@@ -487,7 +492,8 @@ SUPPORT_DANE=yes
 # You do not need to use this for any lookup information added via pkg-config.
 
 # LOOKUP_INCLUDE=-I /usr/local/ldap/include -I /usr/local/mysql/include -I /usr/local/pgsql/include
-# LOOKUP_LIBS=-L/usr/local/lib -lldap -llber -lmysqlclient -lpq -lgds -lsqlite3
+# LOOKUP_INCLUDE +=-I /usr/local/include
+# LOOKUP_LIBS=-L/usr/local/lib -lldap -llber -lmysqlclient -lpq -lgds -lsqlite3 -llmdb
 
 
 #------------------------------------------------------------------------------
@@ -560,7 +566,6 @@ DISABLE_MAL_MKS=yes
 # DISABLE_DNSSEC=yes
 
 # To disable support for Events set DISABLE_EVENT to "yes"
-
 # DISABLE_EVENT=yes
 
 
@@ -569,6 +574,14 @@ DISABLE_MAL_MKS=yes
 # SUPPORT_PIPE_CONNECT=yes
 
 
+# Uncomment the following to remove the fast-ramp two-phase-queue-run support
+# DISABLE_QUEUE_RAMP=yes
+
+# Uncomment the following lines to add SRS (Sender Rewriting Scheme) support
+# using only native facilities.  See EXPERIMENTAL_SRS_ALT for an alternative.
+# SUPPORT_SRS=yes
+
+
 #------------------------------------------------------------------------------
 # Compiling Exim with experimental features. These are documented in
 # experimental-spec.txt. "Experimental" means that the way these features are
@@ -580,19 +593,16 @@ DISABLE_MAL_MKS=yes
 
 # EXPERIMENTAL_DCC=yes
 
-# Uncomment the following lines to add SRS (Sender rewriting scheme) support.
+# Uncomment the following lines to add SRS (Sender rewriting scheme) support
+# using the implementation in linbsrs_alt.
 # You need to have libsrs_alt installed on your system (srs.mirtol.com).
 # Depending on where it is installed you may have to edit the CFLAGS and
 # LDFLAGS lines.
 
-# EXPERIMENTAL_SRS=yes
+# EXPERIMENTAL_SRS_ALT=yes
 # CFLAGS  += -I/usr/local/include
 # LDFLAGS += -lsrs_alt
 
-# Uncomment the following lines to add SRS (Sender rewriting scheme) support
-# using only native facilities.
-# EXPERIMENTAL_SRS_NATIVE=yes
-
 # Uncomment the following line to add DMARC checking capability, implemented
 # using libopendmarc libraries. You must have SPF and DKIM support enabled also.
 # SUPPORT_DMARC=yes
@@ -618,22 +628,9 @@ DISABLE_MAL_MKS=yes
 # Uncomment the following to include extra information in fail DSN message (bounces)
 # EXPERIMENTAL_DSN_INFO=yes
 
-# Uncomment the following to add LMDB lookup support
-# You need to have LMDB installed on your system (https://github.com/LMDB/lmdb)
-# Depending on where it is installed you may have to edit the CFLAGS and LDFLAGS lines.
-# EXPERIMENTAL_LMDB=yes
-# CFLAGS += -I/usr/local/include
-# LDFLAGS += -llmdb
-
 # Uncomment the following line to add queuefile transport support
 # EXPERIMENTAL_QUEUEFILE=yes
 
-# Uncomment the following line to include support for TLS Resumption
-# EXPERIMENTAL_TLS_RESUME=yes
-
-# Uncomment the following to include the fast-ramp two-phase-queue-run support
-# EXPERIMENTAL_QUEUE_RAMP=yes
-
 ###############################################################################
 #                 THESE ARE THINGS YOU MIGHT WANT TO SPECIFY                  #
 ###############################################################################
index c1d60bbd965f18798a61797da8fcdc0be37ad49b..57a07296fd26d617991f00db39287d66f947638d 100644 (file)
 
 #define CALLOUT_TIMEOUT_DEFAULT 30
 
+/* Default quota cache TTLs */
+
+#define QUOTA_POS_DEFAULT (5*60)
+#define QUOTA_NEG_DEFAULT (60*60)
+
+
 /* ACL verb codes - keep in step with the table of verbs that follows */
 
 enum { ACL_ACCEPT, ACL_DEFER, ACL_DENY, ACL_DISCARD, ACL_DROP, ACL_REQUIRE,
@@ -1515,7 +1521,7 @@ static verify_type_t verify_type_list[] = {
     { US"not_blind",           VERIFY_NOT_BLIND,       ACL_BIT_DATA | ACL_BIT_NOTSMTP, FALSE, 0 },
     { US"header_sender",       VERIFY_HDR_SNDR,        ACL_BIT_DATA | ACL_BIT_NOTSMTP, FALSE, 0 },
     { US"sender",              VERIFY_SNDR,            ACL_BIT_MAIL | ACL_BIT_RCPT
-                       |ACL_BIT_PREDATA | ACL_BIT_DATA | ACL_BIT_NOTSMTP,
+                       | ACL_BIT_PREDATA | ACL_BIT_DATA | ACL_BIT_NOTSMTP,
                                                                                FALSE, 6 },
     { US"recipient",           VERIFY_RCPT,            ACL_BIT_RCPT,   FALSE, 0 },
     { US"header_names_ascii",  VERIFY_HDR_NAMES_ASCII, ACL_BIT_DATA | ACL_BIT_NOTSMTP, TRUE, 0 },
@@ -1556,6 +1562,20 @@ static callout_opt_t callout_opt_list[] = {
 
 
 
+static int
+v_period(const uschar * s, const uschar * arg, uschar ** log_msgptr)
+{
+int period;
+if ((period = readconf_readtime(s, 0, FALSE)) < 0)
+  {
+  *log_msgptr = string_sprintf("bad time value in ACL condition "
+    "\"verify %s\"", arg);
+  }
+return period;
+}
+
+
+
 /* This function implements the "verify" condition. It is called when
 encountered in any ACL, because some tests are almost always permitted. Some
 just don't make sense, and always fail (for example, an attempt to test a host
@@ -1590,6 +1610,8 @@ BOOL defer_ok = FALSE;
 BOOL callout_defer_ok = FALSE;
 BOOL no_details = FALSE;
 BOOL success_on_redirect = FALSE;
+BOOL quota = FALSE;
+int quota_pos_cache = QUOTA_POS_DEFAULT, quota_neg_cache = QUOTA_NEG_DEFAULT;
 address_item *sender_vaddr = NULL;
 uschar *verify_sender_address = NULL;
 uschar *pm_mailfrom = NULL;
@@ -1746,7 +1768,7 @@ switch(vp->value)
     in place of the actual sender (rare special-case requirement). */
     {
     uschar *s = ss + 6;
-    if (*s == 0)
+    if (!*s)
       verify_sender_address = sender_address;
     else
       {
@@ -1792,19 +1814,16 @@ while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
   else if (strncmpic(ss, US"callout", 7) == 0)
     {
     callout = CALLOUT_TIMEOUT_DEFAULT;
-    ss += 7;
-    if (*ss != 0)
+    if (*(ss += 7))
       {
       while (isspace(*ss)) ss++;
       if (*ss++ == '=')
         {
        const uschar * sublist = ss;
         int optsep = ',';
-        uschar buffer[256];
-       uschar * opt;
 
         while (isspace(*sublist)) sublist++;
-        while ((opt = string_nextinlist(&sublist, &optsep, buffer, sizeof(buffer))))
+        for (uschar * opt; opt = string_nextinlist(&sublist, &optsep, NULL, 0); )
           {
          callout_opt_t * op;
          double period = 1.0F;
@@ -1826,12 +1845,8 @@ while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
               }
             while (isspace(*opt)) opt++;
            }
-         if (op->timeval && (period = readconf_readtime(opt, 0, FALSE)) < 0)
-           {
-           *log_msgptr = string_sprintf("bad time value in ACL condition "
-             "\"verify %s\"", arg);
+         if (op->timeval && (period = v_period(opt, arg, log_msgptr)) < 0)
            return ERROR;
-           }
 
          switch(op->value)
            {
@@ -1864,6 +1879,38 @@ while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
       }
     }
 
+  /* The quota option has sub-options, comma-separated */
+
+  else if (strncmpic(ss, US"quota", 5) == 0)
+    {
+    quota = TRUE;
+    if (*(ss += 5))
+      {
+      while (isspace(*ss)) ss++;
+      if (*ss++ == '=')
+        {
+       const uschar * sublist = ss;
+        int optsep = ',';
+       int period;
+
+        while (isspace(*sublist)) sublist++;
+        for (uschar * opt; opt = string_nextinlist(&sublist, &optsep, NULL, 0); )
+         if (Ustrncmp(opt, "cachepos=", 9) == 0)
+           if ((period = v_period(opt += 9, arg, log_msgptr)) < 0)
+             return ERROR;
+           else
+             quota_pos_cache = period;
+         else if (Ustrncmp(opt, "cacheneg=", 9) == 0)
+           if ((period = v_period(opt += 9, arg, log_msgptr)) < 0)
+             return ERROR;
+           else
+             quota_neg_cache = period;
+         else if (Ustrcmp(opt, "no_cache") == 0)
+           quota_pos_cache = quota_neg_cache = 0;
+       }
+      }
+    }
+
   /* Option not recognized */
 
   else
@@ -1882,6 +1929,31 @@ if ((verify_options & (vopt_callout_recipsender|vopt_callout_recippmaster)) ==
   return ERROR;
   }
 
+/* Handle quota verification */
+if (quota)
+  {
+  if (vp->value != VERIFY_RCPT)
+    {
+    *log_msgptr = US"can only verify quota of recipient";
+    return ERROR;
+    }
+
+  if ((rc = verify_quota_call(addr->address,
+             quota_pos_cache, quota_neg_cache, log_msgptr)) != OK)
+    {
+    *basic_errno = errno;
+    if (smtp_return_error_details)
+      {
+      if (!*user_msgptr && *log_msgptr)
+        *user_msgptr = string_sprintf("Rejected after %s: %s",
+           smtp_names[smtp_connection_had[smtp_ch_index-1]], *log_msgptr);
+      if (rc == DEFER) f.acl_temp_details = TRUE;
+      }
+    }
+
+  return rc;
+  }
+
 /* Handle sender-in-header verification. Default the user message to the log
 message if giving out verification details. */
 
@@ -1928,8 +2000,8 @@ else if (verify_sender_address)
     }
 
   sender_vaddr = verify_checked_sender(verify_sender_address);
-  if (sender_vaddr != NULL &&               /* Previously checked */
-      callout <= 0)                         /* No callout needed this time */
+  if (   sender_vaddr                          /* Previously checked */
+      && callout <= 0)                         /* No callout needed this time */
     {
     /* If the "routed" flag is set, it means that routing worked before, so
     this check can give OK (the saved return code value, if set, belongs to a
@@ -1996,14 +2068,12 @@ else if (verify_sender_address)
         *basic_errno = sender_vaddr->basic_errno;
       else
        DEBUG(D_acl)
-         {
          if (Ustrcmp(sender_vaddr->address, verify_sender_address) != 0)
            debug_printf_indent("sender %s verified ok as %s\n",
              verify_sender_address, sender_vaddr->address);
          else
            debug_printf_indent("sender %s verified ok\n",
              verify_sender_address);
-         }
       }
     else
       rc = OK;  /* Null sender */
@@ -2047,8 +2117,7 @@ else
 
   *basic_errno = addr2.basic_errno;
   *log_msgptr = addr2.message;
-  *user_msgptr = (addr2.user_message != NULL)?
-    addr2.user_message : addr2.message;
+  *user_msgptr = addr2.user_message ? addr2.user_message : addr2.message;
 
   /* Allow details for temporary error if the address is so flagged. */
   if (testflag((&addr2), af_pass_message)) f.acl_temp_details = TRUE;
@@ -2059,8 +2128,10 @@ else
 
 /* We have a result from the relevant test. Handle defer overrides first. */
 
-if (rc == DEFER && (defer_ok ||
-   (callout_defer_ok && *basic_errno == ERRNO_CALLOUTDEFER)))
+if (  rc == DEFER
+   && (  defer_ok
+      || callout_defer_ok && *basic_errno == ERRNO_CALLOUTDEFER
+   )  )
   {
   HDEBUG(D_acl) debug_printf_indent("verify defer overridden by %s\n",
     defer_ok? "defer_ok" : "callout_defer_ok");
@@ -2070,7 +2141,7 @@ if (rc == DEFER && (defer_ok ||
 /* If we've failed a sender, set up a recipient message, and point
 sender_verified_failed to the address item that actually failed. */
 
-if (rc != OK && verify_sender_address != NULL)
+if (rc != OK && verify_sender_address)
   {
   if (rc != DEFER)
     *log_msgptr = *user_msgptr = US"Sender verify failed";
@@ -2089,7 +2160,7 @@ if (rc != OK && verify_sender_address != NULL)
 /* Verifying an address messes up the values of $domain and $local_part,
 so reset them before returning if this is a RCPT ACL. */
 
-if (addr != NULL)
+if (addr)
   {
   deliver_domain = addr->domain;
   deliver_localpart = addr->local_part;
index a3aaf1fa664adbabc7f2f1d9d720d63808f175cf..708957f04bc140a19b7d5b64d69c7301d766e836 100644 (file)
@@ -365,7 +365,7 @@ HDEBUG(D_auth)
 #ifndef DISABLE_TLS
 if (tls_in.channelbinding && ob->server_channelbinding)
   {
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
   if (!tls_in.ext_master_secret && tls_in.resumption == RESUME_USED)
     {          /* per RFC 7677 section 4 */
     HDEBUG(D_auth) debug_printf(
@@ -814,7 +814,7 @@ HDEBUG(D_auth)
 #ifndef DISABLE_TLS
 if (tls_out.channelbinding && ob->client_channelbinding)
   {
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
   if (!tls_out.ext_master_secret && tls_out.resumption == RESUME_USED)
     {          /* per RFC 7677 section 4 */
     string_format(buffer, buffsize, "%s",
index b36a96fe1ae3cf0fe98bac3d3fdcf42792f1d036..1407b3718cea54aa830736399428732e809b8967 100644 (file)
@@ -27,7 +27,7 @@ Arguments:
 Returns:       nothing
 */
 
-static void
+void
 force_fd(int oldfd, int newfd)
 {
 if (oldfd == newfd) return;
index e17f015f96775627175eda7e49427b1284c80d24..07c0ecf8142840a3a00aeb13752a05a7f1098360 100644 (file)
@@ -52,7 +52,9 @@ Do not put spaces between # and the 'define'.
 #define DISABLE_OCSP
 #define DISABLE_PIPE_CONNECT
 #define DISABLE_PRDR
+#define DISABLE_QUEUE_RAMP
 #define DISABLE_TLS
+#define DISABLE_TLS_RESUME
 #define DISABLE_D_OPTION
 
 #define ENABLE_DISABLE_FSYNC
@@ -97,6 +99,7 @@ Do not put spaces between # and the 'define'.
 #define LOOKUP_IBASE
 #define LOOKUP_JSON
 #define LOOKUP_LDAP
+#define LOOKUP_LMDB
 #define LOOKUP_LSEARCH
 #define LOOKUP_MYSQL
 #define LOOKUP_NIS
@@ -156,6 +159,7 @@ Do not put spaces between # and the 'define'.
 #define SUPPORT_PROXY
 #define SUPPORT_SOCKS
 #define SUPPORT_SPF
+#define SUPPORT_SRS
 #define SUPPORT_TRANSLATE_IP_ADDRESS
 
 #define SYSLOG_LOG_PID
@@ -201,12 +205,8 @@ Do not put spaces between # and the 'define'.
 #define EXPERIMENTAL_BRIGHTMAIL
 #define EXPERIMENTAL_DCC
 #define EXPERIMENTAL_DSN_INFO
-#define EXPERIMENTAL_LMDB
-#define EXPERIMENTAL_QUEUE_RAMP
 #define EXPERIMENTAL_QUEUEFILE
-#define EXPERIMENTAL_SRS
-#define EXPERIMENTAL_SRS_NATIVE
-#define EXPERIMENTAL_TLS_RESUME
+#define EXPERIMENTAL_SRS_ALT
 
 
 /* For developers */
index 3423ee0af64b3b8410919a802ccbf76a818be20e..946137fc9ff838c9eff24b01bc12c51e8e9ea675 100644 (file)
@@ -169,7 +169,16 @@ acl_smtp_data =         acl_check_data
 # tls_privatekey = /etc/ssl/exim.pem
 
 # For OpenSSL, prefer EC- over RSA-authenticated ciphers
-# tls_require_ciphers = ECDSA:RSA:!COMPLEMENTOFDEFAULT
+.ifdef _HAVE_OPENSSL
+tls_require_ciphers = ECDSA:RSA:!COMPLEMENTOFDEFAULT
+.endif
+
+# Don't offer resumption to (most) MUAs, who we don't want to reuse
+# tickets.  Once the TLS extension for vended ticket numbers comes
+# though, re-examine since resumption on a single-use ticket is still a benefit.
+.ifdef _HAVE_TLS_RESUME
+tls_resumption_hosts = ${if inlist {$received_port}{587:465} {:}{*}}
+.endif
 
 # In order to support roaming users who wish to send email from anywhere,
 # you may want to make Exim listen on other ports as well as port 25, in
@@ -801,13 +810,12 @@ begin transports
 
 
 # This transport is used for delivering messages over SMTP connections.
-# Refuse to send any message with over-long lines, which could have
-# been received other than via SMTP. The use of message_size_limit to
-# enforce this is a red herring.
 
 remote_smtp:
   driver = smtp
-  message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
+.ifdef _HAVE_TLS_RESUME
+  tls_resumption_hosts = *
+.endif
 
 
 # This transport is used for delivering messages to a smarthost, if the
@@ -819,7 +827,6 @@ remote_smtp:
 
 smarthost_smtp:
   driver = smtp
-  message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
   multi_domain
   #
 .ifdef _HAVE_TLS
@@ -845,6 +852,9 @@ smarthost_smtp:
 .ifdef _HAVE_GNUTLS
   tls_require_ciphers = SECURE192:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1
 .endif
+.ifdef _HAVE_TLS_RESUME
+  tls_resumption_hosts = *
+.endif
 .endif
 
 
index 2bed143a188ac1ed57e263904c142309545bd813..1816537ecfc055d17cd639961ee41b3fa630cd92 100644 (file)
@@ -1138,14 +1138,14 @@ for (struct cmsghdr * cp = CMSG_FIRSTHDR(&msg);
 buf[sz] = 0;
 switch (buf[0])
   {
-#ifdef EXPERIMENTAL_QUEUE_RAMP
+#ifndef DISABLE_QUEUE_RAMP
   case NOTIFY_MSG_QRUN:
     /* this should be a message_id */
     DEBUG(D_queue_run)
       debug_printf("%s: qrunner trigger: %s\n", __FUNCTION__, buf+1);
     memcpy(queuerun_msgid, buf+1, MESSAGE_ID_LENGTH+1);
     return TRUE;
-#endif /*EXPERIMENTAL_QUEUE_RAMP*/
+#endif
 
   case NOTIFY_QUEUE_SIZE_REQ:
     {
@@ -2120,7 +2120,7 @@ for (;;)
     else
       {
       DEBUG(D_any) debug_printf("%s received\n",
-#ifdef EXPERIMENTAL_QUEUE_RAMP
+#ifndef DISABLE_QUEUE_RAMP
        *queuerun_msgid ? "qrun notification" :
 #endif
        "SIGALRM");
@@ -2165,7 +2165,7 @@ for (;;)
             *p++ = '-';
             *p++ = 'q';
             if (  f.queue_2stage
-#ifdef EXPERIMENTAL_QUEUE_RAMP
+#ifndef DISABLE_QUEUE_RAMP
               && !*queuerun_msgid
 #endif
               ) *p++ = 'q';
@@ -2177,7 +2177,7 @@ for (;;)
            extra[0] = *queue_name
              ? string_sprintf("%sG%s", opt, queue_name) : opt;
 
-#ifdef EXPERIMENTAL_QUEUE_RAMP
+#ifndef DISABLE_QUEUE_RAMP
            if (*queuerun_msgid)
              {
              log_write(0, LOG_MAIN, "notify triggered queue run");
@@ -2212,7 +2212,7 @@ for (;;)
 
           /* No need to re-exec; SIGALRM remains set to the default handler */
 
-#ifdef EXPERIMENTAL_QUEUE_RAMP
+#ifndef DISABLE_QUEUE_RAMP
          if (*queuerun_msgid)
            {
            log_write(0, LOG_MAIN, "notify triggered queue run");
@@ -2248,7 +2248,7 @@ for (;;)
       /* Reset the alarm clock */
 
       sigalrm_seen = FALSE;
-#ifdef EXPERIMENTAL_QUEUE_RAMP
+#ifndef DISABLE_QUEUE_RAMP
       if (*queuerun_msgid)
        *queuerun_msgid = 0;
       else
index 40db50084485400dd04f50e3f7303519d05ec7bc..dd922c72828c79819b3dd4edf1e9b00312078ad3 100644 (file)
@@ -817,7 +817,7 @@ d_tlslog(gstring * g, address_item * addr)
 if (LOGGING(tls_cipher) && addr->cipher)
   {
   g = string_append(g, 2, US" X=", addr->cipher);
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
   if (LOGGING(tls_resumption) && testflag(addr, af_tls_resume))
     g = string_catn(g, US"*", 1);
 #endif
@@ -1149,7 +1149,7 @@ if (LOGGING(sender_on_delivery) || msg)
 if (*queue_name)
   g = string_append(g, 2, US" Q=", queue_name);
 
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
 if(addr->prop.srs_sender)
   g = string_append(g, 3, US" SRS=<", addr->prop.srs_sender, US">");
 #endif
@@ -2125,7 +2125,7 @@ Arguments:
 Returns:     nothing
 */
 
-static void
+void
 deliver_local(address_item *addr, BOOL shadowing)
 {
 BOOL use_initgroups;
@@ -2143,7 +2143,7 @@ has its own return path setting, expand it and replace the existing value. */
 
 if(addr->prop.errors_address)
   return_path = addr->prop.errors_address;
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
 else if (addr->prop.srs_sender)
   return_path = addr->prop.srs_sender;
 #endif
@@ -2152,18 +2152,16 @@ else
 
 if (tp->return_path)
   {
-  uschar *new_return_path = expand_string(tp->return_path);
-  if (!new_return_path)
-    {
-    if (!f.expand_string_forcedfail)
-      {
-      common_error(TRUE, addr, ERRNO_EXPANDFAIL,
-        US"Failed to expand return path \"%s\" in %s transport: %s",
-        tp->return_path, tp->name, expand_string_message);
-      return;
-      }
+  uschar * new_return_path = expand_string(tp->return_path);
+  if (new_return_path)
+    return_path = new_return_path;
+  else if (!f.expand_string_forcedfail)
+    {
+    common_error(TRUE, addr, ERRNO_EXPANDFAIL,
+      US"Failed to expand return path \"%s\" in %s transport: %s",
+      tp->return_path, tp->name, expand_string_message);
+    return;
     }
-  else return_path = new_return_path;
   }
 
 /* For local deliveries, one at a time, the value used for logging can just be
@@ -4429,7 +4427,7 @@ for (int delivery_count = 0; addr_remote; delivery_count++)
 
   if(addr->prop.errors_address)
     return_path = addr->prop.errors_address;
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
   else if(addr->prop.srs_sender)
     return_path = addr->prop.srs_sender;
 #endif
@@ -4773,7 +4771,7 @@ all pipes, so I do not see a reason to use non-blocking IO here
 #ifdef SUPPORT_DANE
       if (tls_out.dane_verified)        setflag(addr, af_dane_verified);
 #endif
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
       if (tls_out.resumption & RESUME_USED) setflag(addr, af_tls_resume);
 # endif
 
index 0ca369cfcfa3990f99cbb4fe6274315acee0a5f2..67a2b8f52ec7679222a90aa74feeb5a1803758b3 100644 (file)
@@ -602,7 +602,7 @@ extern lookup_module_info pgsql_lookup_module_info;
 #if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
 extern lookup_module_info redis_lookup_module_info;
 #endif
-#if defined(EXPERIMENTAL_LMDB)
+#if defined(LOOKUP_LMDB)
 extern lookup_module_info lmdb_lookup_module_info;
 #endif
 #if defined(SUPPORT_SPF)
@@ -698,7 +698,7 @@ addlookupmodule(NULL, &pgsql_lookup_module_info);
 addlookupmodule(NULL, &redis_lookup_module_info);
 #endif
 
-#ifdef EXPERIMENTAL_LMDB
+#ifdef LOOKUP_LMDB
 addlookupmodule(NULL, &lmdb_lookup_module_info);
 #endif
 
index a60488e953a9ce2d858e476db1aa0f6f47a2c408..2f4149f6f55bb23fdf0de097b4333bb0514861a1 100644 (file)
@@ -931,6 +931,9 @@ g = string_cat(NULL, US"Support for:");
 #ifdef USE_OPENSSL
   g = string_cat(g, US" OpenSSL");
 #endif
+#ifndef DISABLE_TLS_RESUME
+  g = string_cat(g, US" TLS_resume");
+#endif
 #ifdef SUPPORT_TRANSLATE_IP_ADDRESS
   g = string_cat(g, US" translate_ip_address");
 #endif
@@ -946,6 +949,9 @@ g = string_cat(NULL, US"Support for:");
 #ifndef DISABLE_DKIM
   g = string_cat(g, US" DKIM");
 #endif
+#ifdef SUPPORT_DMARC
+  g = string_cat(g, US" DMARC");
+#endif
 #ifndef DISABLE_DNSSEC
   g = string_cat(g, US" DNSSEC");
 #endif
@@ -967,14 +973,17 @@ g = string_cat(NULL, US"Support for:");
 #ifdef SUPPORT_PROXY
   g = string_cat(g, US" PROXY");
 #endif
+#ifndef DISABLE_QUEUE_RAMP
+  g = string_cat(g, US" Experimental_Queue_Ramp");
+#endif
 #ifdef SUPPORT_SOCKS
   g = string_cat(g, US" SOCKS");
 #endif
 #ifdef SUPPORT_SPF
   g = string_cat(g, US" SPF");
 #endif
-#ifdef SUPPORT_DMARC
-  g = string_cat(g, US" DMARC");
+#if defined(SUPPORT_SRS)
+  g = string_cat(g, US" SRS");
 #endif
 #ifdef TCP_FASTOPEN
   tcp_init();
@@ -992,21 +1001,12 @@ g = string_cat(NULL, US"Support for:");
 #ifdef EXPERIMENTAL_DSN_INFO
   g = string_cat(g, US" Experimental_DSN_info");
 #endif
-#ifdef EXPERIMENTAL_LMDB
-  g = string_cat(g, US" Experimental_LMDB");
-#endif
-#ifdef EXPERIMENTAL_QUEUE_RAMP
-  g = string_cat(g, US" Experimental_Queue_Ramp");
-#endif
 #ifdef EXPERIMENTAL_QUEUEFILE
   g = string_cat(g, US" Experimental_QUEUEFILE");
 #endif
-#if defined(EXPERIMENTAL_SRS) || defined(EXPERIMENTAL_SRS_NATIVE)
+#if defined(EXPERIMENTAL_SRS_ALT)
   g = string_cat(g, US" Experimental_SRS");
 #endif
-#ifdef EXPERIMENTAL_TLS_RESUME
-  g = string_cat(g, US" Experimental_TLS_resume");
-#endif
 g = string_cat(g, US"\n");
 
 g = string_cat(g, US"Lookups (built-in):");
@@ -1034,7 +1034,7 @@ g = string_cat(g, US"Lookups (built-in):");
 #if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
   g = string_cat(g, US" ldap ldapdn ldapm");
 #endif
-#ifdef EXPERIMENTAL_LMDB
+#ifdef LOOKUP_LMDB
   g = string_cat(g, US" lmdb");
 #endif
 #if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
@@ -1618,6 +1618,7 @@ BOOL removed_privilege = FALSE;
 BOOL usage_wanted = FALSE;
 BOOL verify_address_mode = FALSE;
 BOOL verify_as_sender = FALSE;
+BOOL rcpt_verify_quota = FALSE;
 BOOL version_printed = FALSE;
 uschar *alias_arg = NULL;
 uschar *called_as = US"";
@@ -2790,6 +2791,13 @@ on the second character (the one after '-'), to save some effort. */
                  else badarg = TRUE;
                  break;
 
+    /* -MCq: do a quota check on the given recipient for the given size
+    of message.  Separate from -MC. */
+       case 'q': rcpt_verify_quota = TRUE;
+                 if (++i < argc) message_size = Uatoi(argv[i]);
+                 else badarg = TRUE;
+                 break;
+
     /* -MCS: set the smtp_use_size flag; this is useful only when it
     precedes -MC (see above) */
 
@@ -3504,54 +3512,40 @@ END_ARG:
 if (usage_wanted) exim_usage(called_as);
 
 /* Arguments have been processed. Check for incompatibilities. */
-if ((
-    (smtp_input || extract_recipients || recipients_arg < argc) &&
-    (f.daemon_listen || queue_interval >= 0 || bi_option ||
-      test_retry_arg >= 0 || test_rewrite_arg >= 0 ||
-      filter_test != FTEST_NONE || (msg_action_arg > 0 && !one_msg_action))
-    ) ||
-    (
-    msg_action_arg > 0 &&
-    (f.daemon_listen || queue_interval > 0 || list_options ||
-      (checking && msg_action != MSG_LOAD) ||
-      bi_option || test_retry_arg >= 0 || test_rewrite_arg >= 0)
-    ) ||
-    (
-    (f.daemon_listen || queue_interval > 0) &&
-    (sender_address != NULL || list_options || list_queue || checking ||
-      bi_option)
-    ) ||
-    (
-    f.daemon_listen && queue_interval == 0
-    ) ||
-    (
-    f.inetd_wait_mode && queue_interval >= 0
-    ) ||
-    (
-    list_options &&
-    (checking || smtp_input || extract_recipients ||
-      filter_test != FTEST_NONE || bi_option)
-    ) ||
-    (
-    verify_address_mode &&
-    (f.address_test_mode || smtp_input || extract_recipients ||
-      filter_test != FTEST_NONE || bi_option)
-    ) ||
-    (
-    f.address_test_mode && (smtp_input || extract_recipients ||
-      filter_test != FTEST_NONE || bi_option)
-    ) ||
-    (
-    smtp_input && (sender_address != NULL || filter_test != FTEST_NONE ||
-      extract_recipients)
-    ) ||
-    (
-    deliver_selectstring != NULL && queue_interval < 0
-    ) ||
-    (
-    msg_action == MSG_LOAD &&
-      (!expansion_test || expansion_test_message != NULL)
-    )
+if (  (  (smtp_input || extract_recipients || recipients_arg < argc)
+      && (  f.daemon_listen || queue_interval >= 0 || bi_option
+        || test_retry_arg >= 0 || test_rewrite_arg >= 0
+        || filter_test != FTEST_NONE
+        || msg_action_arg > 0 && !one_msg_action
+      )  )
+   || (  msg_action_arg > 0
+      && (  f.daemon_listen || queue_interval > 0 || list_options
+        || checking && msg_action != MSG_LOAD
+        || bi_option || test_retry_arg >= 0 || test_rewrite_arg >= 0
+      )  )
+   || (  (f.daemon_listen || queue_interval > 0)
+      && (  sender_address || list_options || list_queue || checking
+        || bi_option
+      )  )
+   || f.daemon_listen && queue_interval == 0
+   || f.inetd_wait_mode && queue_interval >= 0
+   || (  list_options
+      && (  checking || smtp_input || extract_recipients
+        || filter_test != FTEST_NONE || bi_option
+      )  )
+   || (  verify_address_mode
+      && (  f.address_test_mode || smtp_input || extract_recipients
+        || filter_test != FTEST_NONE || bi_option
+      )  )
+   || (  f.address_test_mode
+      && (  smtp_input || extract_recipients || filter_test != FTEST_NONE
+        || bi_option
+      )  )
+   || (  smtp_input
+      && (sender_address || filter_test != FTEST_NONE || extract_recipients)
+      )
+   || deliver_selectstring && queue_interval < 0
+   || msg_action == MSG_LOAD && (!expansion_test || expansion_test_message)
    )
   exim_fail("exim: incompatible command-line options or arguments\n");
 
@@ -4172,7 +4166,7 @@ if (!f.admin_user)
      || queue_name_dest && prod_requires_admin
      || debugset && !f.running_in_test_harness
      )
-    exim_fail("exim:%s permission denied\n", debugset? " debugging" : "");
+    exim_fail("exim:%s permission denied\n", debugset ? " debugging" : "");
   }
 
 /* If the real user is not root or the exim uid, the argument for passing
@@ -4181,11 +4175,13 @@ running with the -N option for any delivery action, unless this call to exim is
 one that supplied an input message, or we are using a patched exim for
 regression testing. */
 
-if (real_uid != root_uid && real_uid != exim_uid &&
-     (continue_hostname != NULL ||
-       (f.dont_deliver &&
-         (queue_interval >= 0 || f.daemon_listen || msg_action_arg > 0)
-       )) && !f.running_in_test_harness)
+if (  real_uid != root_uid && real_uid != exim_uid
+   && (  continue_hostname
+      || (  f.dont_deliver
+        && (queue_interval >= 0 || f.daemon_listen || msg_action_arg > 0)
+      )  )
+   && !f.running_in_test_harness
+   )
   exim_fail("exim: Permission denied\n");
 
 /* If the caller is not trusted, certain arguments are ignored when running for
@@ -4207,9 +4203,9 @@ Exim exits if the syntax is bad. */
 
 else
   {
-  if (sender_host_address != NULL)
+  if (sender_host_address)
     sender_host_port = check_port(sender_host_address);
-  if (interface_address != NULL)
+  if (interface_address)
     interface_port = check_port(interface_address);
   }
 
@@ -4296,18 +4292,20 @@ retained only for starting the daemon. We always do the initgroups() in this
 situation (controlled by the TRUE below), in order to be as close as possible
 to the state Exim usually runs in. */
 
-if (!unprivileged &&                      /* originally had root AND */
-    !removed_privilege &&                 /* still got root AND      */
-    !f.daemon_listen &&                     /* not starting the daemon */
-    queue_interval <= 0 &&                /* (either kind of daemon) */
-      (                                   /*    AND EITHER           */
-      deliver_drop_privilege ||           /* requested unprivileged  */
-        (                                 /*       OR                */
-        queue_interval < 0 &&             /* not running the queue   */
-        (msg_action_arg < 0 ||            /*       and               */
-          msg_action != MSG_DELIVER) &&   /* not delivering and      */
-        (!checking || !f.address_test_mode) /* not address checking    */
-   )  ) )
+if (  !unprivileged                            /* originally had root AND */
+   && !removed_privilege                       /* still got root AND      */
+   && !f.daemon_listen                         /* not starting the daemon */
+   && queue_interval <= 0                      /* (either kind of daemon) */
+   && (                                                /*    AND EITHER           */
+         deliver_drop_privilege                        /* requested unprivileged  */
+      || (                                     /*       OR                */
+            queue_interval < 0                 /* not running the queue   */
+         && (  msg_action_arg < 0              /*       and               */
+            || msg_action != MSG_DELIVER       /* not delivering          */
+           )                                   /*       and               */
+         && (!checking || !f.address_test_mode)        /* not address checking    */
+        && !rcpt_verify_quota                  /* and not quota checking  */
+   )  )  )
   exim_setugid(exim_uid, exim_gid, TRUE, US"privilege not needed");
 
 /* When we are retaining a privileged uid, we still change to the exim gid. */
@@ -4338,8 +4336,7 @@ if (malware_test_file)
 #ifdef WITH_CONTENT_SCAN
   int result;
   set_process_info("scanning file for malware");
-  result = malware_in_file(malware_test_file);
-  if (result == FAIL)
+  if ((result = malware_in_file(malware_test_file)) == FAIL)
     {
     printf("No malware found.\n");
     exit(EXIT_SUCCESS);
@@ -4428,6 +4425,18 @@ needed in transports so we lost the optimisation. */
 #endif
   }
 
+/* Handle a request to check quota */
+if (rcpt_verify_quota)
+  if (real_uid != root_uid && real_uid != exim_uid)
+    exim_fail("exim: Permission denied\n");
+  else if (recipients_arg >= argc)
+    exim_fail("exim: missing recipient for quota check\n");
+  else
+    {
+    verify_quota(argv[recipients_arg]);
+    exim_exit(EXIT_SUCCESS);
+    }
+
 /* Handle the -brt option. This is for checking out retry configurations.
 The next three arguments are a domain name or a complete address, and
 optionally two error numbers. All it does is to call the function that
@@ -4862,8 +4871,8 @@ if (  !smtp_input && !sender_address
   sender, or if a sender other than <> is set, override with the originator's
   login (which will get qualified below), except when checking things. */
 
-  if (sender_address == NULL             /* No sender_address set */
-       ||                                /*         OR            */
+  if (  !sender_address                  /* No sender_address set */
+     ||                                  /*         OR            */
        (sender_address[0] != 0 &&        /* Non-empty sender address, AND */
        !checking))                       /* Not running tests, including filter tests */
     {
@@ -4914,7 +4923,6 @@ if (verify_address_mode || f.address_test_mode)
     }
 
   if (recipients_arg < argc)
-    {
     while (recipients_arg < argc)
       {
       /* Supplied addresses are tainted since they come from a user */
@@ -4930,7 +4938,6 @@ if (verify_address_mode || f.address_test_mode)
           while (*++s == ',' || isspace(*s)) ;
         }
       }
-    }
 
   else for (;;)
     {
index 2cc2621c42f515a83ede61abc4e15ed52ed6555c..1ddba187bb99fb8fc51a2484f2f0bba54e28d91b 100644 (file)
@@ -493,7 +493,7 @@ config.h, mytypes.h, and store.h, so we don't need to mention them explicitly.
 #ifdef SUPPORT_SPF
 # include "spf.h"
 #endif
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
 # include "srs.h"
 #endif
 #ifndef DISABLE_DKIM
index 26f7f10acfed2bb61ba423c60014927410ef2af5..b014533c928d3df9c687dd593190f7702b39f336 100644 (file)
@@ -131,7 +131,7 @@ static uschar *item_table[] = {
   US"run",
   US"sg",
   US"sort",
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
   US"srs_encode",
 #endif
   US"substr",
@@ -166,7 +166,7 @@ enum {
   EITEM_RUN,
   EITEM_SG,
   EITEM_SORT,
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
   EITEM_SRS_ENCODE,
 #endif
   EITEM_SUBSTR,
@@ -334,7 +334,7 @@ static uschar *cond_table[] = {
   US"gei",
   US"gt",
   US"gti",
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
   US"inbound_srs",
 #endif
   US"inlist",
@@ -387,7 +387,7 @@ enum {
   ECOND_STR_GEI,
   ECOND_STR_GT,
   ECOND_STR_GTI,
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
   ECOND_INBOUND_SRS,
 #endif
   ECOND_INLIST,
@@ -752,16 +752,16 @@ static var_entry var_table[] = {
   { "spool_directory",     vtype_stringptr,   &spool_directory },
   { "spool_inodes",        vtype_pinodes,     (void *)TRUE },
   { "spool_space",         vtype_pspace,      (void *)TRUE },
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
   { "srs_db_address",      vtype_stringptr,   &srs_db_address },
   { "srs_db_key",          vtype_stringptr,   &srs_db_key },
   { "srs_orig_recipient",  vtype_stringptr,   &srs_orig_recipient },
   { "srs_orig_sender",     vtype_stringptr,   &srs_orig_sender },
 #endif
-#if defined(EXPERIMENTAL_SRS) || defined(EXPERIMENTAL_SRS_NATIVE)
+#if defined(EXPERIMENTAL_SRS_ALT) || defined(SUPPORT_SRS)
   { "srs_recipient",       vtype_stringptr,   &srs_recipient },
 #endif
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
   { "srs_status",          vtype_stringptr,   &srs_status },
 #endif
   { "thisaddress",         vtype_stringptr,   &filter_thisaddress },
@@ -779,7 +779,7 @@ static var_entry var_table[] = {
   { "tls_in_ourcert",      vtype_cert,        &tls_in.ourcert },
   { "tls_in_peercert",     vtype_cert,        &tls_in.peercert },
   { "tls_in_peerdn",       vtype_stringptr,   &tls_in.peerdn },
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
   { "tls_in_resumption",   vtype_int,         &tls_in.resumption },
 #endif
 #ifndef DISABLE_TLS
@@ -797,7 +797,7 @@ static var_entry var_table[] = {
   { "tls_out_ourcert",     vtype_cert,        &tls_out.ourcert },
   { "tls_out_peercert",    vtype_cert,        &tls_out.peercert },
   { "tls_out_peerdn",      vtype_stringptr,   &tls_out.peerdn },
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
   { "tls_out_resumption",  vtype_int,         &tls_out.resumption },
 #endif
 #ifndef DISABLE_TLS
@@ -2439,7 +2439,7 @@ else
 
 
 
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
 /* Do an hmac_md5.  The result is _not_ nul-terminated, and is sized as
 the smaller of a full hmac_md5 result (16 bytes) or the supplied output buffer.
 
@@ -2514,7 +2514,7 @@ for (int i = 0, j = len; i < MD5_HASHLEN; i++)
   }
 return;
 }
-#endif /*EXPERIMENTAL_SRS_NATIVE*/
+#endif /*SUPPORT_SRS*/
 
 
 /*************************************************
@@ -3444,7 +3444,7 @@ switch(cond_type = identify_operator(&s, &opname))
     return s;
     }
 
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
   case ECOND_INBOUND_SRS:
     /* ${if inbound_srs {local_part}{secret}  {yes}{no}} */
     {
@@ -3536,7 +3536,7 @@ srs_result:
     if (yield) *yield = (boolvalue == testfor);
     return s;
     }
-#endif /*EXPERIMENTAL_SRS_NATIVE*/
+#endif /*SUPPORT_SRS*/
 
   /* Unknown condition */
 
@@ -6785,7 +6785,7 @@ while (*s != 0)
       continue;
       }
 
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
     case EITEM_SRS_ENCODE:
       /* ${srs_encode {secret} {return_path} {orig_domain}} */
       {
@@ -6839,7 +6839,7 @@ while (*s != 0)
       yield = string_cat(yield, sub[2]);
       continue;
       }
-#endif /*EXPERIMENTAL_SRS_NATIVE*/
+#endif /*SUPPORT_SRS*/
     }  /* EITEM_* switch */
 
   /* Control reaches here if the name is not recognized as one of the more
index 0028deb0d6d2622aa0c8e88d463c6984e74df84d..486a91595a09ed9e0e80d68a59166e792c6030cc 100644 (file)
@@ -189,6 +189,7 @@ extern void    debug_print_socket(int);
 extern void    decode_bits(unsigned int *, size_t, int *,
                   uschar *, bit_table *, int, uschar *, int);
 extern void    delete_pid_file(void);
+extern void    deliver_local(address_item *, BOOL);
 extern address_item *deliver_make_addr(uschar *, BOOL);
 extern void    delivery_log(int, address_item *, int, uschar *);
 extern int     deliver_message(uschar *, BOOL, BOOL);
@@ -260,6 +261,7 @@ extern BOOL    filter_runtest(int, uschar *, BOOL, BOOL);
 extern BOOL    filter_system_interpret(address_item **, uschar **);
 
 extern uschar * fn_hdrs_added(void);
+extern void    force_fd(int, int);
 
 extern void    header_add(int, const char *, ...);
 extern header_line *header_add_at_position_internal(BOOL, uschar *, BOOL, int, const char *, ...);
@@ -379,7 +381,7 @@ extern void    queue_check_only(void);
 extern unsigned queue_count(void);
 extern unsigned queue_count_cached(void);
 extern void    queue_list(int, uschar **, int);
-#ifdef EXPERIMENTAL_QUEUE_RAMP
+#ifndef DISABLE_QUEUE_RAMP
 extern void    queue_notify_daemon(const uschar * hostname);
 #endif
 extern void    queue_run(uschar *, uschar *, BOOL);
@@ -620,6 +622,8 @@ extern int     verify_check_this_host(const uschar **, unsigned int *,
                 const uschar*, const uschar *, const uschar **);
 extern address_item *verify_checked_sender(uschar *);
 extern void    verify_get_ident(int);
+extern void    verify_quota(uschar *);
+extern int     verify_quota_call(const uschar *, int, int, uschar **);
 extern BOOL    verify_sender(int *, uschar **);
 extern BOOL    verify_sender_preliminary(int *, uschar **);
 extern void    version_init(void);
index fc3086f7251b603d341a5d0f347ba800984ebe21..1b2333053f62ad4b379cd6379b29ada40b23bea0 100644 (file)
@@ -137,7 +137,7 @@ uschar *tls_ocsp_file          = NULL;
 uschar *tls_privatekey         = NULL;
 BOOL    tls_remember_esmtp     = FALSE;
 uschar *tls_require_ciphers    = NULL;
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
 uschar *tls_resumption_hosts   = NULL;
 # endif
 uschar *tls_try_verify_hosts   = NULL;
@@ -382,7 +382,7 @@ BOOL    prod_requires_admin    = TRUE;
 BOOL    proxy_session          = FALSE;
 #endif
 
-#ifdef EXPERIMENTAL_QUEUE_RAMP
+#ifndef DISABLE_QUEUE_RAMP
 BOOL    queue_fast_ramp                = FALSE;
 #endif
 BOOL    queue_list_requires_admin = TRUE;
@@ -407,7 +407,7 @@ BOOL    spf_result_guessed     = FALSE;
 #endif
 BOOL    split_spool_directory  = FALSE;
 BOOL    spool_wireformat       = FALSE;
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
 BOOL    srs_usehash            = TRUE;
 BOOL    srs_usetimestamp       = TRUE;
 #endif
@@ -596,7 +596,7 @@ address_item address_defaults = {
     .extra_headers =   NULL,
     .remove_headers =  NULL,
     .variables =       NULL,
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
     .srs_sender =      NULL,
 #endif
     .ignore_error =    FALSE,
@@ -1508,7 +1508,7 @@ uschar *spf_smtp_comment_template
 FILE   *spool_data_file               = NULL;
 uschar *spool_directory        = US SPOOL_DIRECTORY
                            "\0<--------------Space to patch spool_directory->";
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
 uschar *srs_config             = NULL;
 uschar *srs_db_address         = NULL;
 uschar *srs_db_key             = NULL;
@@ -1521,7 +1521,7 @@ uschar *srs_recipient          = NULL;
 uschar *srs_secrets            = NULL;
 uschar *srs_status             = NULL;
 #endif
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
 uschar *srs_recipient          = NULL;
 #endif
 int     string_datestamp_offset= -1;
index c80c8532f07c54b460fd4dfc334bc103baa9927f..0c85c11501976d9e53d2cab033425d857906cbc8 100644 (file)
@@ -107,7 +107,7 @@ typedef struct {
     OCSP_FAILED,               /* verify failed */
     OCSP_VFIED                 /* verified */
     }     ocsp;                      /* Stapled OCSP status */
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
   unsigned resumption;         /* Session resumption */
   BOOL   host_resumable:1;
   BOOL   ticket_received:1;
@@ -134,7 +134,7 @@ extern uschar *tls_ocsp_file;          /* OCSP stapling proof file */
 extern uschar *tls_privatekey;         /* Private key file */
 extern BOOL    tls_remember_esmtp;     /* For YAEB */
 extern uschar *tls_require_ciphers;    /* So some can be avoided */
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
 extern uschar *tls_resumption_hosts;   /* TLS session resumption */
 # endif
 extern uschar *tls_try_verify_hosts;   /* Optional client verification */
@@ -792,7 +792,7 @@ extern uschar *prvscheck_result;       /* Set during prvscheck expansion item */
 extern const uschar *qualify_domain_recipient; /* Domain to qualify recipients with */
 extern uschar *qualify_domain_sender;  /* Domain to qualify senders with */
 extern uschar *queue_domains;          /* Queue these domains */
-#ifdef EXPERIMENTAL_QUEUE_RAMP
+#ifndef DISABLE_QUEUE_RAMP
 extern BOOL    queue_fast_ramp;        /* 2-phase queue-run overlap */
 #endif
 extern BOOL    queue_list_requires_admin; /* TRUE if -bp requires admin */
@@ -943,6 +943,7 @@ extern int     smtp_load_reserve;      /* Only from reserved if load > this */
 extern int     smtp_mailcmd_count;     /* Count of MAIL commands */
 extern int     smtp_max_synprot_errors;/* Max syntax/protocol errors */
 extern int     smtp_max_unknown_commands; /* As it says */
+extern uschar *smtp_names[];          /* decode for command codes */
 extern uschar *smtp_notquit_reason;    /* Global for disconnect reason */
 extern FILE   *smtp_out;               /* Incoming SMTP output file */
 extern uschar *smtp_ratelimit_hosts;   /* Rate limit these hosts */
@@ -989,7 +990,7 @@ extern BOOL    split_spool_directory;  /* TRUE to use multiple subdirs */
 extern FILE   *spool_data_file;               /* handle for -D file */
 extern uschar *spool_directory;        /* Name of spool directory */
 extern BOOL    spool_wireformat;       /* can write wireformat -D files */
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
 extern uschar *srs_config;             /* SRS config secret:max age:hash length:use timestamp:use hash */
 extern uschar *srs_db_address;         /* SRS db address */
 extern uschar *srs_db_key;             /* SRS db key */
@@ -1004,7 +1005,7 @@ extern uschar *srs_status;             /* SRS staus */
 extern BOOL    srs_usehash;            /* SRS use hash flag */
 extern BOOL    srs_usetimestamp;       /* SRS use timestamp flag */
 #endif
-#ifdef EXPERIMENTAL_SRS_NATIVE
+#ifdef SUPPORT_SRS
 extern uschar *srs_recipient;          /* SRS recipient */
 #endif
 extern BOOL    strict_acl_vars;        /* ACL variables have to be set before being used */
index 4066751983d1c30e15059acf5d660c6089ce36e0..d9cf25d548eac36f8416224731c3af47d2bbeb1b 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "../exim.h"
 
-#ifdef EXPERIMENTAL_LMDB
+#ifdef LOOKUP_LMDB
 
 #include <lmdb.h>
 
@@ -158,4 +158,4 @@ static lookup_info lmdb_lookup_info = {
 static lookup_info *_lookup_list[] = { &lmdb_lookup_info };
 lookup_module_info lmdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
 
-#endif /* EXPERIMENTAL_LMDB */
+#endif /* LOOKUP_LMDB */
index 2b3269d9007282f4f99d4580ca6708a8bcb12e3d..9c3d34a96338117fcaefb74b4ecd685ed149e0e3 100644 (file)
@@ -174,21 +174,18 @@ due to conflicts with other common macros. */
 #ifdef SUPPORT_SOCKS
   builtin_macro_create(US"_HAVE_SOCKS");
 #endif
+#if defined(SUPPORT_SRS)
+  builtin_macro_create(US"_HAVE_NATIVE_SRS");  /* beware clash with _HAVE_SRS */
+#endif
 #ifdef TCP_FASTOPEN
   builtin_macro_create(US"_HAVE_TCP_FASTOPEN");
 #endif
-#ifdef EXPERIMENTAL_LMDB
-  builtin_macro_create(US"_HAVE_LMDB");
-#endif
 #ifdef SUPPORT_SPF
   builtin_macro_create(US"_HAVE_SPF");
 #endif
-#if defined(EXPERIMENTAL_SRS) || defined(EXPERIMENTAL_SRS_NATIVE)
+#if defined(EXPERIMENTAL_SRS_ALT) || defined(SUPPORT_SRS)
   builtin_macro_create(US"_HAVE_SRS");
 #endif
-#if defined(EXPERIMENTAL_SRS_NATIVE)
-  builtin_macro_create(US"_HAVE_NATIVE_SRS");  /* beware clash with _HAVE_SRS */
-#endif
 #ifdef EXPERIMENTAL_ARC
   builtin_macro_create(US"_HAVE_ARC");
 #endif
@@ -204,7 +201,7 @@ due to conflicts with other common macros. */
 #ifdef EXPERIMENTAL_DSN_INFO
   builtin_macro_create(US"_HAVE_DSN_INFO");
 #endif
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
   builtin_macro_create(US"_HAVE_TLS_RESUME");
 #endif
 
@@ -226,6 +223,10 @@ due to conflicts with other common macros. */
 #ifdef LOOKUP_IBASE
   builtin_macro_create(US"_HAVE_LOOKUP_IBASE");
 #endif
+#ifdef LOOKUP_LMDB
+  builtin_macro_create(US"_HAVE_LMDB");
+  builtin_macro_create(US"_HAVE_LOOKUP_LMDB");
+#endif
 #ifdef LOOKUP_LDAP
   builtin_macro_create(US"_HAVE_LOOKUP_JSON");
 #endif
index a507bbf836914a316544b879d0a0d4b1e2892a4f..f6012447d02fd09621dae0d3337ae17b5e81d73f 100644 (file)
@@ -736,6 +736,7 @@ enum { v_none, v_sender, v_recipient, v_expn };
 #define vopt_callout_recippmaster 0x0100   /* use postmaster to verify recip */
 #define vopt_callout_hold        0x0200   /* lazy close connection */
 #define vopt_success_on_redirect  0x0400
+#define vopt_quota                0x0800   /* quota check, to local/appendfile */
 
 /* Values for fields in callout cache records */
 
index 37d6124822b0b2c8725080b48a03a35d08d20ce7..6748afd5d8c99e5eaa237ccf29f530faaf165edc 100644 (file)
@@ -1531,7 +1531,7 @@ if (s)
 /******************************************************************************/
 /******************************************************************************/
 
-#ifdef EXPERIMENTAL_QUEUE_RAMP
+#ifndef DISABLE_QUEUE_RAMP
 void
 queue_notify_daemon(const uschar * msgid)
 {
index 0d0769c88d3f04c597058dda1cd72a1d57d47f68..a8f13350a8567a179abcb4778dd8f4cec1abac5d 100644 (file)
@@ -262,7 +262,7 @@ static optionlist optionlist_config[] = {
   { "qualify_domain",           opt_stringptr,   {&qualify_domain_sender} },
   { "qualify_recipient",        opt_stringptr,   {&qualify_domain_recipient} },
   { "queue_domains",            opt_stringptr,   {&queue_domains} },
-#ifdef EXPERIMENTAL_QUEUE_RAMP
+#ifndef DISABLE_QUEUE_RAMP
   { "queue_fast_ramp",          opt_bool,        {&queue_fast_ramp} },
 #endif
   { "queue_list_requires_admin",opt_bool,        {&queue_list_requires_admin} },
@@ -335,7 +335,7 @@ static optionlist optionlist_config[] = {
   { "sqlite_dbfile",            opt_stringptr,   {&sqlite_dbfile} },
   { "sqlite_lock_timeout",      opt_int,         {&sqlite_lock_timeout} },
 #endif
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
   { "srs_config",               opt_stringptr,   {&srs_config} },
   { "srs_hashlength",           opt_int,         {&srs_hashlength} },
   { "srs_hashmin",              opt_int,         {&srs_hashmin} },
@@ -379,7 +379,7 @@ static optionlist optionlist_config[] = {
   { "tls_privatekey",           opt_stringptr,   {&tls_privatekey} },
   { "tls_remember_esmtp",       opt_bool,        {&tls_remember_esmtp} },
   { "tls_require_ciphers",      opt_stringptr,   {&tls_require_ciphers} },
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
   { "tls_resumption_hosts",     opt_stringptr,   {&tls_resumption_hosts} },
 # endif
   { "tls_try_verify_hosts",     opt_stringptr,   {&tls_try_verify_hosts} },
index 0fbd35f82f7e663a355d3a3496e6968000e27848..df8719ec666a6eaeea95ea890405a673911045f8 100644 (file)
@@ -3994,7 +3994,7 @@ g = add_host_info_for_log(g);
 if (LOGGING(tls_cipher) && tls_in.cipher)
   {
   g = string_append(g, 2, US" X=", tls_in.cipher);
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
   if (LOGGING(tls_resumption) && tls_in.resumption & RESUME_USED)
     g = string_catn(g, US"*", 1);
 # endif
index 03c84fc8953c026bc588f8b275170a32498f5162..5b206c57298354d59d0412775f624fca71a5ea8e 100644 (file)
@@ -242,7 +242,7 @@ rc = rf_get_munge_headers(addr, rblock, &addr_prop.extra_headers,
   &addr_prop.remove_headers);
 if (rc != OK) return rc;
 
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
 addr_prop.srs_sender = NULL;
 #endif
 
index cd225d8e91f59e44b73c7df5fecabd8a75d62856..13b6e5244684e37aabf0b69479c6a475d4e5e144 100644 (file)
@@ -93,7 +93,7 @@ optionlist redirect_router_options[] = {
   { "sieve_useraddress", opt_stringptr,                LOFF(sieve_useraddress) },
   { "sieve_vacation_directory", opt_stringptr, LOFF(sieve_vacation_directory) },
   { "skip_syntax_errors", opt_bool,            LOFF(skip_syntax_errors) },
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
   { "srs",                opt_stringptr,       LOFF(srs) },
   { "srs_alias",          opt_stringptr,       LOFF(srs_alias) },
   { "srs_condition",      opt_stringptr,       LOFF(srs_condition) },
@@ -149,7 +149,7 @@ redirect_router_options_block redirect_router_option_defaults = {
   NULL,        /* qualify_domain */
   NULL,        /* owners */
   NULL,        /* owngroups */
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
   NULL,        /* srs */
   NULL,        /* srs_alias */
   NULL,        /* srs_condition */
@@ -543,7 +543,7 @@ addr_prop.remove_headers = NULL;
 addr_prop.variables = NULL;
 tree_dup((tree_node **)&addr_prop.variables, addr->prop.variables);
 
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
 addr_prop.srs_sender = NULL;
 #endif
 #ifdef SUPPORT_I18N
@@ -578,7 +578,7 @@ if (!ugid.gid_set && pw != NULL)
   ugid.gid_set = TRUE;
   }
 
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
   /* Perform SRS on recipient/return-path as required  */
 
   if(ob->srs != NULL)
index 74e14af7421957e873ca5a09a4cd279c111d1687..7c9ee1ce0dd68e159b363fb6e3a7a84f107d438a 100644 (file)
@@ -34,7 +34,7 @@ typedef struct {
   uid_t  *owners;
   gid_t  *owngroups;
 
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
   uschar *srs;
   uschar *srs_alias;
   uschar *srs_condition;
index f8aaacb04fd194bf9b74f5ff3f376dd8148c0952..d1633a5e108ee310d7347a2c45ff7e8b6f42e29c 100644 (file)
@@ -462,6 +462,7 @@ Arguments:
                NULL for query-style searches
   keystring    the keystring for single-key+file lookups, or
                the querystring for query-style lookups
+  cache_rd     FALSE to avoid lookup in cache layer
   opts        type-specific options
 
 Returns:       a pointer to a dynamic string containing the answer,
@@ -472,7 +473,7 @@ Returns:       a pointer to a dynamic string containing the answer,
 
 static uschar *
 internal_search_find(void * handle, const uschar * filename, uschar * keystring,
-  const uschar * opts)
+  BOOL cache_rd, const uschar * opts)
 {
 tree_node * t = (tree_node *)handle;
 search_cache * c = (search_cache *)(t->data.ptr);
@@ -501,11 +502,13 @@ if (keystring[0] == 0) return NULL;
 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. */
+file. No need to check c->item_cache for NULL, tree_search will do so. Check
+whether we want to use the cache entry last so that we can always replace it. */
 
 if (  (t = tree_search(c->item_cache, keystring))
    && (!(e = t->data.ptr)->expiry || e->expiry > time(NULL))
    && (!opts && !e->opts  ||  opts && e->opts && Ustrcmp(opts, e->opts) == 0)
+   && cache_rd
    )
   { /* Data was in the cache already; set the pointer from the tree node */
   data = e->data.ptr;
@@ -522,7 +525,8 @@ else
     {
     if (t)
       debug_printf_indent("cached data found but %s; ",
-       e->expiry && e->expiry <= time(NULL) ? "out-of-date" : "wrong opts");
+       e->expiry && e->expiry <= time(NULL) ? "out-of-date"
+       : cache_rd ? "wrong opts" : "no_rd option set");
     debug_printf_indent("%s lookup required for %s%s%s\n",
       filename ? US"file" : US"database",
       keystring,
@@ -541,14 +545,19 @@ else
   or points to a bit of dynamic store. Cache the result of the lookup if
   caching is permitted. Lookups can disable caching, when they did something
   that changes their data. The mysql and pgsql lookups do this when an
-  UPDATE/INSERT query was executed. */
+  UPDATE/INSERT query was executed.  Lookups can also set a TTL for the
+  cache entry; the dnsdb lookup does.
+  Finally, the caller can request no caching by setting an option. */
 
   else if (do_cache)
     {
+    DEBUG(D_lookup) debug_printf_indent("%s cache entry\n",
+      t ? "replacing old" : "creating new");
     if (!t)    /* No existing entry.  Create new one. */
       {
       int len = keylength + 1;
-      e = store_get(sizeof(expiring_data) + sizeof(tree_node) + len, is_tainted(keystring));
+      e = store_get(sizeof(expiring_data) + sizeof(tree_node) + len,
+                   is_tainted(keystring));
       t = (tree_node *)(e+1);
       memcpy(t->name, keystring, len);
       t->data.ptr = e;
@@ -621,9 +630,9 @@ search_find(void * handle, const uschar * filename, uschar * keystring,
   int partial, const uschar * affix, int affixlen, int starflags,
   int * expand_setup, const uschar * opts)
 {
-tree_node *t = (tree_node *)handle;
-BOOL set_null_wild = FALSE;
-uschar *yield;
+tree_node * t = (tree_node *)handle;
+BOOL set_null_wild = FALSE, cache_rd = TRUE, ret_key = FALSE;
+uschar * yield;
 
 DEBUG(D_lookup)
   {
@@ -636,6 +645,23 @@ DEBUG(D_lookup)
 
   }
 
+/* Parse global lookup options. Also, create a new options list with
+the global options dropped so that the cache-modifiers are not
+used in the cache key. */
+
+if (opts)
+  {
+  int sep = ',';
+  gstring * g = NULL;
+
+  for (uschar * ele; ele = string_nextinlist(&opts, &sep, NULL, 0); )
+    if (Ustrcmp(ele, "ret=key") == 0) ret_key = TRUE;
+    else if (Ustrcmp(ele, "cache=no_rd") == 0) cache_rd = FALSE;
+    else g = string_append_listele(g, ',', ele);
+
+  opts = string_from_gstring(g);
+  }
+
 /* Arrange to put this database at the top of the LRU chain if it is a type
 that opens real files. */
 
@@ -683,7 +709,7 @@ DEBUG(D_lookup)
 /* First of all, try to match the key string verbatim. If matched a complete
 entry but could have been partial, flag to set up variables. */
 
-yield = internal_search_find(handle, filename, keystring, opts);
+yield = internal_search_find(handle, filename, keystring, cache_rd, opts);
 if (f.search_find_defer) return NULL;
 
 if (yield) { if (partial >= 0) set_null_wild = TRUE; }
@@ -708,7 +734,7 @@ else if (partial >= 0)
     Ustrncpy(keystring2, affix, affixlen);
     Ustrcpy(keystring2 + affixlen, keystring);
     DEBUG(D_lookup) debug_printf_indent("trying partial match %s\n", keystring2);
-    yield = internal_search_find(handle, filename, keystring2, opts);
+    yield = internal_search_find(handle, filename, keystring2, cache_rd, opts);
     if (f.search_find_defer) return NULL;
     }
 
@@ -746,7 +772,8 @@ else if (partial >= 0)
         }
 
       DEBUG(D_lookup) debug_printf_indent("trying partial match %s\n", keystring3);
-      yield = internal_search_find(handle, filename, keystring3, opts);
+      yield = internal_search_find(handle, filename, keystring3,
+               cache_rd, opts);
       if (f.search_find_defer) return NULL;
       if (yield)
         {
@@ -787,7 +814,7 @@ if (!yield  &&  starflags & SEARCH_STARAT)
     *atat = '*';
 
     DEBUG(D_lookup) debug_printf_indent("trying default match %s\n", atat);
-    yield = internal_search_find(handle, filename, atat, opts);
+    yield = internal_search_find(handle, filename, atat, cache_rd, opts);
     *atat = savechar;
     if (f.search_find_defer) return NULL;
 
@@ -810,7 +837,7 @@ and the second is empty. */
 if (!yield  &&  starflags & (SEARCH_STAR|SEARCH_STARAT))
   {
   DEBUG(D_lookup) debug_printf_indent("trying to match *\n");
-  yield = internal_search_find(handle, filename, US"*", opts);
+  yield = internal_search_find(handle, filename, US"*", cache_rd, opts);
   if (yield && expand_setup && *expand_setup >= 0)
     {
     *expand_setup += 1;
@@ -843,17 +870,8 @@ if (set_null_wild && expand_setup && *expand_setup >= 0)
 than the result.  Return a de-tainted version of the key on the grounds that
 it have been validated by the lookup. */
 
-if (yield && opts)
-  {
-  int sep = ',';
-  for (uschar * ele; ele = string_nextinlist(&opts, &sep, NULL, 0); )
-    if (Ustrcmp(ele, "ret=key") == 0)
-      {
-      DEBUG(D_lookup) debug_printf_indent("lookup ret=key: %s\n", keystring);
-      yield = string_copy_taint(keystring, FALSE);
-      break;
-      }
-  }
+if (yield && ret_key)
+  yield = string_copy_taint(keystring, FALSE);
 
 return yield;
 }
index 526164c4699370d00cdbb685232ceb044c004b8b..8b0902b5d9fe0224a1ba1b52e72f87f19482287f 100644 (file)
@@ -227,7 +227,7 @@ static smtp_cmd_list *cmd_list_end =
 /* This list of names is used for performing the smtp_no_mail logging action.
 It must be kept in step with the SCH_xxx enumerations. */
 
-static uschar *smtp_names[] =
+uschar * smtp_names[] =
   {
   US"NONE", US"AUTH", US"DATA", US"BDAT", US"EHLO", US"ETRN", US"EXPN",
   US"HELO", US"HELP", US"MAIL", US"NOOP", US"QUIT", US"RCPT", US"RSET",
@@ -1801,7 +1801,7 @@ s_tlslog(gstring * g)
 if (LOGGING(tls_cipher) && tls_in.cipher)
   {
   g = string_append(g, 2, US" X=", tls_in.cipher);
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
   if (LOGGING(tls_resumption) && tls_in.resumption & RESUME_USED)
     g = string_catn(g, US"*", 1);
 #endif
@@ -2068,6 +2068,7 @@ sending_ip_address = NULL;
 return_path = sender_address = NULL;
 deliver_localpart_data = deliver_domain_data =
 recipient_data = sender_data = NULL;                   /* Can be set by ACL */
+recipient_verify_failure = NULL;
 deliver_localpart_parent = deliver_localpart_orig = NULL;
 deliver_domain_parent = deliver_domain_orig = NULL;
 callout_address = NULL;
index a0147d5eed1d540eb80d88638672eb2f765a8f89..4b70780bcbddb66c577bcde2a4bcf224fd63c454 100644 (file)
@@ -683,7 +683,7 @@ for (;;)
        tls_in.sni = string_unprinting(string_copy_taint(q+4, tainted));
       else if (Ustrncmp(q, "ocsp", 4) == 0)
        tls_in.ocsp = q[5] - '0';
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
       else if (Ustrncmp(q, "resumption", 10) == 0)
        tls_in.resumption = q[11] - 'A';
 # endif
index 4b6539ecd999bf2d69deaf0bb5a6ad84ab7dec1e..9a514b33134cab6c8bf7278c8f186aca5f64d279 100644 (file)
@@ -261,7 +261,7 @@ if (tls_in.ourcert)
     fprintf(fp, "-tls_ourcert %s\n", CS big_buffer);
   }
 if (tls_in.ocsp)        fprintf(fp, "-tls_ocsp %d\n",   tls_in.ocsp);
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
 fprintf(fp, "-tls_resumption %c\n", 'A' + tls_in.resumption);
 # endif
 if (tls_in.ver) spool_var_write(fp, US"tls_ver", tls_in.ver);
index aed88bc62f74337c1e585e128160c471b06d900a..657cd1771d39d028c417c3a8692f6498a814c8d2 100644 (file)
@@ -11,7 +11,7 @@
   License: GPL */
 
 #include "exim.h"
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
 
 #include <srs_alt.h>
 #include "srs.h"
index 99463de97299da816645ac77b30c54423d10ddc3..32404128f5da299fc4cba39f4d7741d9e2c79113 100644 (file)
@@ -10,7 +10,7 @@
 
 #define __SRS_H__ 1
 
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
 
 #include "mytypes.h"
 #include <srs_alt.h>
index c6700d5136803fe8aa91d5fad96cc4e02b4b3517..9aab603f86676f4bbbdf87c8cb61f560eef73afc 100644 (file)
@@ -515,7 +515,7 @@ typedef struct address_item_propagated {
   uschar *remove_headers;         /* list of those to remove */
   void   *variables;             /* router-vasriables */
 
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
   uschar *srs_sender;             /* Change return path when delivering */
 #endif
   BOOL    ignore_error:1;        /* ignore delivery error */
@@ -644,7 +644,7 @@ typedef struct address_item {
 #ifdef SUPPORT_I18N
     BOOL af_utf8_downcvt:1;            /* downconvert was done for delivery */
 #endif
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
     BOOL af_tls_resume:1;              /* TLS used a resumed session */
 #endif
   } flags;
index 24114f05e213085d4a0cbc052f878ffa5a8ad8a7..a351c34d671502076e2701c02f720b9b3b9addf4 100644 (file)
@@ -111,9 +111,11 @@ require current GnuTLS, then we'll drop support for the ancient libraries).
 # endif
 #endif
 
-#ifdef EXPERIMENTAL_TLS_RESUME
-# if GNUTLS_VERSION_NUMBER < 0x030603
-#  error GNUTLS version too early for session-resumption
+#ifndef DISABLE_TLS_RESUME
+# if GNUTLS_VERSION_NUMBER >= 0x030603
+#  define EXIM_HAVE_TLS_RESUME
+# else
+#  warning "GnuTLS library version too old; resumption unsupported"
 # endif
 #endif
 
@@ -131,7 +133,7 @@ require current GnuTLS, then we'll drop support for the ancient libraries).
 void
 options_tls(void)
 {
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
 builtin_macro_create_var(US"_RESUME_DECODE", RESUME_DECODE_STRING );
 # endif
 # ifdef EXIM_HAVE_TLS1_3
@@ -266,7 +268,7 @@ static BOOL gnutls_buggy_ocsp = FALSE;
 static BOOL exim_testharness_disable_ocsp_validity_check = FALSE;
 #endif
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifdef EXIM_HAVE_TLS_RESUME
 static gnutls_datum_t server_sessticket_key;
 #endif
 
@@ -326,7 +328,7 @@ static void exim_gnutls_logger_cb(int level, const char *message);
 
 static int exim_sni_handling_cb(gnutls_session_t session);
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifdef EXIM_HAVE_TLS_RESUME
 static int
 tls_server_ticket_cb(gnutls_session_t sess, u_int htype, unsigned when,
   unsigned incoming, const gnutls_datum_t * msg);
@@ -337,7 +339,7 @@ tls_server_ticket_cb(gnutls_session_t sess, u_int htype, unsigned when,
 void
 tls_daemon_init(void)
 {
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifdef EXIM_HAVE_TLS_RESUME
 /* We are dependent on the GnuTLS implementation of the Session Ticket
 encryption; both the strength and the key rotation period.  We hope that
 the strength at least matches that of the ciphersuite (but GnuTLS does not
@@ -1000,10 +1002,10 @@ return gnutls_ext_raw_parse(NULL, tls_server_servercerts_ext, msg, 0);
  "Handshake Protocol: Certificate" record.
 So we need to spot the Certificate handshake message, parse it and spot any status_request extension(s)
 
-This is different to tls1.2 - where it is a separate record (wireshake term) / handshake message (gnutls term).
+This is different to tls1.2 - where it is a separate record (wireshark term) / handshake message (gnutls term).
 */
 
-#if defined(EXPERIMENTAL_TLS_RESUME) || defined(SUPPORT_GNUTLS_EXT_RAW_PARSE)
+#if defined(EXIM_HAVE_TLS_RESUME) || defined(SUPPORT_GNUTLS_EXT_RAW_PARSE)
 /* Callback for certificate-status, on server. We sent stapled OCSP. */
 static int
 tls_server_certstatus_cb(gnutls_session_t session, unsigned int htype,
@@ -1035,7 +1037,7 @@ switch (htype)
 # endif
   case GNUTLS_HANDSHAKE_CERTIFICATE_STATUS:
     return tls_server_certstatus_cb(sess, htype, when, incoming, msg);
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifdef EXIM_HAVE_TLS_RESUME
   case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET:
     return tls_server_ticket_cb(sess, htype, when, incoming, msg);
 # endif
@@ -2328,7 +2330,7 @@ else
 }
 
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifdef EXIM_HAVE_TLS_RESUME
 static int
 tls_server_ticket_cb(gnutls_session_t sess, u_int htype, unsigned when,
   unsigned incoming, const gnutls_datum_t * msg)
@@ -2442,7 +2444,7 @@ DEBUG(D_tls) debug_printf("initialising GnuTLS as a server\n");
 #endif
   }
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifdef EXIM_HAVE_TLS_RESUME
 tls_server_resume_prehandshake(state);
 #endif
 
@@ -2550,7 +2552,7 @@ if (gnutls_session_get_flags(state->session) & GNUTLS_SFLAGS_EXT_MASTER_SECRET)
   tls_in.ext_master_secret = TRUE;
 #endif
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifdef EXIM_HAVE_TLS_RESUME
 tls_server_resume_posthandshake(state);
 #endif
 
@@ -2683,7 +2685,7 @@ return TRUE;
 
 
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifdef EXIM_HAVE_TLS_RESUME
 /* On the client, get any stashed session for the given IP from hints db
 and apply it to the ssl-connection for attempted resumption.  Although
 there is a gnutls_session_ticket_enable_client() interface it is
@@ -2816,7 +2818,7 @@ if (gnutls_session_is_resumed(state->session))
 
 tls_save_session(tlsp, state->session, host);
 }
-#endif /* EXPERIMENTAL_TLS_RESUME */
+#endif /* !DISABLE_TLS_RESUME */
 
 
 /*************************************************
@@ -2970,7 +2972,7 @@ if (request_ocsp)
   }
 #endif
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifdef EXIM_HAVE_TLS_RESUME
 tls_client_resume_prehandshake(state, tlsp, host, ob);
 #endif
 
@@ -3070,7 +3072,7 @@ if (request_ocsp)
   }
 #endif
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifdef EXIM_HAVE_TLS_RESUME
 tls_client_resume_posthandshake(state, tlsp, host);
 #endif
 
index 8c9d8aa69fe8780645ea36f7865b02b83639df66..a1d299b69d39fc7827d9a5a25e7c422e01254f2b 100644 (file)
@@ -116,7 +116,7 @@ change this guard and punt the issue for a while longer. */
 # define DISABLE_OCSP
 #endif
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
 # if OPENSSL_VERSION_NUMBER < 0x0101010L
 #  error OpenSSL version too old for session-resumption
 # endif
@@ -292,7 +292,7 @@ for (struct exim_openssl_option * o = exim_openssl_options;
   builtin_macro_create(buf);
   }
 
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
 builtin_macro_create_var(US"_RESUME_DECODE", RESUME_DECODE_STRING );
 # endif
 # ifdef SSL_OP_NO_TLSv1_3
@@ -422,7 +422,7 @@ static int tls_server_stapling_cb(SSL *s, void *arg);
 
 
 /* Daemon-called, before every connection, key create/rotate */
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
 static void tk_init(void);
 static int tls_exdata_idx = -1;
 #endif
@@ -430,7 +430,7 @@ static int tls_exdata_idx = -1;
 void
 tls_daemon_init(void)
 {
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
 tk_init();
 #endif
 return;
@@ -891,7 +891,7 @@ fclose(fp);
 #endif
 
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
 /* Manage the keysets used for encrypting the session tickets, on the server. */
 
 typedef struct {                       /* Session ticket encryption key */
@@ -2176,12 +2176,12 @@ availability of the option value macros from OpenSSL.  */
 if (!tls_openssl_options_parse(openssl_options, &init_options))
   return tls_error(US"openssl_options parsing failed", host, NULL, errstr);
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
 tlsp->resumption = RESUME_SUPPORTED;
 #endif
 if (init_options)
   {
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
   /* Should the server offer session resumption? */
   if (!host && verify_check_host(&tls_resumption_hosts) == OK)
     {
@@ -2685,12 +2685,12 @@ else if (verify_check_host(&tls_try_verify_hosts) == OK)
   server_verify_optional = TRUE;
   }
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, ticket_key_callback);
 /* despite working, appears to always return failure, so ignoring */
 #endif
 #ifdef OPENSSL_HAVE_NUM_TICKETS
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
 SSL_CTX_set_num_tickets(server_ctx, tls_in.host_resumable ? 1 : 0);
 # else
 SSL_CTX_set_num_tickets(server_ctx, 0);        /* send no TLS1.3 stateful-tickets */
@@ -2796,7 +2796,7 @@ DEBUG(D_tls) debug_printf("SSL_accept was successful\n");
 ERR_clear_error();     /* Even success can leave errors in the stack. Seen with
                        anon-authentication ciphersuite negotiated. */
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
 if (SSL_session_reused(server_ssl))
   {
   tls_in.resumption |= RESUME_USED;
@@ -2983,7 +2983,7 @@ return DEFER;
 
 
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
 /* On the client, get any stashed session for the given IP from hints db
 and apply it to the ssl-connection for attempted resumption. */
 
@@ -3145,7 +3145,7 @@ if (SSL_session_reused(exim_client_ctx->ssl))
   tlsp->resumption |= RESUME_USED;
   }
 }
-#endif /* EXPERIMENTAL_TLS_RESUME */
+#endif /* !DISABLE_TLS_RESUME */
 
 
 /*************************************************
@@ -3294,7 +3294,7 @@ else
        client_static_cbinfo, errstr) != OK)
     return FALSE;
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
 tls_client_ctx_resume_prehandshake(exim_client_ctx, tlsp, ob, host);
 #endif
 
@@ -3365,7 +3365,7 @@ if (request_ocsp)
   }
 #endif
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
 if (!tls_client_ssl_resume_prehandshake(exim_client_ctx->ssl, tlsp, host,
       errstr))
   return FALSE;
@@ -3406,7 +3406,7 @@ DEBUG(D_tls)
 #endif
   }
 
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
 tls_client_resume_posthandshake(exim_client_ctx, tlsp);
 #endif
 
index 2d8426f297acfadfe03dfe432e826ddc8261c77e..f9ff521f78f5208429650d12f337e0f6345bb43c 100644 (file)
@@ -1571,7 +1571,7 @@ for (host_item * host = hostlist; host; host = host->next)
     {
     sprintf(CS buffer, "%.200s:%d", host->name, host_record->sequence);
     dbfn_write(dbm_file, buffer, host_record, sizeof(dbdata_wait) + host_length);
-#ifdef EXPERIMENTAL_QUEUE_RAMP
+#ifndef DISABLE_QUEUE_RAMP
     if (f.queue_2stage && queue_fast_ramp && !queue_run_in_order)
       queue_notify_daemon(message_id);
 #endif
index f96d001825aa5fc5ff94d97ccb10cd3d2319fd21..c8c0a58b6d3236517da3d336f29cac19483b2dfd 100644 (file)
@@ -2287,14 +2287,14 @@ else
         {
         uschar *new_check_path = string_copy(check_path);
         uschar *slash = Ustrrchr(new_check_path, '/');
-        if (slash != NULL)
+        if (slash)
           {
-          if (slash[1] == 0)
+          if (!slash[1])
             {
             *slash = 0;
             slash = Ustrrchr(new_check_path, '/');
             }
-          if (slash != NULL)
+          if (slash)
             {
             *slash = 0;
             check_path = new_check_path;
@@ -2349,7 +2349,7 @@ else
         {
         uschar *s = path + check_path_len;
         while (*s == '/') s++;
-        s = (*s == 0) ? US "new" : string_sprintf("%s/new", s);
+        s = *s ? string_sprintf("%s/new", s) : US"new";
         if (pcre_exec(dir_regex, NULL, CS s, Ustrlen(s), 0, 0, NULL, 0) < 0)
           {
           disable_quota = TRUE;
@@ -2408,10 +2408,11 @@ else
   count. Note that ob->quota_filecount_value cannot be set without
   ob->quota_value being set. */
 
-  if (!disable_quota &&
-      (ob->quota_value > 0 || THRESHOLD_CHECK) &&
-      (mailbox_size < 0 ||
-        (mailbox_filecount < 0 && ob->quota_filecount_value > 0)))
+  if (  !disable_quota
+     && (ob->quota_value > 0 || THRESHOLD_CHECK)
+     && (  mailbox_size < 0
+       || mailbox_filecount < 0 && ob->quota_filecount_value > 0
+    )   )
     {
     off_t size;
     int filecount = 0;
@@ -2484,7 +2485,7 @@ else
       uschar *basename;
 
       (void)gettimeofday(&msg_tv, NULL);
-      basename = string_sprintf(TIME_T_FMT ".H%luP" PID_T_FMT ".%s",
+      basename = string_sprintf(TIME_T_FMT ".M%luP" PID_T_FMT ".%s",
                msg_tv.tv_sec, msg_tv.tv_usec, getpid(), primary_hostname);
 
       filename = dataname = string_sprintf("tmp/%s", basename);
@@ -2556,11 +2557,12 @@ else
     dataname = string_sprintf("%s.msg", mailstore_basename);
 
     fd = Uopen(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
-    if (fd < 0 &&                                 /* failed to open, and */
-        (errno != ENOENT ||                       /* either not non-exist */
-         !ob->create_directory ||                 /* or not allowed to make */
-         !directory_make(NULL, path, ob->dirmode, FALSE) ||  /* or failed to create dir */
-         (fd = Uopen(filename, O_WRONLY|O_CREAT|O_EXCL, mode)) < 0)) /* or then failed to open */
+    if (  fd < 0                               /* failed to open, and */
+       && (   errno != ENOENT                  /* either not non-exist */
+         || !ob->create_directory              /* or not allowed to make */
+         || !directory_make(NULL, path, ob->dirmode, FALSE)  /* or failed to create dir */
+         || (fd = Uopen(filename, O_WRONLY|O_CREAT|O_EXCL, mode)) < 0 /* or then failed to open */
+       )  )
       {
       addr->basic_errno = errno;
       addr->message = string_sprintf("while creating file %s", filename);
@@ -2739,6 +2741,18 @@ if (!disable_quota && ob->quota_value > 0)
 
   }
 
+if (verify_mode)
+  {
+  addr->basic_errno = errno;
+  addr->message = US"Over quota";
+  addr->transport_return = yield;
+  DEBUG(D_transport)
+    debug_printf("appendfile (verify) yields %d with errno=%d more_errno=%d\n",
+      yield, addr->basic_errno, addr->more_errno);
+
+  goto RETURN;
+  }
+
 /* If we are writing in MBX format, what we actually do is to write the message
 to a temporary file, and then copy it to the real file once we know its size.
 This is the most straightforward way of getting the correct length in the
index 8492a7f25b815be1546bc1ba39aa7adb793ebde4..3d41a6767413df71fe04c91110f3d916a0d55dfe 100644 (file)
@@ -111,6 +111,7 @@ optionlist smtp_transport_options[] = {
   { "lmtp_ignore_quota",    opt_bool,     LOFF(lmtp_ignore_quota) },
   { "max_rcpt",             opt_int | opt_public,
       OPT_OFF(transport_instance, max_addresses) },
+  { "message_linelength_limit", opt_int,   LOFF(message_linelength_limit) },
   { "multi_domain",         opt_expand_bool | opt_public,
       OPT_OFF(transport_instance, multi_domain) },
   { "port",                 opt_stringptr, LOFF(port) },
@@ -127,7 +128,7 @@ optionlist smtp_transport_options[] = {
   { "tls_dh_min_bits",      opt_int,      LOFF(tls_dh_min_bits) },
   { "tls_privatekey",       opt_stringptr, LOFF(tls_privatekey) },
   { "tls_require_ciphers",  opt_stringptr, LOFF(tls_require_ciphers) },
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
   { "tls_resumption_hosts", opt_stringptr, LOFF(tls_resumption_hosts) },
 # endif
   { "tls_sni",              opt_stringptr, LOFF(tls_sni) },
@@ -207,6 +208,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   .size_addition =             1024,
   .hosts_max_try =             5,
   .hosts_max_try_hardlimit =   50,
+  .message_linelength_limit =  998,
   .address_retry_include_sender = TRUE,
   .allow_localhost =           FALSE,
   .authenticated_sender_force =        FALSE,
@@ -233,7 +235,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   .tls_verify_certificates =   US"system",
   .tls_dh_min_bits =           EXIM_CLIENT_DH_DEFAULT_MIN_BITS,
   .tls_tempfail_tryclear =     TRUE,
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
   .tls_resumption_hosts =      NULL,
 # endif
   .tls_verify_hosts =          NULL,
@@ -1970,7 +1972,7 @@ tls_out.peerdn = NULL;
 tls_out.sni = NULL;
 #endif
 tls_out.ocsp = OCSP_NOT_REQ;
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
 tls_out.resumption = 0;
 #endif
 tls_out.ver = NULL;
@@ -4524,6 +4526,22 @@ DEBUG(D_transport)
       cutthrough.cctx.sock >= 0 ? cutthrough.cctx.sock : 0);
   }
 
+/* Check the restrictions on line length */
+
+if (max_received_linelength > ob->message_linelength_limit)
+  {
+  struct timeval now;
+  gettimeofday(&now, NULL);
+
+  for (address_item * addr = addrlist; addr; addr = addr->next)
+    if (addr->transport_return == DEFER)
+      addr->transport_return = PENDING_DEFER;
+
+  set_errno_nohost(addrlist, ERRNO_SMTPFORMAT,
+    US"message has lines too long for transport", FAIL, TRUE, &now);
+  goto END_TRANSPORT;
+  }
+
 /* Set the flag requesting that these hosts be added to the waiting
 database if the delivery fails temporarily or if we are running with
 queue_smtp or a 2-stage queue run. This gets unset for certain
index 6e63a002d93468f09602be0bb75c4d0f927e6e11..607a3772dddc8a3d768ba7a500eaeb4923d54952 100644 (file)
@@ -62,6 +62,7 @@ typedef struct {
   int     size_addition;
   int     hosts_max_try;
   int     hosts_max_try_hardlimit;
+  int    message_linelength_limit;
   BOOL    address_retry_include_sender;
   BOOL    allow_localhost;
   BOOL    authenticated_sender_force;
@@ -84,7 +85,7 @@ typedef struct {
   uschar *tls_crl;
   uschar *tls_privatekey;
   uschar *tls_require_ciphers;
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
   uschar *tls_resumption_hosts;
 # endif
   uschar *tls_sni;
index fba1f6e9e0a96d80c447a9201bddc00ad563cc38..3a40cea268d5d5a6f511af29ffe5d830263ac8a8 100644 (file)
@@ -71,7 +71,7 @@ dbdata_callout_cache *cache_record;
 
 if (!(cache_record = dbfn_read_with_length(dbm_file, key, &length)))
   {
-  HDEBUG(D_verify) debug_printf("callout cache: no %s record found for %s\n", type, key);
+  HDEBUG(D_verify) debug_printf_indent("callout cache: no %s record found for %s\n", type, key);
   return NULL;
   }
 
@@ -85,7 +85,7 @@ now = time(NULL);
 
 if (now - cache_record->time_stamp > expire)
   {
-  HDEBUG(D_verify) debug_printf("callout cache: %s record expired for %s\n", type, key);
+  HDEBUG(D_verify) debug_printf_indent("callout cache: %s record expired for %s\n", type, key);
   return NULL;
   }
 
@@ -112,7 +112,7 @@ if (type[0] == 'd' && cache_record->result != ccache_reject)
     cache_record->random_result = ccache_unknown;
   }
 
-HDEBUG(D_verify) debug_printf("callout cache: found %s record for %s\n", type, key);
+HDEBUG(D_verify) debug_printf_indent("callout cache: found %s record for %s\n", type, key);
 return cache_record;
 }
 
@@ -139,11 +139,11 @@ stage, unless caching has been disabled. */
 
 if (options & vopt_callout_no_cache)
   {
-  HDEBUG(D_verify) debug_printf("callout cache: disabled by no_cache\n");
+  HDEBUG(D_verify) debug_printf_indent("callout cache: disabled by no_cache\n");
   }
 else if (!(dbm_file = dbfn_open(US"callout", O_RDWR, &dbblock, FALSE, TRUE)))
   {
-  HDEBUG(D_verify) debug_printf("callout cache: not available\n");
+  HDEBUG(D_verify) debug_printf_indent("callout cache: not available\n");
   }
 else
   {
@@ -174,7 +174,7 @@ else
        || *from_address == 0 && cache_record->result == ccache_reject_mfnull)
       {
       HDEBUG(D_verify)
-       debug_printf("callout cache: domain gave initial rejection, or "
+       debug_printf_indent("callout cache: domain gave initial rejection, or "
          "does not accept HELO or MAIL FROM:<>\n");
       setflag(addr, af_verify_nsfail);
       addr->user_message = US"(result of an earlier callout reused).";
@@ -195,14 +195,14 @@ else
       {
       case ccache_accept:
        HDEBUG(D_verify)
-         debug_printf("callout cache: domain accepts random addresses\n");
+         debug_printf_indent("callout cache: domain accepts random addresses\n");
        *failure_ptr = US"random";
        dbfn_close(dbm_file);
        return TRUE;     /* Default yield is OK */
 
       case ccache_reject:
        HDEBUG(D_verify)
-         debug_printf("callout cache: domain rejects random addresses\n");
+         debug_printf_indent("callout cache: domain rejects random addresses\n");
        *opt_ptr = options & ~vopt_callout_random;
        new_domain_record->random_result = ccache_reject;
        new_domain_record->random_stamp = cache_record->random_stamp;
@@ -210,7 +210,7 @@ else
 
       default:
        HDEBUG(D_verify)
-         debug_printf("callout cache: need to check random address handling "
+         debug_printf_indent("callout cache: need to check random address handling "
            "(not cached or cache expired)\n");
        dbfn_close(dbm_file);
        return FALSE;
@@ -227,7 +227,7 @@ else
        {
        setflag(addr, af_verify_pmfail);
        HDEBUG(D_verify)
-         debug_printf("callout cache: domain does not accept "
+         debug_printf_indent("callout cache: domain does not accept "
            "RCPT TO:<postmaster@domain>\n");
        *yield = FAIL;
        *failure_ptr = US"postmaster";
@@ -239,7 +239,7 @@ else
       if (cache_record->postmaster_result == ccache_unknown)
        {
        HDEBUG(D_verify)
-         debug_printf("callout cache: need to check RCPT "
+         debug_printf_indent("callout cache: need to check RCPT "
            "TO:<postmaster@domain> (not cached or cache expired)\n");
        dbfn_close(dbm_file);
        return FALSE;
@@ -250,7 +250,7 @@ else
       that the value in the cache record is preserved (with its old timestamp).
       */
 
-      HDEBUG(D_verify) debug_printf("callout cache: domain accepts RCPT "
+      HDEBUG(D_verify) debug_printf_indent("callout cache: domain accepts RCPT "
        "TO:<postmaster@domain>\n");
       *pm_ptr = NULL;
       new_domain_record->postmaster_result = ccache_accept;
@@ -274,12 +274,12 @@ else
   if (cache_address_record->result == ccache_accept)
     {
     HDEBUG(D_verify)
-      debug_printf("callout cache: address record is positive\n");
+      debug_printf_indent("callout cache: address record is positive\n");
     }
   else
     {
     HDEBUG(D_verify)
-      debug_printf("callout cache: address record is negative\n");
+      debug_printf_indent("callout cache: address record is negative\n");
     addr->user_message = US"Previous (cached) callout verification failure";
     *failure_ptr = US"recipient";
     *yield = FAIL;
@@ -316,13 +316,13 @@ Otherwise the value is ccache_accept, ccache_reject, or ccache_reject_mfnull. */
 if (dom_rec->result != ccache_unknown)
   if (!(dbm_file = dbfn_open(US"callout", O_RDWR|O_CREAT, &dbblock, FALSE, TRUE)))
     {
-    HDEBUG(D_verify) debug_printf("callout cache: not available\n");
+    HDEBUG(D_verify) debug_printf_indent("callout cache: not available\n");
     }
   else
     {
     (void)dbfn_write(dbm_file, domain, dom_rec,
       (int)sizeof(dbdata_callout_cache));
-    HDEBUG(D_verify) debug_printf("wrote callout cache domain record for %s:\n"
+    HDEBUG(D_verify) debug_printf_indent("wrote callout cache domain record for %s:\n"
       "  result=%d postmaster=%d random=%d\n",
       domain,
       dom_rec->result,
@@ -339,13 +339,13 @@ if (done  &&  addr_rec->result != ccache_unknown)
     dbm_file = dbfn_open(US"callout", O_RDWR|O_CREAT, &dbblock, FALSE, TRUE);
   if (!dbm_file)
     {
-    HDEBUG(D_verify) debug_printf("no callout cache available\n");
+    HDEBUG(D_verify) debug_printf_indent("no callout cache available\n");
     }
   else
     {
     (void)dbfn_write(dbm_file, address_key, addr_rec,
       (int)sizeof(dbdata_callout_cache_address));
-    HDEBUG(D_verify) debug_printf("wrote %s callout cache address record for %s\n",
+    HDEBUG(D_verify) debug_printf_indent("wrote %s callout cache address record for %s\n",
       addr_rec->result == ccache_accept ? "positive" : "negative",
       address_key);
     }
@@ -568,6 +568,7 @@ if (!addr->transport)
   {
   HDEBUG(D_verify) debug_printf("cannot callout via null transport\n");
   }
+
 else if (Ustrcmp(addr->transport->driver_name, "smtp") != 0)
   log_write(0, LOG_MAIN|LOG_PANIC|LOG_CONFIG_FOR, "callout transport '%s': %s is non-smtp",
     addr->transport->name, addr->transport->driver_name);
@@ -1612,7 +1613,7 @@ address testing (-bt), which is indicated by address_test_mode being set.
 Arguments:
   vaddr            contains the address to verify; the next field in this block
                      must be NULL
-  f                if not NULL, write the result to this file
+  fp               if not NULL, write the result to this file
   options          various option bits:
                      vopt_fake_sender => this sender verify is not for the real
                        sender (it was verify=sender=xxxx or an address from a
@@ -1663,9 +1664,9 @@ BOOL expn         = (options & vopt_expn) != 0;
 BOOL success_on_redirect = (options & vopt_success_on_redirect) != 0;
 int i;
 int yield = OK;
-int verify_type = expn? v_expn :
-   f.address_test_mode? v_none :
-          options & vopt_is_recipient? v_recipient : v_sender;
+int verify_type = expn ? v_expn :
+   f.address_test_mode ? v_none :
+          options & vopt_is_recipient ? v_recipient : v_sender;
 address_item *addr_list;
 address_item *addr_new = NULL;
 address_item *addr_remote = NULL;
@@ -1846,6 +1847,8 @@ while (addr_new)
 
   if (rc == OK)
     {
+    BOOL local_verify = FALSE;
+
     if (routed) *routed = TRUE;
     if (callout > 0)
       {
@@ -1872,72 +1875,76 @@ while (addr_new)
       transport's options, so as to mimic what would happen if we were really
       sending a message to this address. */
 
-      if ((tp = addr->transport) && !tp->info->local)
-        {
-        (void)(tp->setup)(tp, addr, &tf, 0, 0, NULL);
+      if ((tp = addr->transport))
+       if (!tp->info->local)
+         {
+         (void)(tp->setup)(tp, addr, &tf, 0, 0, NULL);
 
-        /* If the transport has hosts and the router does not, or if the
-        transport is configured to override the router's hosts, we must build a
-        host list of the transport's hosts, and find the IP addresses */
+         /* If the transport has hosts and the router does not, or if the
+         transport is configured to override the router's hosts, we must build a
+         host list of the transport's hosts, and find the IP addresses */
 
-        if (tf.hosts && (!host_list || tf.hosts_override))
-          {
-          uschar *s;
-          const uschar *save_deliver_domain = deliver_domain;
-          uschar *save_deliver_localpart = deliver_localpart;
-
-          host_list = NULL;    /* Ignore the router's hosts */
-
-          deliver_domain = addr->domain;
-          deliver_localpart = addr->local_part;
-          s = expand_string(tf.hosts);
-          deliver_domain = save_deliver_domain;
-          deliver_localpart = save_deliver_localpart;
-
-          if (!s)
-            {
-            log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand list of hosts "
-              "\"%s\" in %s transport for callout: %s", tf.hosts,
-              tp->name, expand_string_message);
-            }
-          else
-            {
-            int flags;
-            host_build_hostlist(&host_list, s, tf.hosts_randomize);
-
-            /* Just ignore failures to find a host address. If we don't manage
-            to find any addresses, the callout will defer. Note that more than
-            one address may be found for a single host, which will result in
-            additional host items being inserted into the chain. Hence we must
-            save the next host first. */
-
-            flags = HOST_FIND_BY_A | HOST_FIND_BY_AAAA;
-            if (tf.qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE;
-            if (tf.search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
-
-            for (host_item * host = host_list, * nexthost; host; host = nexthost)
-              {
-              nexthost = host->next;
-              if (tf.gethostbyname ||
-                  string_is_ip_address(host->name, NULL) != 0)
-                (void)host_find_byname(host, NULL, flags, NULL, TRUE);
-              else
+         if (tf.hosts && (!host_list || tf.hosts_override))
+           {
+           uschar *s;
+           const uschar *save_deliver_domain = deliver_domain;
+           uschar *save_deliver_localpart = deliver_localpart;
+
+           host_list = NULL;    /* Ignore the router's hosts */
+
+           deliver_domain = addr->domain;
+           deliver_localpart = addr->local_part;
+           s = expand_string(tf.hosts);
+           deliver_domain = save_deliver_domain;
+           deliver_localpart = save_deliver_localpart;
+
+           if (!s)
+             {
+             log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand list of hosts "
+               "\"%s\" in %s transport for callout: %s", tf.hosts,
+               tp->name, expand_string_message);
+             }
+           else
+             {
+             int flags;
+             host_build_hostlist(&host_list, s, tf.hosts_randomize);
+
+             /* Just ignore failures to find a host address. If we don't manage
+             to find any addresses, the callout will defer. Note that more than
+             one address may be found for a single host, which will result in
+             additional host items being inserted into the chain. Hence we must
+             save the next host first. */
+
+             flags = HOST_FIND_BY_A | HOST_FIND_BY_AAAA;
+             if (tf.qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE;
+             if (tf.search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
+
+             for (host_item * host = host_list, * nexthost; host; host = nexthost)
                {
-               const dnssec_domains * dsp = NULL;
-               if (Ustrcmp(tp->driver_name, "smtp") == 0)
+               nexthost = host->next;
+               if (tf.gethostbyname ||
+                   string_is_ip_address(host->name, NULL) != 0)
+                 (void)host_find_byname(host, NULL, flags, NULL, TRUE);
+               else
                  {
-                 smtp_transport_options_block * ob =
-                     (smtp_transport_options_block *) tp->options_block;
-                 dsp = &ob->dnssec;
-                 }
+                 const dnssec_domains * dsp = NULL;
+                 if (Ustrcmp(tp->driver_name, "smtp") == 0)
+                   {
+                   smtp_transport_options_block * ob =
+                       (smtp_transport_options_block *) tp->options_block;
+                   dsp = &ob->dnssec;
+                   }
 
-                (void) host_find_bydns(host, NULL, flags, NULL, NULL, NULL,
-                 dsp, NULL, NULL);
+                 (void) host_find_bydns(host, NULL, flags, NULL, NULL, NULL,
+                   dsp, NULL, NULL);
+                 }
                }
-              }
-            }
-          }
-        }
+             }
+           }
+         }
+       else if (  options & vopt_quota
+               && Ustrcmp(tp->driver_name, "appendfile") == 0)
+         local_verify = TRUE;
 
       /* Can only do a callout if we have at least one host! If the callout
       fails, it will have set ${sender,recipient}_verify_failure. */
@@ -1963,11 +1970,17 @@ while (addr_new)
 #endif
           }
         }
+      else if (local_verify)
+       {
+        HDEBUG(D_verify) debug_printf("Attempting quota verification\n");
+
+       deliver_set_expansions(addr);
+       deliver_local(addr, TRUE);
+       rc = addr->transport_return;
+       }
       else
-        {
         HDEBUG(D_verify) debug_printf("Cannot do callout: neither router nor "
           "transport provided a host list, or transport is not smtp\n");
-        }
       }
     }
 
@@ -2156,7 +2169,7 @@ for (addr_list = addr_local, i = 0; i < 2; addr_list = addr_remote, i++)
     addr_list = addr->next;
 
     fprintf(fp, "%s", CS addr->address);
-#ifdef EXPERIMENTAL_SRS
+#ifdef EXPERIMENTAL_SRS_ALT
     if(addr->prop.srs_sender)
       fprintf(fp, "    [srs = %s]", addr->prop.srs_sender);
 #endif
@@ -3919,6 +3932,246 @@ while ((domain = string_nextinlist(&list, &sep, NULL, 0)))
 return FAIL;
 }
 
+
+
+/****************************************************
+  Verify a local user account for quota sufficiency
+****************************************************/
+
+/* The real work, done via a re-exec for privs, calls
+down to the transport for the quota check.
+
+Route and transport (in recipient-verify mode) the
+given recipient. 
+
+A routing result indicating any transport type other than appendfile
+results in a fail.
+
+Return, on stdout, a result string containing:
+- highlevel result code (OK, DEFER, FAIL)
+- errno
+- where string
+- message string
+*/
+
+void
+verify_quota(uschar * address)
+{
+address_item vaddr = {.address = address};
+BOOL routed;
+uschar * msg = US"\0";
+int rc, len = 1;
+
+if ((rc = verify_address(&vaddr, NULL, vopt_is_recipient | vopt_quota,
+    1, 0, 0, NULL, NULL, &routed)) != OK)
+  {
+  uschar * where = recipient_verify_failure;
+  msg = acl_verify_message ? acl_verify_message : vaddr.message;
+  if (!msg) msg = US"";
+  if (rc == DEFER && vaddr.basic_errno == ERRNO_EXIMQUOTA)
+    {
+    rc = FAIL;                                 /* DEFER -> FAIL */
+    where = US"quota";
+    vaddr.basic_errno = 0;
+    }
+  else if (!where) where = US"";
+
+  len = 5 + Ustrlen(msg) + 1 + Ustrlen(where);
+  msg = string_sprintf("%c%c%c%c%c%s%c%s", (uschar)rc,
+    (vaddr.basic_errno >> 24) && 0xff, (vaddr.basic_errno >> 16) && 0xff,
+    (vaddr.basic_errno >> 8) && 0xff, vaddr.basic_errno && 0xff,
+    where, '\0', msg);
+  }
+
+DEBUG(D_verify) debug_printf_indent("verify_quota: len %d\n", len);
+write(1, msg, len);
+return;
+}
+
+
+/******************************************************************************/
+
+/* Quota cache lookup.  We use the callout hints db also for the quota cache.
+Return TRUE if a nonexpired record was found, having filled in the yield
+argument.
+*/
+
+static BOOL
+cached_quota_lookup(const uschar * rcpt, int * yield,
+  int pos_cache, int neg_cache)
+{
+open_db dbblock, *dbm_file = NULL;
+dbdata_callout_cache_address * cache_address_record;
+
+if (!pos_cache && !neg_cache)
+  return FALSE;
+if (!(dbm_file = dbfn_open(US"callout", O_RDWR, &dbblock, FALSE, TRUE)))
+  {
+  HDEBUG(D_verify) debug_printf_indent("quota cache: not available\n");
+  return FALSE;
+  }
+if (!(cache_address_record = (dbdata_callout_cache_address *)
+    get_callout_cache_record(dbm_file, rcpt, US"address",
+      pos_cache, neg_cache)))
+  {
+  dbfn_close(dbm_file);
+  return FALSE;
+  }
+if (cache_address_record->result == ccache_accept)
+  *yield = OK;
+dbfn_close(dbm_file);
+return TRUE;
+}
+
+/* Quota cache write */
+
+static void
+cache_quota_write(const uschar * rcpt, int yield, int pos_cache, int neg_cache)
+{
+open_db dbblock, *dbm_file = NULL;
+dbdata_callout_cache_address cache_address_record;
+
+if (!pos_cache && !neg_cache)
+  return;
+if (!(dbm_file = dbfn_open(US"callout", O_RDWR|O_CREAT, &dbblock, FALSE, TRUE)))
+  {
+  HDEBUG(D_verify) debug_printf_indent("quota cache: not available\n");
+  return;
+  }
+
+cache_address_record.result = yield == OK ? ccache_accept : ccache_reject;
+
+(void)dbfn_write(dbm_file, rcpt, &cache_address_record,
+       (int)sizeof(dbdata_callout_cache_address));
+HDEBUG(D_verify) debug_printf_indent("wrote %s quota cache record for %s\n",
+      yield == OK ? "positive" : "negative", rcpt);
+
+dbfn_close(dbm_file);
+return;
+}
+
+
+/* To evaluate a local user's quota, starting in ACL, we need to
+fork & exec to regain privileges, to that we can change to the user's
+identity for access to their files.
+
+Arguments:
+ rcpt          Recipient account
+ pos_cache     Number of seconds to cache a positive result (delivery
+               to be accepted).  Zero to disable caching.
+ neg_cache     Number of seconds to cache a negative result.  Zero to disable.
+ msg           Pointer to result string pointer
+
+Return:                OK/DEFER/FAIL code
+*/
+
+int
+verify_quota_call(const uschar * rcpt, int pos_cache, int neg_cache,
+  uschar ** msg)
+{
+int pfd[2], pid, save_errno, yield = FAIL;
+void (*oldsignal)(int);
+const uschar * where = US"socketpair";
+
+*msg = NULL;
+
+if (cached_quota_lookup(rcpt, &yield, pos_cache, neg_cache))
+  {
+  HDEBUG(D_verify) debug_printf_indent("quota cache: address record is %d\n",
+    yield == OK ? "positive" : "negative");
+  if (yield != OK)
+    {
+    recipient_verify_failure = US"quota";
+    acl_verify_message = *msg =
+      US"Previous (cached) quota verification failure";
+    }
+  return yield;
+  }
+
+if (pipe(pfd) != 0)
+  goto fail;
+
+where = US"fork";
+oldsignal = signal(SIGCHLD, SIG_DFL);
+if ((pid = exim_fork(US"quota-verify")) < 0)
+  {
+  save_errno = errno;
+  close(pfd[pipe_write]);
+  close(pfd[pipe_read]);
+  errno = save_errno;
+  goto fail;
+  }
+
+if (pid == 0)          /* child */
+  {
+  close(pfd[pipe_read]);
+  force_fd(pfd[pipe_write], 1);                /* stdout to pipe */
+  close(pfd[pipe_write]);
+  dup2(1, 0);
+  if (debug_fd > 0) force_fd(debug_fd, 2);
+
+  child_exec_exim(CEE_EXEC_EXIT, FALSE, NULL, FALSE, 3,
+    US"-MCq", string_sprintf("%d", message_size), rcpt);
+  /*NOTREACHED*/
+  }
+
+save_errno = errno;
+close(pfd[pipe_write]);
+
+if (pid < 0)
+  {
+  DEBUG(D_verify) debug_printf_indent(" fork: %s\n", strerror(save_errno));
+  }
+else
+  {
+  uschar buf[128];
+  int n = read(pfd[pipe_read], buf, sizeof(buf));
+  int status;
+
+  waitpid(pid, &status, 0);
+  if (status == 0)
+    {
+    uschar * s;
+
+    if (n > 0) yield = buf[0];
+    if (n > 4)
+      save_errno = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
+    if ((recipient_verify_failure = n > 5
+       ? string_copyn_taint(buf+5, n-5, FALSE) : NULL))
+      {
+      int m;
+      s = buf + 5 + Ustrlen(recipient_verify_failure) + 1;
+      m = n - (s - buf);
+      acl_verify_message = *msg =
+       m > 0 ? string_copyn_taint(s, m, FALSE) : NULL;
+      }
+
+    DEBUG(D_verify) debug_printf_indent("verify call response:"
+      " len %d yield %s errno '%s' where '%s' msg '%s'\n",
+      n, rc_names[yield], strerror(save_errno), recipient_verify_failure, *msg);
+
+    if (  yield == OK
+       || save_errno == 0 && Ustrcmp(recipient_verify_failure, "quota") == 0)
+      cache_quota_write(rcpt, yield, pos_cache, neg_cache);
+    else DEBUG(D_verify)
+      debug_printf_indent("result not cacheable\n");
+    }
+  else
+    {
+    DEBUG(D_verify)
+      debug_printf_indent("verify call response: waitpid status 0x%04x\n", status);
+    }
+  }
+
+close(pfd[pipe_read]);
+errno = save_errno;
+
+fail:
+
+return yield;
+}
+
+
 /* vi: aw ai sw=2
 */
 /* End of verify.c */
diff --git a/test/confs/0588 b/test/confs/0588
new file mode 100644 (file)
index 0000000..9a88c9c
--- /dev/null
@@ -0,0 +1,42 @@
+# Exim test configuration 0588
+
+.include DIR/aux-var/std_conf_prefix
+
+log_selector = +received_recipients +sender_on_delivery +millisec
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = accept
+
+# ----- Routers -----
+
+begin routers
+
+rx_dump:
+  driver =     redirect
+  condition =  ${if !eq {$received_ip_address}{127.0.0.1}}
+  data =       :blackhole:
+
+smtp_try:
+  driver =     accept
+  transport =  send_to_server
+
+# ----- Transports -----
+
+begin transports
+
+send_to_server:
+  driver = smtp
+  hosts = HOSTIPV4
+  allow_localhost
+  port = PORT_D
+  hosts_try_fastopen = :
+
+# ----- Retry -----
+
+begin retry
+
+* * F,5d,10s
+
+# End
+
diff --git a/test/confs/0589 b/test/confs/0589
new file mode 100644 (file)
index 0000000..b0f7311
--- /dev/null
@@ -0,0 +1,60 @@
+# Exim test configuration 0589
+
+.include DIR/aux-var/std_conf_prefix
+
+primary_hostname = myhost.test.ex
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = chk_rcpt
+log_selector = +millisec
+
+# --- ACL ---
+
+begin acl
+
+chk_rcpt:
+  deny         !verify = recipient/quota=cachepos=20s,cacheneg=100s
+               logwrite = where='$recipient_verify_failure' msg='$acl_verify_message'
+  accept
+
+loggit:
+  accept       logwrite = $acl_arg1 was called for $local_part@$domain
+               message = /
+
+# ----- Routers -----
+
+begin routers
+
+localuser:
+  driver =     accept
+  local_parts =        !route_fail
+  transport =  appendfile
+  # set address_data purely to get logging of use of the router
+  address_data = ${acl {loggit}{router   }}
+
+failrouter:
+  driver =     accept
+  condition =  ${if eq {${acl {loggit}{router   }}}{} {no}{no}}
+  transport =  appendfile
+
+# ----- Transports -----
+
+begin transports
+
+appendfile:
+  driver =     appendfile
+  file =       DIR/test-mail/themailfile
+  quota =      1k
+  user =       CALLER
+  # set homedir purely to get logging of use of the transport
+  home_directory = ${acl {loggit}{transport}}
+
+# ----- Retry -----
+
+begin retry
+
+* * F,5d,1d
+
+
+# End
diff --git a/test/log/0588 b/test/log/0588
new file mode 100644 (file)
index 0000000..9446451
--- /dev/null
@@ -0,0 +1,15 @@
+
+******** SERVER ********
+2017-07-30 18:51:05.712 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+2017-07-30 18:51:05.712 10HmaX-0005vi-00 <= CALLER@test.ex H=(test) [127.0.0.1] P=smtp S=sss for good@test.ex
+2017-07-30 18:51:05.712 10HmaY-0005vi-00 <= CALLER@test.ex H=(test) [127.0.0.1] P=smtp S=sss for bad@test.ex
+2017-07-30 18:51:05.712 10HmaZ-0005vi-00 <= CALLER@test.ex H=the.local.host.name [ip4.ip4.ip4.ip4] P=esmtp S=sss for good@test.ex
+2017-07-30 18:51:05.712 10HmaZ-0005vi-00 => :blackhole: <good@test.ex> R=rx_dump
+2017-07-30 18:51:05.712 10HmaZ-0005vi-00 Completed
+2017-07-30 18:51:05.712 10HmaX-0005vi-00 => good@test.ex F=<CALLER@test.ex> R=smtp_try T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] C="250 OK id=10HmaZ-0005vi-00"
+2017-07-30 18:51:05.712 10HmaX-0005vi-00 Completed
+2017-07-30 18:51:05.712 10HmaY-0005vi-00 ** bad@test.ex F=<CALLER@test.ex> R=smtp_try T=send_to_server: message has lines too long for transport
+2017-07-30 18:51:05.712 10HmbA-0005vi-00 <= <> R=10HmaY-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@test.ex
+2017-07-30 18:51:05.712 10HmbA-0005vi-00 => :blackhole: <CALLER@test.ex> R=rx_dump
+2017-07-30 18:51:05.712 10HmbA-0005vi-00 Completed
+2017-07-30 18:51:05.712 10HmaY-0005vi-00 Completed
diff --git a/test/log/0589 b/test/log/0589
new file mode 100644 (file)
index 0000000..dcbd656
--- /dev/null
@@ -0,0 +1,17 @@
+
+******** SERVER ********
+2017-07-30 18:51:05.712 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+2017-07-30 18:51:05.712 router    was called for quota_good@test.ex
+2017-07-30 18:51:05.712 transport was called for quota_good@test.ex
+2017-07-30 18:51:05.712 router    was called for quota_fail@test.ex
+2017-07-30 18:51:05.712 transport was called for quota_fail@test.ex
+2017-07-30 18:51:05.712 where='quota' msg='Over quota'
+2017-07-30 18:51:05.712 H=(test) [127.0.0.1] F=<b@test.ex> rejected RCPT <quota_fail@test.ex>: Over quota
+2017-07-30 18:51:05.712 router    was called for route_fail@test.ex
+2017-07-30 18:51:05.712 where='route' msg='Unrouteable address'
+2017-07-30 18:51:05.712 H=(test) [127.0.0.1] F=<c@test.ex> rejected RCPT <route_fail@test.ex>: Unrouteable address
+2017-07-30 18:51:05.712 where='quota' msg='Previous (cached) quota verification failure'
+2017-07-30 18:51:05.712 H=(test) [127.0.0.1] F=<e@test.ex> rejected RCPT <quota_fail@test.ex>: Previous (cached) quota verification failure
+2017-07-30 18:51:05.712 router    was called for route_fail@test.ex
+2017-07-30 18:51:05.712 where='route' msg='Unrouteable address'
+2017-07-30 18:51:05.712 H=(test) [127.0.0.1] F=<f@test.ex> rejected RCPT <route_fail@test.ex>: Unrouteable address
diff --git a/test/rejectlog/0589 b/test/rejectlog/0589
new file mode 100644 (file)
index 0000000..432b678
--- /dev/null
@@ -0,0 +1,6 @@
+
+******** SERVER ********
+2017-07-30 18:51:05.712 H=(test) [127.0.0.1] F=<b@test.ex> rejected RCPT <quota_fail@test.ex>: Over quota
+2017-07-30 18:51:05.712 H=(test) [127.0.0.1] F=<c@test.ex> rejected RCPT <route_fail@test.ex>: Unrouteable address
+2017-07-30 18:51:05.712 H=(test) [127.0.0.1] F=<e@test.ex> rejected RCPT <quota_fail@test.ex>: Previous (cached) quota verification failure
+2017-07-30 18:51:05.712 H=(test) [127.0.0.1] F=<f@test.ex> rejected RCPT <route_fail@test.ex>: Unrouteable address
index 05af333257c680e5c49ebbfdac18b6b36c8deb05..e4cf7ad6da5f65e79d0356dd479d56823d9e850a 100755 (executable)
@@ -916,7 +916,7 @@ RESET_AFTER_EXTRA_LINE_READ:
   s/renamed tmp\/\d+\.[^.]+\.(\S+) as new\/\d+\.[^.]+\.(\S+)/renamed tmp\/MAILDIR.$1 as new\/MAILDIR.$1/;
 
   # Maildir file names in general
-  s/\b\d+\.H\d+P\d+\b/dddddddddd.HddddddPddddd/;
+  s/\b\d+\.M\d+P\d+\b/dddddddddd.HddddddPddddd/;
 
   # Maildirsize data
   while (/^\d+S,\d+C\s*$/)
diff --git a/test/scripts/0000-Basic/0588 b/test/scripts/0000-Basic/0588
new file mode 100644 (file)
index 0000000..44328a7
--- /dev/null
@@ -0,0 +1,45 @@
+# message_linelength_limit
+#
+# The "write" script cmd subtracts 1 for the newline,
+# and the linecount in exim doesn't count the line-ending.
+write test-data-good 1x999
+++++
+****
+write test-data-bad  1x1000
+++++
+****
+#
+exim -bd -DSERVER=server -oX PORT_D
+****
+client 127.0.0.1 PORT_D
+??? 220
+HELO test
+??? 250
+MAIL FROM:<CALLER@test.ex>
+??? 250
+RCPT TO:<good@test.ex>
+??? 250
+DATA
+??? 354
+Subject: should be good
+
+<<< test-data-good
+.
+??? 250
+MAIL FROM:<CALLER@test.ex>
+??? 250
+RCPT TO:<bad@test.ex>
+??? 250
+DATA
+??? 354
+Subject: should be bad
+
+<<< test-data-bad
+.
+??? 250
+QUIT
+??? 221
+****
+#
+sleep 1
+killdaemon
diff --git a/test/scripts/0000-Basic/0589 b/test/scripts/0000-Basic/0589
new file mode 100644 (file)
index 0000000..8cea367
--- /dev/null
@@ -0,0 +1,44 @@
+# verify quota at smtp time
+#
+exim -bd -DSERVER=server -oX PORT_D
+****
+client 127.0.0.1 PORT_D
+??? 220
+EHLO test
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250 HELP
+MAIL FROM:<a@test.ex>\r\nRCPT TO:<quota_good@test.ex>
+??? 250
+??? 250
+RSET
+??? 250
+MAIL FROM:<b@test.ex> SIZE=2048\r\nRCPT TO:<quota_fail@test.ex>
+??? 250
+??? 550
+RSET
+??? 250
+MAIL FROM:<c@test.ex>\r\nRCPT TO:<route_fail@test.ex>
+??? 250
+??? 550
+RSET
+??? 250
+MAIL FROM:<d@test.ex>\r\nRCPT TO:<quota_good@test.ex>
+??? 250
+??? 250
+RSET
+??? 250
+MAIL FROM:<e@test.ex> SIZE=512\r\nRCPT TO:<quota_fail@test.ex>
+??? 250
+??? 550
+RSET
+??? 250
+MAIL FROM:<f@test.ex>\r\nRCPT TO:<route_fail@test.ex>
+??? 250
+??? 550
+QUIT
+****
+#
+killdaemon
index 381ef25632f5de0a6cdd4a9ed1229b4dd5d1fc59..8677b7166233b0d48803035712fd695366193ce5 100644 (file)
@@ -1,6 +1,7 @@
 # dsearch lookup
 # This test will fail on a case-insensitive filesystem (e.g. MacOS default)
 exim -be
+dsearch specifics
 ok:         ${lookup{TESTNUM.tst}              dsearch{DIR/aux-fixed}{$value}{FAIL}}
 fail:       ${lookup{TESTNUM.file_not_here}    dsearch{DIR/aux-fixed}{$value}{FAIL}}
 fail:       ${lookup{TESTNUM.tst}              dsearch{DIR/dir_not_here}{$value}{FAIL}}
@@ -16,6 +17,16 @@ fail,dir:   ${lookup{TESTNUM.tst} dsearch,filter=dir    {DIR/aux-fixed}{$value}{
 ok,subdir:  ${lookup{TESTNUM.dir} dsearch,filter=subdir {DIR/aux-fixed}{$value}{FAIL}}
 fail,subdir:${lookup{..}          dsearch,filter=subdir {DIR/aux-fixed}{$value}{FAIL}}
 fail,subdir:${lookup{TESTNUM.tst} dsearch,filter=subdir {DIR/aux-fixed}{$value}{FAIL}}
+
+cachelayer tests
+fail:       ${lookup{test-data}   dsearch               {DIR/}          {$value}{FAIL}}
+createfile: ${run {/bin/cp DIR/aux-fixed/TESTNUM.tst DIR/test-data} {OK}{FAIL}}
+fail,cached:${lookup{test-data}   dsearch               {DIR/}         {$value}{FAIL}}
+ok,no_rd    ${lookup{test-data}   dsearch,cache=no_rd   {DIR/}         {$value}{FAIL}}
+delfile:    ${run {/bin/rm DIR/test-data}                            {OK}{FAIL}}
+ok,cached:  ${lookup{test-data}   dsearch               {DIR/}         {$value}{FAIL}}
+fail,no_rd  ${lookup{test-data}   dsearch,cache=no_rd   {DIR/}         {$value}{FAIL}}
+fail:       ${lookup{test-data}   dsearch               {DIR/}         {$value}{FAIL}}
 ****
 #
 1
index 7286713d681ae2df5948ee87cddfea6734643e8f..a32fd44f6c1535e6e068c93368e7ecc479b70247 100644 (file)
@@ -1,2 +1,2 @@
-support Experimental_SRS
+support SRS
 feature _HAVE_NATIVE_SRS
index 2f12f27427f3bc25abb461181ecccfd43ab0d8d2..7f34d4f81b0425e24a3c09634ab391e1b67cb78c 100644 (file)
@@ -1,3 +1,3 @@
 support GnuTLS
 running IPv4
-support Experimental_TLS_resume
+support TLS_resume
index 027b4dcab7442954bf753aa9cbbe7604db1eafbf..8e3a29f539918fcb01a0d9bc79c438d8acdbb063 100644 (file)
@@ -1,3 +1,3 @@
 support OpenSSL
 running IPv4
-support Experimental_TLS_resume
+support TLS_resume
index 9d6fb5df8c628b46324c1331bf9df825e25b12bf..bd2d8067f0c6742cc4926df9b0b5956fd7dc063b 100644 (file)
@@ -326,6 +326,7 @@ internal_search_find: file="TESTSUITE/aux-fixed/0002.lsearch"
   type=lsearch key="ten-1.test.ex" opts=NULL
 file lookup required for ten-1.test.ex
   in TESTSUITE/aux-fixed/0002.lsearch
+creating new cache entry
 lookup yielded: 
 host in "<
  partial-lsearch;TESTSUITE/aux-fixed/0002.lsearch 
@@ -372,6 +373,7 @@ internal_search_find: file="TESTSUITE/aux-fixed/0002.lsearch"
   type=lsearch key="V4NET.0.0.2" opts=NULL
 file lookup required for V4NET.0.0.2
   in TESTSUITE/aux-fixed/0002.lsearch
+creating new cache entry
 lookup failed
 host in "net-lsearch;TESTSUITE/aux-fixed/0002.lsearch"? no (end of list)
 deny: condition test failed in ACL "connect2"
index e270896479461ba520a43fdd109fd97fe72e1268..7a30dfe54e1635546d0dd3a52ff45c7d3655d83b 100644 (file)
@@ -54,6 +54,7 @@ checking local_parts
    type=lsearch key="smart.domain" opts=NULL
  file lookup required for smart.domain
    in TESTSUITE/aux-fixed/0085.data
+ creating new cache entry
  lookup yielded: x : y : abc@d.e.f
 x in "x : y : abc@d.e.f"? yes (matched "x")
 checking senders
@@ -124,6 +125,7 @@ checking local_parts
    type=lsearch key="test.ex" opts=NULL
  file lookup required for test.ex
    in TESTSUITE/aux-fixed/0085.data
+ creating new cache entry
  lookup yielded: x : y : abc@d.e.f
 x in "x : y : abc@d.e.f"? yes (matched "x")
 checking senders
@@ -158,6 +160,7 @@ checking require_files
    type=lsearch key="test.ex.files" opts=NULL
  file lookup required for test.ex.files
    in TESTSUITE/aux-fixed/0085.data
+ creating new cache entry
  lookup yielded: /etc/passwd
 file check: ${lookup{$domain.files}lsearch{TESTSUITE/aux-fixed/0085.data}{$value}}
 expanded file: /etc/passwd
@@ -255,6 +258,7 @@ checking local_parts
    type=lsearch key="smart.domain" opts=NULL
  file lookup required for smart.domain
    in TESTSUITE/aux-fixed/0085.data
+ creating new cache entry
  lookup yielded: x : y : abc@d.e.f
 x in "x : y : abc@d.e.f"? yes (matched "x")
 checking senders
@@ -323,6 +327,7 @@ checking local_parts
    type=lsearch key="test.ex" opts=NULL
  file lookup required for test.ex
    in TESTSUITE/aux-fixed/0085.data
+ creating new cache entry
  lookup yielded: x : y : abc@d.e.f
 x in "x : y : abc@d.e.f"? yes (matched "x")
 checking senders
index d393252b57f0446cba9dc08a2a5f3d45d81e5e2f..347d9761bc7ddb0111174d1ff0ca35a1a805b516 100644 (file)
@@ -27,6 +27,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="x" opts=NULL
  file lookup required for x
    in TESTSUITE/aux-fixed/0123.aliases1
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -47,6 +48,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="x" opts=NULL
  file lookup required for x
    in TESTSUITE/aux-fixed/0123.aliases2
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -69,6 +71,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="x" opts=NULL
  file lookup required for x
    in TESTSUITE/aux-fixed/0123.aliases3
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -91,6 +94,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="x" opts=NULL
  file lookup required for x
    in TESTSUITE/aux-fixed/0123.aliases4
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -113,6 +117,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="x" opts=NULL
  file lookup required for x
    in TESTSUITE/aux-fixed/0123.aliases5
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -135,6 +140,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="x" opts=NULL
  file lookup required for x
    in TESTSUITE/aux-fixed/0123.aliases6
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -165,6 +171,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="y" opts=NULL
  file lookup required for y
    in TESTSUITE/aux-fixed/0123.aliases1
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -188,6 +195,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="y" opts=NULL
  file lookup required for y
    in TESTSUITE/aux-fixed/0123.aliases2
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -211,6 +219,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="y" opts=NULL
  file lookup required for y
    in TESTSUITE/aux-fixed/0123.aliases3
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -234,6 +243,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="y" opts=NULL
  file lookup required for y
    in TESTSUITE/aux-fixed/0123.aliases4
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -257,6 +267,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="y" opts=NULL
  file lookup required for y
    in TESTSUITE/aux-fixed/0123.aliases5
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -280,6 +291,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="y" opts=NULL
  file lookup required for y
    in TESTSUITE/aux-fixed/0123.aliases6
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -310,6 +322,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="z" opts=NULL
  file lookup required for z
    in TESTSUITE/aux-fixed/0123.aliases1
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -333,6 +346,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="z" opts=NULL
  file lookup required for z
    in TESTSUITE/aux-fixed/0123.aliases2
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -356,6 +370,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="z" opts=NULL
  file lookup required for z
    in TESTSUITE/aux-fixed/0123.aliases3
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -379,6 +394,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="z" opts=NULL
  file lookup required for z
    in TESTSUITE/aux-fixed/0123.aliases4
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -402,6 +418,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="z" opts=NULL
  file lookup required for z
    in TESTSUITE/aux-fixed/0123.aliases5
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
@@ -425,6 +442,7 @@ rda_interpret (string): '${lookup{$local_part}lsearch{TESTSUITE/aux-fixed/0123.a
    type=lsearch key="z" opts=NULL
  file lookup required for z
    in TESTSUITE/aux-fixed/0123.aliases6
+ creating new cache entry
  lookup failed
 expanded: ''
 file is not a filter file
index 292f52337f09c02243770fa035a8e29a6a0b4fe2..0a27a58781e2ab87b3646624580e7bd1f84b2c9a 100644 (file)
@@ -13,18 +13,21 @@ dropping to exim gid; retaining priv uid
    type=lsearch key="a.b.c" opts=NULL
  file lookup required for a.b.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match *.a.b.c
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="*.a.b.c" opts=NULL
  file lookup required for *.a.b.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match *.b.c
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="*.b.c" opts=NULL
  file lookup required for *.b.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup yielded: [*.b.c]
  search_open: lsearch "TESTSUITE/aux-fixed/0387.1"
    cached open
@@ -37,18 +40,21 @@ dropping to exim gid; retaining priv uid
    type=lsearch key="x.y.c" opts=NULL
  file lookup required for x.y.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match *.x.y.c
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="*.x.y.c" opts=NULL
  file lookup required for *.x.y.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match *.y.c
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="*.y.c" opts=NULL
  file lookup required for *.y.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  search_open: lsearch "TESTSUITE/aux-fixed/0387.1"
    cached open
@@ -79,6 +85,7 @@ dropping to exim gid; retaining priv uid
    type=lsearch key="*" opts=NULL
  file lookup required for *
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup yielded: [*]
  search_open: lsearch "TESTSUITE/aux-fixed/0387.1"
    cached open
@@ -109,6 +116,7 @@ dropping to exim gid; retaining priv uid
    type=lsearch key="*.c" opts=NULL
  file lookup required for *.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup yielded: [*.c]
  search_open: lsearch "TESTSUITE/aux-fixed/0387.1"
    cached open
@@ -121,12 +129,14 @@ dropping to exim gid; retaining priv uid
    type=lsearch key="x@y.c" opts=NULL
  file lookup required for x@y.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match *.x@y.c
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="*.x@y.c" opts=NULL
  file lookup required for *.x@y.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match *.c
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
@@ -151,6 +161,7 @@ dropping to exim gid; retaining priv uid
    type=lsearch key="*@y.c" opts=NULL
  file lookup required for *@y.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup yielded: [*@y.c]
  search_open: lsearch "TESTSUITE/aux-fixed/0387.1"
    cached open
@@ -193,12 +204,14 @@ dropping to exim gid; retaining priv uid
    type=lsearch key=".a.b.c" opts=NULL
  file lookup required for .a.b.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match .b.c
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key=".b.c" opts=NULL
  file lookup required for .b.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup yielded: [.b.c]
  search_open: lsearch "TESTSUITE/aux-fixed/0387.1"
    cached open
@@ -217,6 +230,7 @@ dropping to exim gid; retaining priv uid
    type=lsearch key="b.c" opts=NULL
  file lookup required for b.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup yielded: [b.c]
  search_open: lsearch "TESTSUITE/aux-fixed/0387.1"
    cached open
@@ -235,12 +249,14 @@ dropping to exim gid; retaining priv uid
    type=lsearch key="*a.b.c" opts=NULL
  file lookup required for *a.b.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match *b.c
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="*b.c" opts=NULL
  file lookup required for *b.c
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup yielded: [*b.c]
  search_open: lsearch "TESTSUITE/aux-fixed/0387.1"
    cached open
@@ -253,24 +269,28 @@ dropping to exim gid; retaining priv uid
    type=lsearch key="p.q.r" opts=NULL
  file lookup required for p.q.r
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match *.p.q.r
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="*.p.q.r" opts=NULL
  file lookup required for *.p.q.r
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match *.q.r
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="*.q.r" opts=NULL
  file lookup required for *.q.r
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match *.r
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="*.r" opts=NULL
  file lookup required for *.r
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match *
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
@@ -295,24 +315,28 @@ dropping to exim gid; retaining priv uid
    type=lsearch key=".p.q.r" opts=NULL
  file lookup required for .p.q.r
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match .q.r
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key=".q.r" opts=NULL
  file lookup required for .q.r
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match .r
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key=".r" opts=NULL
  file lookup required for .r
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match .
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="." opts=NULL
  file lookup required for .
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup yielded: [.]
  search_open: lsearch "TESTSUITE/aux-fixed/0387.1"
    cached open
@@ -325,18 +349,21 @@ dropping to exim gid; retaining priv uid
    type=lsearch key="x.aa.bb" opts=NULL
  file lookup required for x.aa.bb
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match ++x.aa.bb
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="++x.aa.bb" opts=NULL
  file lookup required for ++x.aa.bb
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match ++aa.bb
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="++aa.bb" opts=NULL
  file lookup required for ++aa.bb
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup yielded: [++aa.bb]
  search_open: lsearch "TESTSUITE/aux-fixed/0387.1"
    cached open
@@ -349,30 +376,35 @@ dropping to exim gid; retaining priv uid
    type=lsearch key="x.aa.zz" opts=NULL
  file lookup required for x.aa.zz
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match ++x.aa.zz
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="++x.aa.zz" opts=NULL
  file lookup required for ++x.aa.zz
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match ++aa.zz
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="++aa.zz" opts=NULL
  file lookup required for ++aa.zz
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match ++zz
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="++zz" opts=NULL
  file lookup required for ++zz
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup failed
  trying partial match ++
  internal_search_find: file="TESTSUITE/aux-fixed/0387.1"
    type=lsearch key="++" opts=NULL
  file lookup required for ++
    in TESTSUITE/aux-fixed/0387.1
+ creating new cache entry
  lookup yielded: [++]
  search_open: lsearch "TESTSUITE/aux-fixed/0387.1"
    cached open
index 4756eb62f982b1106e9f62b671f751462bae49fa..f77cfeee7ace640f9b4e709bc4ccc3e39b496406 100644 (file)
@@ -124,9 +124,9 @@ Attempting full verification using callout
  returned from EXIM_DBOPEN: 0xAAAAAAAA
  opened hints database TESTSUITE/spool/db/callout: flags=O_RDWR
  dbfn_read: key=remote
-callout cache: found domain record for remote
+ callout cache: found domain record for remote
  dbfn_read: key=qq@remote
-callout cache: no address record found for qq@remote
+ callout cache: no address record found for qq@remote
  EXIM_DBCLOSE(0xAAAAAAAA)
  closed hints database and lockfile
 interface=NULL port=1224
@@ -156,10 +156,10 @@ cmd buf flush ddd bytes
  returned from EXIM_DBOPEN: 0xAAAAAAAA
  opened hints database TESTSUITE/spool/db/callout: flags=O_RDWR|O_CREAT
  dbfn_write: key=remote
-wrote callout cache domain record for remote:
-  result=1 postmaster=0 random=0
+ wrote callout cache domain record for remote:
+   result=1 postmaster=0 random=0
  dbfn_write: key=qq@remote
-wrote negative callout cache address record for qq@remote
+ wrote negative callout cache address record for qq@remote
  EXIM_DBCLOSE(0xAAAAAAAA)
  closed hints database and lockfile
 ----------- end verify ------------
@@ -238,10 +238,10 @@ Attempting full verification using callout
  returned from EXIM_DBOPEN: 0xAAAAAAAA
  opened hints database TESTSUITE/spool/db/callout: flags=O_RDWR
  dbfn_read: key=remote
-callout cache: found domain record for remote
+ callout cache: found domain record for remote
  dbfn_read: key=qq@remote
-callout cache: found address record for qq@remote
-callout cache: address record is negative
+ callout cache: found address record for qq@remote
+ callout cache: address record is negative
  EXIM_DBCLOSE(0xAAAAAAAA)
  closed hints database and lockfile
 ----------- end verify ------------
index 0c22cf8f598c5cb185c3a09cdaacccdad9be1a83..16bf13b5e36a8a26f0780c603aa0982a03d61b9c 100644 (file)
@@ -94,6 +94,7 @@ internal_search_find: file="TESTSUITE/aux-fixed/0403.data"
   type=lsearch key="test.ex" opts=NULL
 file lookup required for test.ex
   in TESTSUITE/aux-fixed/0403.data
+creating new cache entry
 lookup yielded: [DOMAINDATA_test.ex]
 test.ex in "lsearch;TESTSUITE/aux-fixed/0403.data"? yes (matched "lsearch;TESTSUITE/aux-fixed/0403.data")
 checking local_parts
@@ -108,6 +109,7 @@ internal_search_find: file="TESTSUITE/aux-fixed/0403.data"
   type=lsearch key="userx" opts=NULL
 file lookup required for userx
   in TESTSUITE/aux-fixed/0403.data
+creating new cache entry
 lookup yielded: [LOCALPARTDATA_userx]
 userx in "lsearch;TESTSUITE/aux-fixed/0403.data"? yes (matched "lsearch;TESTSUITE/aux-fixed/0403.data")
 +++ROUTER:
index f1edd1ae3b76248c41d5e231fd0a64d90cef4452..18a51470046f9eae3a2e29025aea489e04243e70 100644 (file)
@@ -28,6 +28,7 @@ internal_search_find: file="TESTSUITE/aux-fixed/0414.list1"
   type=lsearch key="b.domain" opts=NULL
 file lookup required for b.domain
   in TESTSUITE/aux-fixed/0414.list1
+creating new cache entry
 lookup failed
 b.domain in "lsearch;TESTSUITE/aux-fixed/0414.list1"? no (end of list)
 search_open: lsearch "TESTSUITE/aux-fixed/0414.list2"
@@ -41,6 +42,7 @@ internal_search_find: file="TESTSUITE/aux-fixed/0414.list2"
   type=lsearch key="b.domain" opts=NULL
 file lookup required for b.domain
   in TESTSUITE/aux-fixed/0414.list2
+creating new cache entry
 lookup yielded: b.domain-data
 b.domain in "lsearch;TESTSUITE/aux-fixed/0414.list2"? yes (matched "lsearch;TESTSUITE/aux-fixed/0414.list2")
 data from lookup saved for cache for +B: key 'b.domain' value 'b.domain-data'
@@ -87,6 +89,7 @@ internal_search_find: file="TESTSUITE/aux-fixed/0414.list1"
   type=lsearch key="a.domain" opts=NULL
 file lookup required for a.domain
   in TESTSUITE/aux-fixed/0414.list1
+creating new cache entry
 lookup yielded: a.domain-data
 a.domain in "lsearch;TESTSUITE/aux-fixed/0414.list1"? yes (matched "lsearch;TESTSUITE/aux-fixed/0414.list1")
 data from lookup saved for cache for +A: key 'a.domain' value 'a.domain-data'
@@ -109,6 +112,7 @@ internal_search_find: file="TESTSUITE/aux-fixed/0414.list2"
   type=lsearch key="a.domain" opts=NULL
 file lookup required for a.domain
   in TESTSUITE/aux-fixed/0414.list2
+creating new cache entry
 lookup failed
 a.domain in "lsearch;TESTSUITE/aux-fixed/0414.list2"? no (end of list)
 a.domain in "+B"? no (end of list)
index b01205611244b822ab2afe4e9a7e80820ec37a0f..67280c3e2da07679f76d3b1073ddbc2a18dd7200 100644 (file)
@@ -85,9 +85,9 @@ Attempting full verification using callout
  returned from EXIM_DBOPEN: 0xAAAAAAAA
  opened hints database TESTSUITE/spool/db/callout: flags=O_RDWR
  dbfn_read: key=y
-callout cache: no domain record found for y
+ callout cache: no domain record found for y
  dbfn_read: key=x@y
-callout cache: no address record found for x@y
+ callout cache: no address record found for x@y
  EXIM_DBCLOSE(0xAAAAAAAA)
  closed hints database and lockfile
 interface=NULL port=1224
@@ -117,10 +117,10 @@ cmd buf flush ddd bytes
  returned from EXIM_DBOPEN: 0xAAAAAAAA
  opened hints database TESTSUITE/spool/db/callout: flags=O_RDWR|O_CREAT
  dbfn_write: key=y
-wrote callout cache domain record for y:
-  result=1 postmaster=0 random=0
+ wrote callout cache domain record for y:
+   result=1 postmaster=0 random=0
  dbfn_write: key=x@y
-wrote positive callout cache address record for x@y
+ wrote positive callout cache address record for x@y
  EXIM_DBCLOSE(0xAAAAAAAA)
  closed hints database and lockfile
 ----------- end verify ------------
@@ -196,10 +196,10 @@ Attempting full verification using callout
  returned from EXIM_DBOPEN: 0xAAAAAAAA
  opened hints database TESTSUITE/spool/db/callout: flags=O_RDWR
  dbfn_read: key=y
-callout cache: found domain record for y
+ callout cache: found domain record for y
  dbfn_read: key=x@y
-callout cache: found address record for x@y
-callout cache: address record is positive
+ callout cache: found address record for x@y
+ callout cache: address record is positive
  EXIM_DBCLOSE(0xAAAAAAAA)
  closed hints database and lockfile
 ----------- end verify ------------
index 0e5a5b3e96cc7b4deb1463513cc9cd6391a6e5e5..8c2cf0a8a4eb60bc982a20f0d66ac89361b87038 100644 (file)
@@ -9,6 +9,7 @@ Exim version x.yz ....
    type=lsearch key="spool" opts=NULL
  file lookup required for spool
    in TESTSUITE/aux-fixed/0437.ls
+ creating new cache entry
  lookup yielded: spool
 configuration file is TESTSUITE/test-config
 admin user
@@ -26,6 +27,7 @@ search_tidyup called
    type=lsearch key="transport" opts=NULL
  file lookup required for transport
    in TESTSUITE/aux-fixed/0437.ls
+ creating new cache entry
  lookup yielded: t1
 search_tidyup called
 search_tidyup called
@@ -39,6 +41,7 @@ search_tidyup called
    type=lsearch key="file" opts=NULL
  file lookup required for file
    in TESTSUITE/aux-fixed/0437.ls
+ creating new cache entry
  lookup yielded: file
 search_tidyup called
 LOG: MAIN
@@ -58,6 +61,7 @@ search_tidyup called
    type=lsearch key="transport" opts=NULL
  file lookup required for transport
    in TESTSUITE/aux-fixed/0437.ls
+ creating new cache entry
  lookup yielded: t1
 search_tidyup called
 search_tidyup called
@@ -71,6 +75,7 @@ search_tidyup called
    type=lsearch key="file" opts=NULL
  file lookup required for file
    in TESTSUITE/aux-fixed/0437.ls
+ creating new cache entry
  lookup yielded: file
 search_tidyup called
 LOG: MAIN
index 6ea3f3f978cadf7eef47e8eba41585d0e6fbdecf..625b571227b72d7dd9344a5e2bc896519613f22e 100644 (file)
@@ -31,6 +31,7 @@ internal_search_find: file="TESTSUITE/aux-fixed/0464.domains"
   type=lsearch key="domain1" opts=NULL
 file lookup required for domain1
   in TESTSUITE/aux-fixed/0464.domains
+creating new cache entry
 lookup yielded: data for domain1
 domain1 in "lsearch;TESTSUITE/aux-fixed/0464.domains"? yes (matched "lsearch;TESTSUITE/aux-fixed/0464.domains")
 data from lookup saved for cache for +special_domains: key 'domain1' value 'data for domain1'
@@ -78,6 +79,7 @@ internal_search_find: file="TESTSUITE/aux-fixed/0464.domains"
   type=lsearch key="xxx.domain1" opts=NULL
 file lookup required for xxx.domain1
   in TESTSUITE/aux-fixed/0464.domains
+creating new cache entry
 lookup failed
 xxx.domain1 in "lsearch;TESTSUITE/aux-fixed/0464.domains"? no (end of list)
 xxx.domain1 in "+special_domains"? no (end of list)
index f4619a3e97898a45aad0a3db4071fc3e424c4193..14fbe553472036424e3e6100d9d9dc7ac6a5cca7 100644 (file)
@@ -111,12 +111,14 @@ r1@test.ex in "*@*"? yes (matched "*@*")
    type=lsearch key="test.ex" opts=NULL
  file lookup required for test.ex
    in TESTSUITE/aux-fixed/0471.rw
+ creating new cache entry
  lookup failed
  trying partial match *.test.ex
  internal_search_find: file="TESTSUITE/aux-fixed/0471.rw"
    type=lsearch key="*.test.ex" opts=NULL
  file lookup required for *.test.ex
    in TESTSUITE/aux-fixed/0471.rw
+ creating new cache entry
  lookup failed
 address match test: subject=CALLER@myhost.test.ex pattern=*@*
 myhost.test.ex in "*"? yes (matched "*")
@@ -132,12 +134,14 @@ CALLER@myhost.test.ex in "*@*"? yes (matched "*@*")
    type=lsearch key="myhost.test.ex" opts=NULL
  file lookup required for myhost.test.ex
    in TESTSUITE/aux-fixed/0471.rw
+ creating new cache entry
  lookup failed
  trying partial match *.myhost.test.ex
  internal_search_find: file="TESTSUITE/aux-fixed/0471.rw"
    type=lsearch key="*.myhost.test.ex" opts=NULL
  file lookup required for *.myhost.test.ex
    in TESTSUITE/aux-fixed/0471.rw
+ creating new cache entry
  lookup failed
  trying partial match *.test.ex
  internal_search_find: file="TESTSUITE/aux-fixed/0471.rw"
@@ -241,6 +245,7 @@ random@test.example in "*@*"? yes (matched "*@*")
    type=lsearch key="test.example" opts=NULL
  file lookup required for test.example
    in TESTSUITE/aux-fixed/0471.rw
+ creating new cache entry
  lookup yielded: rwtest.example
 LOG: address_rewrite MAIN
   "random@test.example" from to: rewritten as "random@rwtest.example" by rule 1
index 25d7f745d821b17dc0b1583a720f0ce0bb6b1c50..56ce2e13a54f4ca3652c0791c6aa71db003078f6 100644 (file)
@@ -16,6 +16,7 @@ sender address = CALLER@myhost.test.ex
    type=lsearch key="list" opts=NULL
  file lookup required for list
    in TESTSUITE/aux-fixed/0484.aliases
+ creating new cache entry
  lookup yielded: userx, usery
  search_open: lsearch "TESTSUITE/aux-fixed/0484.aliases"
    cached open
@@ -40,6 +41,7 @@ sender address = CALLER@myhost.test.ex
    type=lsearch key="root" opts=NULL
  file lookup required for root
    in TESTSUITE/aux-fixed/0484.aliases
+ creating new cache entry
  lookup yielded: userx
  search_open: lsearch "TESTSUITE/aux-fixed/0484.aliases"
    cached open
@@ -76,6 +78,7 @@ sender address = CALLER@myhost.test.ex
    type=lsearch key="list" opts=NULL
  file lookup required for list
    in TESTSUITE/aux-fixed/0484.aliases2
+ creating new cache entry
  lookup yielded: userx2, usery2
  search_open: lsearch "TESTSUITE/aux-fixed/0484.aliases2"
    cached open
@@ -89,6 +92,7 @@ sender address = CALLER@myhost.test.ex
    type=lsearch key="root" opts=NULL
  file lookup required for root
    in TESTSUITE/aux-fixed/0484.aliases2
+ creating new cache entry
  lookup failed
  search_open: lsearch "TESTSUITE/aux-fixed/0484.aliases2"
    cached open
index ba50dffa7900af1293815530d2475bdab5adb62b..9631e9b82273c247f0f2345f836604615009ac82 100644 (file)
@@ -10,6 +10,7 @@ dropping to exim gid; retaining priv uid
    type=dnsdb key="a=localhost.test.ex" opts=NULL
  database lookup required for a=localhost.test.ex
  dnsdb key: localhost.test.ex
+ creating new cache entry
  lookup yielded: 127.0.0.1
  search_open: dnsdb "NULL"
    cached open
@@ -35,6 +36,7 @@ search_tidyup called
     type=dnsdb key="a=shorthost.test.ex" opts=NULL
   database lookup required for a=shorthost.test.ex
   dnsdb key: shorthost.test.ex
+  creating new cache entry
   lookup yielded: 127.0.0.1
   search_open: dnsdb "NULL"
     cached open
@@ -45,6 +47,7 @@ search_tidyup called
     type=dnsdb key="a=shorthost.test.ex" opts=NULL
   cached data found but out-of-date;   database lookup required for a=shorthost.test.ex
   dnsdb key: shorthost.test.ex
+  replacing old cache entry
   lookup yielded: 127.0.0.1
 LOG: MAIN
   <= CALLER@myhost.test.ex U=CALLER P=local S=sss
index 8f9d0b585e1677b6e8097181a02185d95329eca3..d25ac45754c0d85962cafb81d573d948b0dd454a 100644 (file)
@@ -37,6 +37,7 @@ database lookup required for test.ex
 dnsdb key: test.ex
 DNS lookup of test.ex (TXT) using fakens
 DNS lookup of test.ex (TXT) succeeded
+creating new cache entry
 lookup yielded: A TXT record for test.ex.
 test.ex in "dnsdb;test.ex"? yes (matched "dnsdb;test.ex")
 checking local_parts
@@ -101,6 +102,7 @@ DNS lookup of unknown (TXT) gave HOST_NOT_FOUND
 returning DNS_NOMATCH
 faking res_search(TXT) response length as 65535
  writing neg-cache entry for unknown-TXT-xxxx, ttl 3000
+creating new cache entry
 lookup failed
 unknown in "dnsdb;unknown"? no (end of list)
 r1 router skipped: local_parts mismatch
@@ -130,6 +132,7 @@ database lookup required for A=myhost.test.ex
 dnsdb key: myhost.test.ex
 DNS lookup of myhost.test.ex (A) using fakens
 DNS lookup of myhost.test.ex (A) succeeded
+creating new cache entry
 lookup yielded: V4NET.10.10.10
 CALLER@myhost.test.ex in "dnsdb;A=myhost.test.ex"? yes (matched "dnsdb;A=myhost.test.ex")
 calling r2 router
@@ -159,6 +162,7 @@ internal_search_find: file="NULL"
   type=dnsdb key="a=shorthost.test.ex" opts=NULL
 database lookup required for a=shorthost.test.ex
 dnsdb key: shorthost.test.ex
+creating new cache entry
 lookup yielded: 127.0.0.1
 search_open: dnsdb "NULL"
   cached open
@@ -178,6 +182,7 @@ internal_search_find: file="NULL"
   type=dnsdb key="a=shorthost.test.ex" opts=NULL
 cached data found but out-of-date; database lookup required for a=shorthost.test.ex
 dnsdb key: shorthost.test.ex
+replacing old cache entry
 lookup yielded: 127.0.0.1
 LOG: MAIN
   <= a@shorthost.test.ex U=CALLER P=local S=sss
index 3752ec538179c9417ca2a23240a3e0dbe75261c3..2c595a6dd9d824f90cc87c4a85cbaa13a082eaf7 100644 (file)
@@ -44,6 +44,7 @@ cioce.test.again.dns in dns_again_means_nonexist? yes (matched "*")
 cioce.test.again.dns is in dns_again_means_nonexist: returning DNS_NOMATCH
 DNS: no SOA record found for neg-TTL
  writing neg-cache entry for cioce.test.again.dns-MX-xxxx, ttl -1
+ creating new cache entry
  lookup failed
 sender host name required, to match against *.cioce.test.again.dns
 looking up host name for ip4.ip4.ip4.ip4
index 399fa0adb84ad07fcbb1165ccf32da6de60f4e93..e5dd60a27ef0524ab638cdb6fb3d5c28e166f656 100644 (file)
@@ -10,6 +10,7 @@ dropping to exim gid; retaining priv uid
    type=sqlite key="select name from them where id='userx';" opts=NULL
  file lookup required for select name from them where id='userx';
    in TESTSUITE/aux-fixed/sqlitedb
+ creating new cache entry
  lookup yielded: Ayen Other
  search_open: sqlite "TESTSUITE/aux-fixed/sqlitedb"
    cached open
@@ -41,6 +42,7 @@ dropping to exim gid; retaining priv uid
    type=sqlite key="select name from them where id='nothing';" opts=NULL
  file lookup required for select name from them where id='nothing';
    in TESTSUITE/aux-fixed/sqlitedb
+ creating new cache entry
  lookup yielded: 
  search_open: sqlite "TESTSUITE/aux-fixed/sqlitedb"
    cached open
@@ -51,6 +53,7 @@ dropping to exim gid; retaining priv uid
    type=sqlite key="select id,name from them where id='nothing';" opts=NULL
  file lookup required for select id,name from them where id='nothing';
    in TESTSUITE/aux-fixed/sqlitedb
+ creating new cache entry
  lookup yielded: id=nothing name="" 
  search_open: sqlite "TESTSUITE/aux-fixed/sqlitedb"
    cached open
@@ -61,6 +64,7 @@ dropping to exim gid; retaining priv uid
    type=sqlite key="select * from them where id='quote2';" opts=NULL
  file lookup required for select * from them where id='quote2';
    in TESTSUITE/aux-fixed/sqlitedb
+ creating new cache entry
  lookup yielded: name="\"stquot" id=quote2 
  search_open: sqlite "TESTSUITE/aux-fixed/sqlitedb"
    cached open
@@ -71,6 +75,7 @@ dropping to exim gid; retaining priv uid
    type=sqlite key="select * from them where id='newline';" opts=NULL
  file lookup required for select * from them where id='newline';
    in TESTSUITE/aux-fixed/sqlitedb
+ creating new cache entry
  lookup yielded: name="before
  after" id=newline 
  search_open: sqlite "TESTSUITE/aux-fixed/sqlitedb"
@@ -82,6 +87,7 @@ dropping to exim gid; retaining priv uid
    type=sqlite key="select * from them where id='tab';" opts=NULL
  file lookup required for select * from them where id='tab';
    in TESTSUITE/aux-fixed/sqlitedb
+ creating new cache entry
  lookup yielded: name="x       x" id=tab 
  search_open: sqlite "TESTSUITE/aux-fixed/sqlitedb"
    cached open
@@ -92,6 +98,7 @@ dropping to exim gid; retaining priv uid
    type=sqlite key="select * from them where id='its';" opts=NULL
  file lookup required for select * from them where id='its';
    in TESTSUITE/aux-fixed/sqlitedb
+ creating new cache entry
  lookup yielded: name=it's id=its 
  search_open: sqlite "TESTSUITE/aux-fixed/sqlitedb"
    cached open
@@ -102,6 +109,7 @@ dropping to exim gid; retaining priv uid
    type=sqlite key="select * from them where name='it''s';" opts=NULL
  file lookup required for select * from them where name='it''s';
    in TESTSUITE/aux-fixed/sqlitedb
+ creating new cache entry
  lookup yielded: name=it's id=its 
 search_tidyup called
 >>>>>>>>>>>>>>>> Exim pid=pppp (fresh-exec) terminating with rc=0 >>>>>>>>>>>>>>>>
@@ -247,6 +255,7 @@ internal_search_find: file="TESTSUITE/aux-fixed/sqlitedb"
   type=sqlite key="select * from them where id='10.10.10.10'" opts=NULL
 file lookup required for select * from them where id='10.10.10.10'
   in TESTSUITE/aux-fixed/sqlitedb
+creating new cache entry
 lookup yielded: name=ok id=10.10.10.10 
 host in "sqlite;TESTSUITE/aux-fixed/sqlitedb select * from them where id='10.10.10.10'"? yes (matched "sqlite;TESTSUITE/aux-fixed/sqlitedb select * from them where id='10.10.10.10'")
 host in "+relay_hosts"? yes (matched "+relay_hosts")
@@ -377,6 +386,7 @@ processing address_data
    type=sqlite key="select name from them where id='userx'" opts=NULL
  file lookup required for select name from them where id='userx'
    in TESTSUITE/aux-fixed/sqlitedb
+ creating new cache entry
  lookup yielded: Ayen Other
 calling r1 router
 r1 router called for userx@myhost.test.ex
@@ -419,6 +429,7 @@ appendfile transport entered
    type=sqlite key="select id from them where id='userx'" opts=NULL
  file lookup required for select id from them where id='userx'
    in TESTSUITE/aux-fixed/sqlitedb
+ creating new cache entry
  lookup yielded: userx
 appendfile: mode=600 notify_comsat=0 quota=0 warning=0
   file=TESTSUITE/test-mail/userx format=unix
@@ -481,6 +492,7 @@ dropping to exim gid; retaining priv uid
    type=sqlite key="select name from them where id='userx';" opts=NULL
  file lookup required for select name from them where id='userx';
    in TESTSUITE/aux-fixed/sqlitedb
+ creating new cache entry
  lookup yielded: Ayen Other
 search_tidyup called
 >>>>>>>>>>>>>>>> Exim pid=pppp (fresh-exec) terminating with rc=0 >>>>>>>>>>>>>>>>
@@ -495,6 +507,7 @@ dropping to exim gid; retaining priv uid
  internal_search_find: file="NULL"
    type=sqlite key="select name from them where id='userx';" opts=NULL
  database lookup required for select name from them where id='userx';
+ creating new cache entry
  lookup yielded: Ayen Other
 search_tidyup called
 >>>>>>>>>>>>>>>> Exim pid=pppp (fresh-exec) terminating with rc=0 >>>>>>>>>>>>>>>>
index 925fb914b67bdd653ebe95a8af6da95e0bd8d471..657f115e9cf4104db9d57dd1d677d2e21422cac5 100644 (file)
@@ -14,6 +14,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for select name from them where id='ph10';
  MySQL query: "select name from them where id='ph10';" opts 'NULL'
  MYSQL new connection: host=127.0.0.1 port=1223 socket=NULL database=test user=root
+ creating new cache entry
  lookup yielded: Philip Hazel
  search_open: mysql "NULL"
    cached open
@@ -35,6 +36,7 @@ dropping to exim gid; retaining priv uid
  MySQL query: "select name from them where id='xxxx';" opts 'NULL'
  MYSQL using cached connection for 127.0.0.1:1223/test/root
  MYSQL: no data found
+ creating new cache entry
  lookup failed
  search_open: mysql "NULL"
    cached open
@@ -46,6 +48,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for select name from them where id='nothing';
  MySQL query: "select name from them where id='nothing';" opts 'NULL'
  MYSQL using cached connection for 127.0.0.1:1223/test/root
+ creating new cache entry
  lookup yielded: 
  search_open: mysql "NULL"
    cached open
@@ -57,6 +60,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for select id,name from them where id='nothing';
  MySQL query: "select id,name from them where id='nothing';" opts 'NULL'
  MYSQL using cached connection for 127.0.0.1:1223/test/root
+ creating new cache entry
  lookup yielded: id=nothing name="" 
  search_open: mysql "NULL"
    cached open
@@ -82,6 +86,7 @@ dropping to exim gid; retaining priv uid
  MySQL query: "select * from them where id='quote';" opts 'NULL'
  MYSQL using cached connection for 127.0.0.1:1223/test/root
  MYSQL: no data found
+ creating new cache entry
  lookup failed
  search_open: mysql "NULL"
    cached open
@@ -94,6 +99,7 @@ dropping to exim gid; retaining priv uid
  MySQL query: "select * from them where id='filter';" opts 'NULL'
  MYSQL using cached connection for 127.0.0.1:1223/test/root
  MYSQL: no data found
+ creating new cache entry
  lookup failed
  search_open: mysql "NULL"
    cached open
@@ -105,6 +111,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for select * from them where id='quote2';
  MySQL query: "select * from them where id='quote2';" opts 'NULL'
  MYSQL using cached connection for 127.0.0.1:1223/test/root
+ creating new cache entry
  lookup yielded: name="\"stquot" id=quote2 
  search_open: mysql "NULL"
    cached open
@@ -117,6 +124,7 @@ dropping to exim gid; retaining priv uid
  MySQL query: "select * from them where id='nlonly';" opts 'NULL'
  MYSQL using cached connection for 127.0.0.1:1223/test/root
  MYSQL: no data found
+ creating new cache entry
  lookup failed
  search_open: mysql "NULL"
    cached open
@@ -138,6 +146,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for servers=127.0.0.1::1223:x; select name from them where id='ph10';
  MySQL query: "servers=127.0.0.1::1223:x; select name from them where id='ph10';" opts 'NULL'
  MYSQL using cached connection for 127.0.0.1:1223/test/root
+ creating new cache entry
  lookup yielded: Philip Hazel
  search_open: mysql "NULL"
    cached open
@@ -149,6 +158,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for servers=127.0.0.1::1223/test/root/:x; select name from them where id='ph10';
  MySQL query: "servers=127.0.0.1::1223/test/root/:x; select name from them where id='ph10';" opts 'NULL'
  MYSQL using cached connection for 127.0.0.1:1223/test/root
+ creating new cache entry
  lookup yielded: Philip Hazel
  search_open: mysql "NULL"
    cached open
@@ -160,6 +170,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for servers=ip4.ip4.ip4.ip4::1223/test/root/:127.0.0.1::1223; select name from them where id='ph10';
  MySQL query: "servers=ip4.ip4.ip4.ip4::1223/test/root/:127.0.0.1::1223; select name from them where id='ph10';" opts 'NULL'
  MYSQL new connection: host=ip4.ip4.ip4.ip4 port=1223 socket=NULL database=test user=root
+ creating new cache entry
  lookup yielded: Philip Hazel
  search_open: mysql "NULL"
    cached open
@@ -171,6 +182,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for servers=localhost(TESTSUITE/mysql/sock)/test/root/pass; select name from them where id='ph10';
  MySQL query: "servers=localhost(TESTSUITE/mysql/sock)/test/root/pass; select name from them where id='ph10';" opts 'NULL'
  MYSQL new connection: host=localhost port=0 socket=TESTSUITE/mysql/sock database=test user=root
+ creating new cache entry
  lookup yielded: Philip Hazel
  search_open: mysql "NULL"
    cached open
@@ -182,6 +194,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for SELECT name FROM them WHERE id IN ('ph10', 'aaaa');
  MySQL query: "SELECT name FROM them WHERE id IN ('ph10', 'aaaa');" opts 'NULL'
  MYSQL using cached connection for 127.0.0.1:1223/test/root
+ creating new cache entry
  lookup yielded: Philip Hazel
  Aristotle
  search_open: mysql "NULL"
@@ -194,6 +207,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for SELECT *    FROM them WHERE id IN ('ph10', 'aaaa');
  MySQL query: "SELECT *    FROM them WHERE id IN ('ph10', 'aaaa');" opts 'NULL'
  MYSQL using cached connection for 127.0.0.1:1223/test/root
+ creating new cache entry
  lookup yielded: name="Philip Hazel" id=ph10 
  name=Aristotle id=aaaa 
  search_open: mysql "NULL"
@@ -257,6 +271,7 @@ processing "warn" (TESTSUITE/test-config 25)
  MySQL query: "select name from them where id = 'c'" opts 'NULL'
  MYSQL new connection: host=127.0.0.1 port=1223 socket=NULL database=test user=root
  MYSQL: no data found
+ creating new cache entry
  lookup failed
 check set acl_m0 = ok:   ${lookup mysql                    {select name from them where id = '$local_part'}}
                  = ok:   
@@ -271,6 +286,7 @@ check set acl_m0 = ok:   ${lookup mysql                    {select name from the
  MySQL query: "select name from them where id = 'c'" opts 'servers=127.0.0.1::1223/test/root/pass'
  MYSQL using cached connection for 127.0.0.1:1223/test/root
  MYSQL: no data found
+ replacing old cache entry
  lookup failed
 check set acl_m0 = ok:   ${lookup mysql,servers=127.0.0.1::1223/test/root/pass      {select name from them where id = '$local_part'}}
                  = ok:   
@@ -285,6 +301,7 @@ check set acl_m0 = ok:   ${lookup mysql,servers=127.0.0.1::1223/test/root/pass
  MySQL query: "select name from them where id = 'c'" opts 'servers=127.0.0.1::1223'
  MYSQL using cached connection for 127.0.0.1:1223/test/root
  MYSQL: no data found
+ replacing old cache entry
  lookup failed
 check set acl_m0 = ok:   ${lookup mysql,servers=127.0.0.1::1223    {select name from them where id = '$local_part'}}
                  = ok:   
@@ -315,6 +332,7 @@ database lookup required for select * from them where id='c'
 MySQL query: "select * from them where id='c'" opts 'NULL'
 MYSQL using cached connection for 127.0.0.1:1223/test/root
 MYSQL: no data found
+creating new cache entry
 lookup failed
 host in "net-mysql;select * from them where id='c'"? no (end of list)
 warn: condition test failed in ACL "check_recipient"
@@ -370,6 +388,7 @@ database lookup required for select * from them where id='10.0.0.0'
 MySQL query: "select * from them where id='10.0.0.0'" opts 'NULL'
 MYSQL using cached connection for 127.0.0.1:1223/test/root
 MYSQL: no data found
+creating new cache entry
 lookup failed
 host in "net-mysql;select * from them where id='10.0.0.0'"? no (end of list)
 host in "+relay_hosts"? no (end of list)
@@ -483,6 +502,7 @@ processing address_data
  database lookup required for select name from them where id='ph10'
  MySQL query: "select name from them where id='ph10'" opts 'NULL'
  MYSQL new connection: host=127.0.0.1 port=1223 socket=NULL database=test user=root
+ creating new cache entry
  lookup yielded: Philip Hazel
 calling r1 router
 r1 router called for ph10@myhost.test.ex
@@ -527,6 +547,7 @@ appendfile transport entered
  database lookup required for select id from them where id='ph10'
  MySQL query: "select id from them where id='ph10'" opts 'NULL'
  MYSQL new connection: host=127.0.0.1 port=1223 socket=NULL database=test user=root
+ creating new cache entry
  lookup yielded: ph10
 appendfile: mode=600 notify_comsat=0 quota=0 warning=0
   file=TESTSUITE/test-mail/ph10 format=unix
index 8c610d87eacff92fd0e38ab537f060cce3c9214e..eee26190d2eadb1ccbfd9ae7561011bcea2e70d5 100644 (file)
@@ -15,6 +15,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for select name from them where id='ph10';
  PostgreSQL query: "select name from them where id='ph10';" opts 'NULL'
  PGSQL new connection: host=localhost port=1223 database=test user=CALLER
+ creating new cache entry
  lookup yielded: Philip Hazel
  search_open: pgsql "NULL"
    cached open
@@ -36,6 +37,7 @@ dropping to exim gid; retaining priv uid
  PostgreSQL query: "select name from them where id='xxxx';" opts 'NULL'
  PGSQL using cached connection for localhost:1223/test/CALLER
  PGSQL: no data found
+ creating new cache entry
  lookup failed
  search_open: pgsql "NULL"
    cached open
@@ -47,6 +49,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for select name from them where id='nothing';
  PostgreSQL query: "select name from them where id='nothing';" opts 'NULL'
  PGSQL using cached connection for localhost:1223/test/CALLER
+ creating new cache entry
  lookup yielded: 
  search_open: pgsql "NULL"
    cached open
@@ -58,6 +61,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for select id,name from them where id='nothing';
  PostgreSQL query: "select id,name from them where id='nothing';" opts 'NULL'
  PGSQL using cached connection for localhost:1223/test/CALLER
+ creating new cache entry
  lookup yielded: id=nothing name="" 
  search_open: pgsql "NULL"
    cached open
@@ -82,6 +86,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for select * from them where id='quote2';
  PostgreSQL query: "select * from them where id='quote2';" opts 'NULL'
  PGSQL using cached connection for localhost:1223/test/CALLER
+ creating new cache entry
  lookup yielded: name="\"stquot" id=quote2 
  search_open: pgsql "NULL"
    cached open
@@ -93,6 +98,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for select * from them where id='newline';
  PostgreSQL query: "select * from them where id='newline';" opts 'NULL'
  PGSQL using cached connection for localhost:1223/test/CALLER
+ creating new cache entry
  lookup yielded: name="before\r
  after" id=newline 
  search_open: pgsql "NULL"
@@ -105,6 +111,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for select * from them where id='tab';
  PostgreSQL query: "select * from them where id='tab';" opts 'NULL'
  PGSQL using cached connection for localhost:1223/test/CALLER
+ creating new cache entry
  lookup yielded: name="x       x" id=tab 
  search_open: pgsql "NULL"
    cached open
@@ -116,6 +123,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for select * from them where name='''stquot';
  PostgreSQL query: "select * from them where name='''stquot';" opts 'NULL'
  PGSQL using cached connection for localhost:1223/test/CALLER
+ creating new cache entry
  lookup yielded: name='stquot id=quote1 
  search_open: pgsql "NULL"
    cached open
@@ -137,6 +145,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for servers=localhost::1223:x; select name from them where id='ph10';
  PostgreSQL query: "servers=localhost::1223:x; select name from them where id='ph10';" opts 'NULL'
  PGSQL using cached connection for localhost:1223/test/CALLER
+ creating new cache entry
  lookup yielded: Philip Hazel
  search_open: pgsql "NULL"
    cached open
@@ -148,6 +157,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for servers=localhost::1223/test/CALLER/:x; select name from them where id='ph10';
  PostgreSQL query: "servers=localhost::1223/test/CALLER/:x; select name from them where id='ph10';" opts 'NULL'
  PGSQL using cached connection for localhost:1223/test/CALLER
+ creating new cache entry
  lookup yielded: Philip Hazel
  search_open: pgsql "NULL"
    cached open
@@ -159,6 +169,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for servers=(TESTSUITE/pgsql/.s.PGSQL.1223)/test/CALLER/:x; select name from them where id='ph10';
  PostgreSQL query: "servers=(TESTSUITE/pgsql/.s.PGSQL.1223)/test/CALLER/:x; select name from them where id='ph10';" opts 'NULL'
  PGSQL new connection: socket=TESTSUITE/pgsql/.s.PGSQL.1223 database=test user=CALLER
+ creating new cache entry
  lookup yielded: Philip Hazel
  search_open: pgsql "NULL"
    cached open
@@ -170,6 +181,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for SELECT name FROM them WHERE id IN ('ph10', 'aaaa');
  PostgreSQL query: "SELECT name FROM them WHERE id IN ('ph10', 'aaaa');" opts 'NULL'
  PGSQL using cached connection for localhost:1223/test/CALLER
+ creating new cache entry
  lookup yielded: Philip Hazel
  Aristotle
  search_open: pgsql "NULL"
@@ -182,6 +194,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for SELECT *    FROM them WHERE id IN ('ph10', 'aaaa');
  PostgreSQL query: "SELECT *    FROM them WHERE id IN ('ph10', 'aaaa');" opts 'NULL'
  PGSQL using cached connection for localhost:1223/test/CALLER
+ creating new cache entry
  lookup yielded: name="Philip Hazel" id=ph10 
  name=Aristotle id=aaaa 
  search_open: pgsql "NULL"
@@ -244,6 +257,7 @@ processing "warn" (TESTSUITE/test-config 27)
  PostgreSQL query: "select name from them where id = 'c'" opts 'NULL'
  PGSQL new connection: host=localhost port=1223 database=test user=CALLER
  PGSQL: no data found
+ creating new cache entry
  lookup failed
 check set acl_m0 = ok:   ${lookup pgsql                    {select name from them where id = '$local_part'}}
                  = ok:   
@@ -274,6 +288,7 @@ database lookup required for select * from them where id='c'
 PostgreSQL query: "select * from them where id='c'" opts 'NULL'
 PGSQL using cached connection for localhost:1223/test/CALLER
 PGSQL: no data found
+creating new cache entry
 lookup failed
 host in "net-pgsql;select * from them where id='c'"? no (end of list)
 warn: condition test failed in ACL "check_recipient"
@@ -329,6 +344,7 @@ database lookup required for select * from them where id='10.0.0.0'
 PostgreSQL query: "select * from them where id='10.0.0.0'" opts 'NULL'
 PGSQL using cached connection for localhost:1223/test/CALLER
 PGSQL: no data found
+creating new cache entry
 lookup failed
 host in "net-pgsql;select * from them where id='10.0.0.0'"? no (end of list)
 host in "+relay_hosts"? no (end of list)
@@ -543,6 +559,7 @@ processing address_data
  database lookup required for select name from them where id='ph10'
  PostgreSQL query: "select name from them where id='ph10'" opts 'NULL'
  PGSQL new connection: host=localhost port=1223 database=test user=CALLER
+ creating new cache entry
  lookup yielded: Philip Hazel
 calling r1 router
 r1 router called for CALLER@myhost.test.ex
@@ -587,6 +604,7 @@ appendfile transport entered
  database lookup required for select id from them where id='ph10'
  PostgreSQL query: "select id from them where id='ph10'" opts 'NULL'
  PGSQL new connection: host=localhost port=1223 database=test user=CALLER
+ creating new cache entry
  lookup yielded: ph10
 appendfile: mode=600 notify_comsat=0 quota=0 warning=0
   file=TESTSUITE/test-mail/ph10 format=unix
@@ -651,6 +669,7 @@ dropping to exim gid; retaining priv uid
  database lookup required for select name from them where id='ph10';
  PostgreSQL query: "select name from them where id='ph10';" opts 'NULL'
  PGSQL new connection: socket=TESTSUITE/pgsql/.s.PGSQL.1223 database=test user=CALLER
+ creating new cache entry
  lookup yielded: Philip Hazel
 search_tidyup called
 close PGSQL connection: (TESTSUITE/pgsql/.s.PGSQL.1223)/test/CALLER
index 32bf69ca69d7ba773a35a88307450c1dd5e4d709..601a9ec851b3cdcd6fde4bb6cd4711ac11281d8a 100644 (file)
@@ -31,6 +31,7 @@ internal_search_find: file="NULL"
   type=testdb key="fail" opts=NULL
 database lookup required for fail
 testdb lookup forced FAIL
+creating new cache entry
 lookup failed
 host in "testdb;fail"? no (end of list)
 deny: condition test failed in ACL "connect1"
@@ -73,6 +74,7 @@ internal_search_find: file="NULL"
   type=testdb key="fail" opts=NULL
 database lookup required for fail
 testdb lookup forced FAIL
+creating new cache entry
 lookup failed
 host in "net-testdb;fail"? no (end of list)
 deny: condition test failed in ACL "connect2"
index 1c944c24cc4a1cb402a1c4c52f987590e3c207b0..7b7719801d4e3f63dca83808faf7f5cafd9dc23c 100644 (file)
@@ -16,6 +16,7 @@ sender address = CALLER@myhost.test.ex
    type=lsearch key="list" opts=NULL
  file lookup required for list
    in TESTSUITE/aux-fixed/3212.aliases
+ creating new cache entry
  lookup yielded: userx, usery
  search_open: lsearch "TESTSUITE/aux-fixed/3212.aliases"
    cached open
@@ -40,6 +41,7 @@ sender address = CALLER@myhost.test.ex
    type=lsearch key="root" opts=NULL
  file lookup required for root
    in TESTSUITE/aux-fixed/3212.aliases
+ creating new cache entry
  lookup yielded: userx
  search_open: lsearch "TESTSUITE/aux-fixed/3212.aliases"
    cached open
@@ -74,6 +76,7 @@ sender address = CALLER@myhost.test.ex
  internal_search_find: file="NULL"
    type=testdb key="something" opts=NULL
  database lookup required for something
+ creating new cache entry
  lookup yielded: something
  search_open: testdb "NULL"
    cached open
@@ -108,6 +111,7 @@ sender address = CALLER@myhost.test.ex
  internal_search_find: file="NULL"
    type=testdb key="something" opts=NULL
  database lookup required for something
+ creating new cache entry
  lookup yielded: something
  search_open: lsearch "TESTSUITE/aux-fixed/3212.aliases"
    cached open
index d66f928d42dfb8f77af7970aa043772ca4f49a5d..fd77c72b7be163dad67999c7ad79d0ff797b62cb 100644 (file)
@@ -64,6 +64,7 @@ interface = ip4.ip4.ip4.ip4
 keepalive
 no_lmtp_ignore_quota
 max_rcpt = 100
+message_linelength_limit = 998
 multi_domain
 port = 1224
 protocol = smtp
diff --git a/test/stdout/0588 b/test/stdout/0588
new file mode 100644 (file)
index 0000000..994f04e
--- /dev/null
@@ -0,0 +1,40 @@
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> HELO test
+??? 250
+<<< 250 the.local.host.name Hello test [127.0.0.1]
+>>> MAIL FROM:<CALLER@test.ex>
+??? 250
+<<< 250 OK
+>>> RCPT TO:<good@test.ex>
+??? 250
+<<< 250 Accepted
+>>> DATA
+??? 354
+<<< 354 Enter message, ending with "." on a line by itself
+>>> Subject: should be good
+>>> 
+>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+>>> .
+??? 250
+<<< 250 OK id=10HmaX-0005vi-00
+>>> MAIL FROM:<CALLER@test.ex>
+??? 250
+<<< 250 OK
+>>> RCPT TO:<bad@test.ex>
+??? 250
+<<< 250 Accepted
+>>> DATA
+??? 354
+<<< 354 Enter message, ending with "." on a line by itself
+>>> Subject: should be bad
+>>> 
+>>> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+>>> .
+??? 250
+<<< 250 OK id=10HmaY-0005vi-00
+>>> QUIT
+??? 221
+<<< 221 the.local.host.name closing connection
+End of script
diff --git a/test/stdout/0589 b/test/stdout/0589
new file mode 100644 (file)
index 0000000..9f70b73
--- /dev/null
@@ -0,0 +1,61 @@
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> EHLO test
+??? 250-
+<<< 250-myhost.test.ex Hello test [127.0.0.1]
+??? 250-SIZE
+<<< 250-SIZE 52428800
+??? 250-8BITMIME
+<<< 250-8BITMIME
+??? 250-PIPELINING
+<<< 250-PIPELINING
+??? 250 HELP
+<<< 250 HELP
+>>> MAIL FROM:<a@test.ex>\r\nRCPT TO:<quota_good@test.ex>
+??? 250
+<<< 250 OK
+??? 250
+<<< 250 Accepted
+>>> RSET
+??? 250
+<<< 250 Reset OK
+>>> MAIL FROM:<b@test.ex> SIZE=ssss\r\nRCPT TO:<quota_fail@test.ex>
+??? 250
+<<< 250 OK
+??? 550
+<<< 550 Administrative prohibition
+>>> RSET
+??? 250
+<<< 250 Reset OK
+>>> MAIL FROM:<c@test.ex>\r\nRCPT TO:<route_fail@test.ex>
+??? 250
+<<< 250 OK
+??? 550
+<<< 550 Administrative prohibition
+>>> RSET
+??? 250
+<<< 250 Reset OK
+>>> MAIL FROM:<d@test.ex>\r\nRCPT TO:<quota_good@test.ex>
+??? 250
+<<< 250 OK
+??? 250
+<<< 250 Accepted
+>>> RSET
+??? 250
+<<< 250 Reset OK
+>>> MAIL FROM:<e@test.ex> SIZE=ssss\r\nRCPT TO:<quota_fail@test.ex>
+??? 250
+<<< 250 OK
+??? 550
+<<< 550 Administrative prohibition
+>>> RSET
+??? 250
+<<< 250 Reset OK
+>>> MAIL FROM:<f@test.ex>\r\nRCPT TO:<route_fail@test.ex>
+??? 250
+<<< 250 OK
+??? 550
+<<< 550 Administrative prohibition
+>>> QUIT
+End of script
index 7e413c0a3ba562e9f4cd0a39b07ef47f4fd7a803..c6014d388a30a9af5512d4fa4182f371ef65c65d 100644 (file)
@@ -1,3 +1,4 @@
+> dsearch specifics
 > ok:         2500.tst
 > fail:       FAIL
 > Failed: failed to open TESTSUITE/dir_not_here for directory search: No such file or directory
 > fail,subdir:FAIL
 > fail,subdir:FAIL
 > 
+> cachelayer tests
+> fail:       FAIL
+> createfile: OK
+> fail,cached:FAIL
+> ok,no_rd    test-data
+> delfile:    OK
+> ok,cached:  test-data
+> fail,no_rd  FAIL
+> fail:       FAIL
+>