Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > a4080654d049ad31b216b761b9173c1f > files > 144

exim-doc-4.69-4mdv2010.0.i586.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html401/loose.dtd">
<html>
<!-- Created on September, 10 2009 by texi2html 1.78 -->
<!--
Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
            Karl Berry  <karl@freefriends.org>
            Olaf Bachmann <obachman@mathematik.uni-kl.de>
            and many others.
Maintained by: Many creative people.
Send bugs and suggestions to <texi2html-bug@nongnu.org>

-->
<head>
<title>Specification of the Exim Mail Transfer Agent: 40. Access control lists</title>

<meta name="description" content="Specification of the Exim Mail Transfer Agent: 40. Access control lists">
<meta name="keywords" content="Specification of the Exim Mail Transfer Agent: 40. Access control lists">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="texi2html 1.78">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
pre.display {font-family: serif}
pre.format {font-family: serif}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: serif; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: serif; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.roman {font-family:serif; font-weight:normal;}
span.sansserif {font-family:sans-serif; font-weight:normal;}
ul.toc {list-style: none}
-->
</style>


</head>

<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">

<a name="Access-control-lists"></a>
<a name="SEC308"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="spec_39.html#SEC307" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC309" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec_39.html#SEC294" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h1 class="chapter"> 40. Access control lists </h1>

<p>Access Control Lists (ACLs) are defined in a separate section of the run time
configuration file, headed by &quot;begin acl&quot;. Each ACL definition starts with a
name, terminated by a colon. Here is a complete ACL section that contains just
one very small ACL:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">begin acl
small_acl:
  accept   hosts = one.host.only
</pre></td></tr></table>

<p>You can have as many lists as you like in the ACL section, and the order in
which they appear does not matter. The lists are self-terminating.
</p>
<p>The majority of ACLs are used to control Exim's behaviour when it receives
certain SMTP commands. This applies both to incoming TCP/IP connections, and
when a local process submits a message using SMTP by specifying the <code>-bs</code>
option. The most common use is for controlling which recipients are accepted
in incoming messages. In addition, you can define an ACL that is used to check
local non-SMTP messages. The default configuration file contains an example of
a realistic ACL for checking RCPT commands. This is discussed in chapter
<a href="spec_7.html#SEC79">The default configuration file</a>.
</p>
<table class="menu" border="0" cellspacing="0">
<tr><td align="left" valign="top"><a href="#SEC309">40.1 Testing ACLs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC310">40.2 Specifying when ACLs are used</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC311">40.3 The non-SMTP ACLs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC312">40.4 The SMTP connect ACL</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC313">40.5 The EHLO/HELO ACL</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC314">40.6 The DATA ACLs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC315">40.7 The SMTP MIME ACL</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC316">40.8 The QUIT ACL</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC317">40.9 The not-QUIT ACL</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC318">40.10 Finding an ACL to use</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC319">40.11 ACL return codes</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC320">40.12 Unset ACL options</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC321">40.13 Data for message ACLs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC322">40.14 Data for non-message ACLs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC323">40.15 Format of an ACL</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC324">40.16 ACL verbs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC325">40.17 ACL variables</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC326">40.18 Condition and modifier processing</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC327">40.19 ACL modifiers</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC328">40.20 Use of the control modifier</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC329">40.21 Summary of message fixup control</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC330">40.22 Adding header lines in ACLs</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC331">40.23 ACL conditions</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC332">40.24 Using DNS lists</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC333">40.25 Specifying the IP address for a DNS list lookup</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC334">40.26 DNS lists keyed on domain names</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC335">40.27 Multiple explicit keys for a DNS list</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC336">40.28 Data returned by DNS lists</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC337">40.29 Variables set from DNS lists</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC338">40.30 Additional matching conditions for DNS lists</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC339">40.31 Negated DNS matching conditions</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC340">40.32 Handling multiple DNS records from a DNS list</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC341">40.33 Detailed information from merged DNS lists</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC342">40.34 DNS lists and IPv6</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC343">40.35 Rate limiting incoming messages</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC344">40.36 Ratelimit options for what is being measured</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC345">40.37 Ratelimit options for handling fast clients</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC346">40.38 Using rate limiting</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC347">40.39 Reading ratelimit data without updating</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC348">40.40 Address verification</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC349">40.41 Callout verification</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC350">40.42 Additional parameters for callouts</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC351">40.43 Callout caching</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC352">40.44 Sender address verification reporting</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC353">40.45 Redirection while verifying</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC354">40.46 Client SMTP authorization (CSA)</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC355">40.47 Bounce address tag validation</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC356">40.48 Using an ACL to control relaying</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC357">40.49 Checking a relay configuration</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
</table>

<hr size="6">
<a name="Testing-ACLs"></a>
<a name="SEC309"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC308" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC310" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.1 Testing ACLs </h2>

<p>The <code>-bh</code> command line option provides a way of testing your ACL
configuration locally by running a fake SMTP session with which you interact.
The host <em>relay-test.mail-abuse.org</em> provides a service for checking your
relaying configuration (see section <a href="#SEC357">Checking a relay configuration</a> for more details).
</p>
<hr size="6">
<a name="Specifying-when-ACLs-are-used"></a>
<a name="SEC310"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC309" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC311" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.2 Specifying when ACLs are used </h2>

<p>In order to cause an ACL to be used, you have to name it in one of the relevant
options in the main part of the configuration. These options are:
<a name="IDX2478"></a>
<a name="IDX2479"></a>
<a name="IDX2480"></a>
<a name="IDX2481"></a>
<a name="IDX2482"></a>
<a name="IDX2483"></a>
<a name="IDX2484"></a>
<a name="IDX2485"></a>
<a name="IDX2486"></a>
<a name="IDX2487"></a>
<a name="IDX2488"></a>
<a name="IDX2489"></a>
<a name="IDX2490"></a>
<a name="IDX2491"></a>
</p>
<table>
<tr><td>
<p><code>acl_not_smtp</code></p></td><td><p> ACL for non-SMTP messages
</p></td></tr>
<tr><td>
<p><code>acl_not_smtp_mime</code></p></td><td><p> ACL for non-SMTP MIME parts
</p></td></tr>
<tr><td>
<p><code>acl_not_smtp_start</code></p></td><td><p> ACL at start of non-SMTP message
</p></td></tr>
<tr><td>
<p><code>acl_smtp_auth</code></p></td><td><p> ACL for AUTH
</p></td></tr>
<tr><td>
<p><code>acl_smtp_connect</code></p></td><td><p> ACL for start of SMTP connection
</p></td></tr>
<tr><td>
<p><code>acl_smtp_data</code></p></td><td><p> ACL after DATA is complete
</p></td></tr>
<tr><td>
<p><code>acl_smtp_etrn</code></p></td><td><p> ACL for ETRN
</p></td></tr>
<tr><td>
<p><code>acl_smtp_expn</code></p></td><td><p> ACL for EXPN
</p></td></tr>
<tr><td>
<p><code>acl_smtp_helo</code></p></td><td><p> ACL for HELO or EHLO
</p></td></tr>
<tr><td>
<p><code>acl_smtp_mail</code></p></td><td><p> ACL for MAIL
</p></td></tr>
<tr><td>
<p><code>acl_smtp_mailauth</code></p></td><td><p> ACL for the AUTH parameter of MAIL
</p></td></tr>
<tr><td>
<p><code>acl_smtp_mime</code></p></td><td><p> ACL for content-scanning MIME parts
</p></td></tr>
<tr><td>
<p><code>acl_smtp_notquit</code></p></td><td><p> ACL for non-QUIT terminations
</p></td></tr>
<tr><td>
<p><code>acl_smtp_predata</code></p></td><td><p> ACL at start of DATA command
</p></td></tr>
<tr><td>
<p><code>acl_smtp_quit</code></p></td><td><p> ACL for QUIT
</p></td></tr>
<tr><td>
<p><code>acl_smtp_rcpt</code></p></td><td><p> ACL for RCPT
</p></td></tr>
<tr><td>
<p><code>acl_smtp_starttls</code></p></td><td><p> ACL for STARTTLS
</p></td></tr>
<tr><td>
<p><code>acl_smtp_vrfy</code></p></td><td><p> ACL for VRFY
</p></td></tr>
</table>

<p>For example, if you set
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">acl_smtp_rcpt = small_acl
</pre></td></tr></table>

<p>the little ACL defined above is used whenever Exim receives a RCPT command
in an SMTP dialogue. The majority of policy tests on incoming messages can be
done when RCPT commands arrive. A rejection of RCPT should cause the
sending MTA to give up on the recipient address contained in the RCPT
command, whereas rejection at other times may cause the client MTA to keep on
trying to deliver the message. It is therefore recommended that you do as much
testing as possible at RCPT time.
</p>
<hr size="6">
<a name="The-non_002dSMTP-ACLs"></a>
<a name="SEC311"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC310" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC312" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.3 The non-SMTP ACLs </h2>

<p>The non-SMTP ACLs apply to all non-interactive incoming messages, that is, they
apply to batched SMTP as well as to non-SMTP messages. (Batched SMTP is not
really SMTP.) Many of the ACL conditions (for example, host tests, and tests on
the state of the SMTP connection such as encryption and authentication) are not
relevant and are forbidden in these ACLs. However, the sender and recipients
are known, so the <code>senders</code> and <code>sender_domains</code> conditions and the
<code>$sender_address</code> and <code>$recipients</code> variables can be used. Variables such as
<code>$authenticated_sender</code> are also available. You can specify added header lines
in any of these ACLs.
</p>
<p>The <code>acl_not_smtp_start</code> ACL is run right at the start of receiving a
non-SMTP message, before any of the message has been read. (This is the
analogue of the <code>acl_smtp_predata</code> ACL for SMTP input.) In the case of
batched SMTP input, it runs after the DATA command has been reached. The
result of this ACL is ignored; it cannot be used to reject a message. If you
really need to, you could set a value in an ACL variable here and reject based
on that in the <code>acl_not_smtp</code> ACL. However, this ACL can be used to set
controls, and in particular, it can be used to set
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">control = suppress_local_fixups
</pre></td></tr></table>

<p>This cannot be used in the other non-SMTP ACLs because by the time they are
run, it is too late.
</p>
<p>The <code>acl_not_smtp_mime</code> ACL is available only when Exim is compiled with the
content-scanning extension. For details, see chapter <a href="spec_41.html#SEC358">Content scanning at ACL time</a>.
</p>
<p>The <code>acl_not_smtp</code> ACL is run just before the <code>local_scan()</code> function. Any
kind of rejection is treated as permanent, because there is no way of sending a
temporary error for these kinds of message.
</p>
<hr size="6">
<a name="The-SMTP-connect-ACL"></a>
<a name="SEC312"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC311" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC313" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.4 The SMTP connect ACL </h2>

<p>The ACL test specified by <code>acl_smtp_connect</code> happens at the start of an SMTP
session, after the test specified by <code>host_reject_connection</code> (which is now
an anomaly) and any TCP Wrappers testing (if configured). If the connection is
accepted by an <code>accept</code> verb that has a <code>message</code> modifier, the contents of
the message override the banner message that is otherwise specified by the
<code>smtp_banner</code> option.
</p>
<hr size="6">
<a name="The-EHLO_002fHELO-ACL"></a>
<a name="SEC313"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC312" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC314" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.5 The EHLO/HELO ACL </h2>

<p>The ACL test specified by <code>acl_smtp_helo</code> happens when the client issues an
EHLO or HELO command, after the tests specified by <code>helo_accept_junk_hosts</code>,
<code>helo_allow_chars</code>, <code>helo_verify_hosts</code>, and <code>helo_try_verify_hosts</code>.
Note that a client may issue more than one EHLO or HELO command in an SMTP
session, and indeed is required to issue a new EHLO or HELO after successfully
setting up encryption following a STARTTLS command.
</p>
<p>If the command is accepted by an <code>accept</code> verb that has a <code>message</code>
modifier, the message may not contain more than one line (it will be truncated
at the first newline and a panic logged if it does). Such a message cannot
affect the EHLO options that are listed on the second and subsequent lines of
an EHLO response.
</p>
<hr size="6">
<a name="The-DATA-ACLs"></a>
<a name="SEC314"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC313" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC315" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.6 The DATA ACLs </h2>

<p>Two ACLs are associated with the DATA command, because it is two-stage
command, with two responses being sent to the client.
When the DATA command is received, the ACL defined by <code>acl_smtp_predata</code>
is obeyed. This gives you control after all the RCPT commands, but before
the message itself is received. It offers the opportunity to give a negative
response to the DATA command before the data is transmitted. Header lines
added by MAIL or RCPT ACLs are not visible at this time, but any that
are defined here are visible when the <code>acl_smtp_data</code> ACL is run.
</p>
<p>You cannot test the contents of the message, for example, to verify addresses
in the headers, at RCPT time or when the DATA command is received. Such
tests have to appear in the ACL that is run after the message itself has been
received, before the final response to the DATA command is sent. This is
the ACL specified by <code>acl_smtp_data</code>, which is the second ACL that is
associated with the DATA command.
</p>
<p>For both of these ACLs, it is not possible to reject individual recipients. An
error response rejects the entire message. Unfortunately, it is known that some
MTAs do not treat hard (5<em>xx</em>) responses to the DATA command (either
before or after the data) correctly - they keep the message on their queues
and try again later, but that is their problem, though it does waste some of
your resources.
</p>
<hr size="6">
<a name="The-SMTP-MIME-ACL"></a>
<a name="SEC315"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC314" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC316" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.7 The SMTP MIME ACL </h2>

<p>The <code>acl_smtp_mime</code> option is available only when Exim is compiled with the
content-scanning extension. For details, see chapter <a href="spec_41.html#SEC358">Content scanning at ACL time</a>.
</p>
<hr size="6">
<a name="The-QUIT-ACL"></a>
<a name="SEC316"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC315" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC317" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.8 The QUIT ACL </h2>

<p>The ACL for the SMTP QUIT command is anomalous, in that the outcome of the ACL
does not affect the response code to QUIT, which is always 221. Thus, the ACL
does not in fact control any access. For this reason, the only verbs that are
permitted are <code>accept</code> and <code>warn</code>.
</p>
<p>This ACL can be used for tasks such as custom logging at the end of an SMTP
session. For example, you can use ACL variables in other ACLs to count
messages, recipients, etc., and log the totals at QUIT time using one or
more <code>logwrite</code> modifiers on a <code>warn</code> verb.
</p>
<p><strong>Warning</strong>: Only the <code>$acl_c</code><em>x</em> variables can be used for this, because
the <code>$acl_m</code><em>x</em> variables are reset at the end of each incoming message.
</p>
<p>You do not need to have a final <code>accept</code>, but if you do, you can use a
<code>message</code> modifier to specify custom text that is sent as part of the 221
response to QUIT.
</p>
<p>This ACL is run only for a &quot;normal&quot; QUIT. For certain kinds of disastrous
failure (for example, failure to open a log file, or when Exim is bombing out
because it has detected an unrecoverable error), all SMTP commands from the
client are given temporary error responses until QUIT is received or the
connection is closed. In these special cases, the QUIT ACL does not run.
</p>
<hr size="6">
<a name="The-not_002dQUIT-ACL"></a>
<a name="SEC317"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC316" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC318" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.9 The not-QUIT ACL </h2>

<p>The not-QUIT ACL, specified by <code>smtp_notquit_acl</code>, is run in most cases when
an SMTP session ends without sending QUIT. However, when Exim itself is is bad
trouble, such as being unable to write to its log files, this ACL is not run,
because it might try to do things (such as write to log files) that make the
situation even worse.
</p>
<p>Like the QUIT ACL, this ACL is provided to make it possible to do customized
logging or to gather statistics, and its outcome is ignored. The <code>delay</code>
modifier is forbidden in this ACL, and the only permitted verbs are <code>accept</code>
and <code>warn</code>.
</p>
<a name="IDX2492"></a>
<p>When the not-QUIT ACL is running, the variable <code>$smtp_notquit_reason</code> is set
to a string that indicates the reason for the termination of the SMTP
connection. The possible values are:
</p>
<table>
<tr><td>
<p>&lsquo;<samp>acl-drop</samp>&rsquo;</p></td><td><p> Another ACL issued a <code>drop</code> command
</p></td></tr>
<tr><td>
<p>&lsquo;<samp>bad-commands</samp>&rsquo;</p></td><td><p> Too many unknown or non-mail commands
</p></td></tr>
<tr><td>
<p>&lsquo;<samp>command-timeout</samp>&rsquo;</p></td><td><p> Timeout while reading SMTP commands
</p></td></tr>
<tr><td>
<p>&lsquo;<samp>connection-lost</samp>&rsquo;</p></td><td><p> The SMTP connection has been lost
</p></td></tr>
<tr><td>
<p>&lsquo;<samp>data-timeout</samp>&rsquo;</p></td><td><p> Timeout while reading message data
</p></td></tr>
<tr><td>
<p>&lsquo;<samp>local-scan-error</samp>&rsquo;</p></td><td><p> The <code>local_scan()</code> function crashed
</p></td></tr>
<tr><td>
<p>&lsquo;<samp>local-scan-timeout</samp>&rsquo;</p></td><td><p> The <code>local_scan()</code> function timed out
</p></td></tr>
<tr><td>
<p>&lsquo;<samp>signal-exit</samp>&rsquo;</p></td><td><p> SIGTERM or SIGINT
</p></td></tr>
<tr><td>
<p>&lsquo;<samp>synchronization-error</samp>&rsquo;</p></td><td><p> SMTP synchronization error
</p></td></tr>
<tr><td>
<p>&lsquo;<samp>tls-failed</samp>&rsquo;</p></td><td><p> TLS failed to start
</p></td></tr>
</table>

<p>In most cases when an SMTP connection is closed without having received QUIT,
Exim sends an SMTP response message before actually closing the connection.
With the exception of the &lsquo;<samp>acl-drop</samp>&rsquo; case, the default message can be
overridden by the <code>message</code> modifier in the not-QUIT ACL. In the case of a
<code>drop</code> verb in another ACL, it is the message from the other ACL that is
used.
</p>
<hr size="6">
<a name="Finding-an-ACL-to-use"></a>
<a name="SEC318"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC317" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC319" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.10 Finding an ACL to use </h2>

<p>The value of an <code>acl_smtp_</code><em>xxx</em> option is expanded before use, so
you can use different ACLs in different circumstances. For example,
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">acl_smtp_rcpt = ${if ={25}{$interface_port} \
                     {acl_check_rcpt} {acl_check_rcpt_submit} }
</pre></td></tr></table>

<p>In the default configuration file there are some example settings for
providing an RFC 4409 message submission service on port 587 and a
non-standard &quot;smtps&quot; service on port 465. You can use a string
expansion like this to choose an ACL for MUAs on these ports which is
more appropriate for this purpose than the default ACL on port 25.
</p>
<p>The expanded string does not have to be the name of an ACL in the
configuration file; there are other possibilities. Having expanded the
string, Exim searches for an ACL as follows:
</p>
<ul class="toc">
<li>
If the string begins with a slash, Exim uses it as a file name, and reads its
contents as an ACL. The lines are processed in the same way as lines in the
Exim configuration file. In particular, continuation lines are supported, blank
lines are ignored, as are lines whose first non-whitespace character is &quot;#&quot;.
If the file does not exist or cannot be read, an error occurs (typically
causing a temporary failure of whatever caused the ACL to be run). For example:

<table><tr><td>&nbsp;</td><td><pre class="example">acl_smtp_data = /etc/acls/\
  ${lookup{$sender_host_address}lsearch\
  {/etc/acllist}{$value}{default}}
</pre></td></tr></table>

<p>This looks up an ACL file to use on the basis of the host's IP address, falling
back to a default if the lookup fails. If an ACL is successfully read from a
file, it is retained in memory for the duration of the Exim process, so that it
can be re-used without having to re-read the file.
</p>
</li><li>
If the string does not start with a slash, and does not contain any spaces,
Exim searches the ACL section of the configuration for an ACL whose name
matches the string.

</li><li>
If no named ACL is found, or if the string contains spaces, Exim parses
the string as an inline ACL. This can save typing in cases where you just
want to have something like

<table><tr><td>&nbsp;</td><td><pre class="example">acl_smtp_vrfy = accept
</pre></td></tr></table>

<p>in order to allow free use of the VRFY command. Such a string may contain
newlines; it is processed in the same way as an ACL that is read from a file.
</p></li></ul>

<hr size="6">
<a name="ACL-return-codes"></a>
<a name="SEC319"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC318" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC320" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.11 ACL return codes </h2>

<p>Except for the QUIT ACL, which does not affect the SMTP return code (see
section <a href="#SEC316">The QUIT ACL</a> above), the result of running an ACL is either
&quot;accept&quot; or &quot;deny&quot;, or, if some test cannot be completed (for example, if a
database is down), &quot;defer&quot;. These results cause 2<em>xx</em>, 5<em>xx</em>, and 4<em>xx</em>
return codes, respectively, to be used in the SMTP dialogue. A fourth return,
&quot;error&quot;, occurs when there is an error such as invalid syntax in the ACL.
This also causes a 4<em>xx</em> return code.
</p>
<p>For the non-SMTP ACL, &quot;defer&quot; and &quot;error&quot; are treated in the same way as
&quot;deny&quot;, because there is no mechanism for passing temporary errors to the
submitters of non-SMTP messages.
</p>
<p>ACLs that are relevant to message reception may also return &quot;discard&quot;. This
has the effect of &quot;accept&quot;, but causes either the entire message or an
individual recipient address to be discarded. In other words, it is a
blackholing facility. Use it with care.
</p>
<p>If the ACL for MAIL returns &quot;discard&quot;, all recipients are discarded, and no
ACL is run for subsequent RCPT commands. The effect of &quot;discard&quot; in a
RCPT ACL is to discard just the one recipient address. If there are no
recipients left when the message's data is received, the DATA ACL is not
run. A &quot;discard&quot; return from the DATA or the non-SMTP ACL discards all the
remaining recipients. The &quot;discard&quot; return is not permitted for the
<code>acl_smtp_predata</code> ACL.
</p>
<a name="IDX2493"></a>
<p>The <code>local_scan()</code> function is always run, even if there are no remaining
recipients; it may create new recipients.
</p>
<hr size="6">
<a name="Unset-ACL-options"></a>
<a name="SEC320"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC319" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC321" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.12 Unset ACL options </h2>

<p>The default actions when any of the <code>acl_</code><em>xxx</em> options are unset are not
all the same. <strong>Note</strong>: These defaults apply only when the relevant ACL is
not defined at all. For any defined ACL, the default action when control
reaches the end of the ACL statements is &quot;deny&quot;.
</p>
<p>For <code>acl_smtp_quit</code> and <code>acl_not_smtp_start</code> there is no default because
these two are ACLs that are used only for their side effects. They cannot be
used to accept or reject anything.
</p>
<p>For <code>acl_not_smtp</code>, <code>acl_smtp_auth</code>, <code>acl_smtp_connect</code>,
<code>acl_smtp_data</code>, <code>acl_smtp_helo</code>, <code>acl_smtp_mail</code>, <code>acl_smtp_mailauth</code>,
<code>acl_smtp_mime</code>, <code>acl_smtp_predata</code>, and <code>acl_smtp_starttls</code>, the action
when the ACL is not defined is &quot;accept&quot;.
</p>
<p>For the others (<code>acl_smtp_etrn</code>, <code>acl_smtp_expn</code>, <code>acl_smtp_rcpt</code>, and
<code>acl_smtp_vrfy</code>), the action when the ACL is not defined is &quot;deny&quot;.
This means that <code>acl_smtp_rcpt</code> must be defined in order to receive any
messages over an SMTP connection. For an example, see the ACL in the default
configuration file.
</p>
<hr size="6">
<a name="Data-for-message-ACLs"></a>
<a name="SEC321"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC320" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC322" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.13 Data for message ACLs </h2>

<p>When a MAIL or RCPT ACL, or either of the DATA ACLs, is running, the variables
that contain information about the host and the message's sender (for example,
<code>$sender_host_address</code> and <code>$sender_address</code>) are set, and can be used in ACL
statements. In the case of RCPT (but not MAIL or DATA), <code>$domain</code> and
<code>$local_part</code> are set from the argument address. The entire SMTP command
is available in <code>$smtp_command</code>.
</p>
<p>When an ACL for the AUTH parameter of MAIL is running, the variables that
contain information about the host are set, but <code>$sender_address</code> is not yet
set. Section <a href="spec_33.html#SEC274">The AUTH parameter on MAIL commands</a> contains a discussion of this parameter and
how it is used.
</p>
<a name="IDX2494"></a>
<p>The <code>$message_size</code> variable is set to the value of the SIZE parameter on
the MAIL command at MAIL, RCPT and pre-data time, or to -1 if
that parameter is not given. The value is updated to the true message size by
the time the final DATA ACL is run (after the message data has been
received).
</p>
<a name="IDX2495"></a>
<a name="IDX2496"></a>
<p>The <code>$rcpt_count</code> variable increases by one for each RCPT command received.
The <code>$recipients_count</code> variable increases by one each time a RCPT command is
accepted, so while an ACL for RCPT is being processed, it contains the number
of previously accepted recipients. At DATA time (for both the DATA ACLs),
<code>$rcpt_count</code> contains the total number of RCPT commands, and
<code>$recipients_count</code> contains the total number of accepted recipients.
</p>
<hr size="6">
<a name="Data-for-non_002dmessage-ACLs"></a>
<a name="SEC322"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC321" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC323" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.14 Data for non-message ACLs </h2>

<p>When an ACL is being run for AUTH, EHLO, ETRN, EXPN, HELO, STARTTLS, or VRFY,
the remainder of the SMTP command line is placed in <code>$smtp_command_argument</code>,
and the entire SMTP command is available in <code>$smtp_command</code>.
These variables can be tested using a <code>condition</code> condition. For example,
here is an ACL for use with AUTH, which insists that either the session is
encrypted, or the CRAM-MD5 authentication method is used. In other words, it
does not permit authentication methods that use cleartext passwords on
unencrypted connections.
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">acl_check_auth:
  accept encrypted = *
  accept condition = ${if eq{${uc:$smtp_command_argument}}\
                     {CRAM-MD5}}
  deny   message   = TLS encryption or CRAM-MD5 required
</pre></td></tr></table>

<p>(Another way of applying this restriction is to arrange for the authenticators
that use cleartext passwords not to be advertised when the connection is not
encrypted. You can use the generic <code>server_advertise_condition</code> authenticator
option to do this.)
</p>
<hr size="6">
<a name="Format-of-an-ACL"></a>
<a name="SEC323"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC322" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC324" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.15 Format of an ACL </h2>

<p>An individual ACL consists of a number of statements. Each statement starts
with a verb, optionally followed by a number of conditions and &quot;modifiers&quot;.
Modifiers can change the way the verb operates, define error and log messages,
set variables, insert delays, and vary the processing of accepted messages.
</p>
<p>If all the conditions are met, the verb is obeyed. The same condition may be
used (with different arguments) more than once in the same statement. This
provides a means of specifying an &quot;and&quot; conjunction between conditions. For
example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny  dnslists = list1.example
dnslists = list2.example
</pre></td></tr></table>

<p>If there are no conditions, the verb is always obeyed. Exim stops evaluating
the conditions and modifiers when it reaches a condition that fails. What
happens then depends on the verb (and in one case, on a special modifier). Not
all the conditions make sense at every testing point. For example, you cannot
test a sender address in the ACL that is run for a VRFY command.
</p>
<hr size="6">
<a name="ACL-verbs"></a>
<a name="SEC324"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC323" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC325" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.16 ACL verbs </h2>

<p>The ACL verbs are as follows:
</p>
<ul class="toc">
<li>
<a name="IDX2497"></a>
<code>accept</code>: If all the conditions are met, the ACL returns &quot;accept&quot;. If any
of the conditions are not met, what happens depends on whether <code>endpass</code>
appears among the conditions (for syntax see below). If the failing condition
is before <code>endpass</code>, control is passed to the next ACL statement; if it is
after <code>endpass</code>, the ACL returns &quot;deny&quot;. Consider this statement, used to
check a RCPT command:

<table><tr><td>&nbsp;</td><td><pre class="example">accept domains = +local_domains
endpass
verify = recipient
</pre></td></tr></table>

<p>If the recipient domain does not match the <code>domains</code> condition, control
passes to the next statement. If it does match, the recipient is verified, and
the command is accepted if verification succeeds. However, if verification
fails, the ACL yields &quot;deny&quot;, because the failing condition is after
<code>endpass</code>.
</p>
<p>The <code>endpass</code> feature has turned out to be confusing to many people, so its
use is not recommended nowadays. It is always possible to rewrite an ACL so
that <code>endpass</code> is not needed, and it is no longer used in the default
configuration.
</p>
<a name="IDX2498"></a>
<p>If a <code>message</code> modifier appears on an <code>accept</code> statement, its action
depends on whether or not <code>endpass</code> is present. In the absence of <code>endpass</code>
(when an <code>accept</code> verb either accepts or passes control to the next
statement), <code>message</code> can be used to vary the message that is sent when an
SMTP command is accepted. For example, in a RCPT ACL you could have:
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">accept  &lt;some conditions&gt;
        message = OK, I will allow you through today
</pre></td></tr></table>

<p>You can specify an SMTP response code, optionally followed by an &quot;extended
response code&quot; at the start of the message, but the first digit must be the
same as would be sent by default, which is 2 for an <code>accept</code> verb.
</p>
<p>If <code>endpass</code> is present in an <code>accept</code> statement, <code>message</code> specifies
an error message that is used when access is denied. This behaviour is retained
for backward compatibility, but current &quot;best practice&quot; is to avoid the use
of <code>endpass</code>.
</p>
</li><li>
<a name="IDX2499"></a>
<code>defer</code>: If all the conditions are true, the ACL returns &quot;defer&quot; which, in
an SMTP session, causes a 4<em>xx</em> response to be given. For a non-SMTP ACL,
<code>defer</code> is the same as <code>deny</code>, because there is no way of sending a
temporary error. For a RCPT command, <code>defer</code> is much the same as using a
<code>redirect</code> router and &lsquo;<samp>:defer:</samp>&rsquo; while verifying, but the <code>defer</code> verb can
be used in any ACL, and even for a recipient it might be a simpler approach.

</li><li>
<a name="IDX2500"></a>
<code>deny</code>: If all the conditions are met, the ACL returns &quot;deny&quot;. If any of
the conditions are not met, control is passed to the next ACL statement. For
example,

<table><tr><td>&nbsp;</td><td><pre class="example">deny dnslists = blackholes.mail-abuse.org
</pre></td></tr></table>

<p>rejects commands from hosts that are on a DNS black list.
</p>
</li><li>
<a name="IDX2501"></a>
<code>discard</code>: This verb behaves like <code>accept</code>, except that it returns
&quot;discard&quot; from the ACL instead of &quot;accept&quot;. It is permitted only on ACLs
that are concerned with receiving messages. When all the conditions are true,
the sending entity receives a &quot;success&quot; response. However, <code>discard</code> causes
recipients to be discarded. If it is used in an ACL for RCPT, just the one
recipient is discarded; if used for MAIL, DATA or in the non-SMTP ACL, all the
message's recipients are discarded. Recipients that are discarded before DATA
do not appear in the log line when the <code>log_recipients</code> log selector is set.

<p>If the <code>log_message</code> modifier is set when <code>discard</code> operates,
its contents are added to the line that is automatically written to the log.
The <code>message</code> modifier operates exactly as it does for <code>accept</code>.
</p>
</li><li>
<a name="IDX2502"></a>
<code>drop</code>: This verb behaves like <code>deny</code>, except that an SMTP connection is
forcibly closed after the 5<em>xx</em> error message has been sent. For example:

<table><tr><td>&nbsp;</td><td><pre class="example">drop   message   = I don't take more than 20 RCPTs
       condition = ${if &gt; {$rcpt_count}{20}}
</pre></td></tr></table>

<p>There is no difference between <code>deny</code> and <code>drop</code> for the connect-time ACL.
The connection is always dropped after sending a 550 response.
</p>
</li><li>
<a name="IDX2503"></a>
<code>require</code>: If all the conditions are met, control is passed to the next ACL
statement. If any of the conditions are not met, the ACL returns &quot;deny&quot;. For
example, when checking a RCPT command,

<table><tr><td>&nbsp;</td><td><pre class="example">require message = Sender did not verify
        verify  = sender
</pre></td></tr></table>

<p>passes control to subsequent statements only if the message's sender can be
verified. Otherwise, it rejects the command. Note the positioning of the
<code>message</code> modifier, before the <code>verify</code> condition. The reason for this is
discussed in section <a href="#SEC326">Condition and modifier processing</a>.
</p>
</li><li>
<a name="IDX2504"></a>
<code>warn</code>: If all the conditions are true, a line specified by the
<code>log_message</code> modifier is written to Exim's main log. Control always passes
to the next ACL statement. If any condition is false, the log line is not
written. If an identical log line is requested several times in the same
message, only one copy is actually written to the log. If you want to force
duplicates to be written, use the <code>logwrite</code> modifier instead.

<p>If <code>log_message</code> is not present, a <code>warn</code> verb just checks its conditions
and obeys any &quot;immediate&quot; modifiers (such as <code>control</code>, <code>set</code>,
<code>logwrite</code>, and <code>add_header</code>) that appear before the first failing
condition. There is more about adding header lines in section
<a href="#SEC330">Adding header lines in ACLs</a>.
</p>
<p>If any condition on a <code>warn</code> statement cannot be completed (that is, there is
some sort of defer), the log line specified by <code>log_message</code> is not written.
This does not include the case of a forced failure from a lookup, which
is considered to be a successful completion. After a defer, no further
conditions or modifiers in the <code>warn</code> statement are processed. The incident
is logged, and the ACL continues to be processed, from the next statement
onwards.
</p>
<a name="IDX2505"></a>
<p>When one of the <code>warn</code> conditions is an address verification that fails, the
text of the verification failure message is in <code>$acl_verify_message</code>. If you
want this logged, you must set it up explicitly. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">warn   !verify = sender
       log_message = sender verify failed: $acl_verify_message
</pre></td></tr></table>
</li></ul>

<p>At the end of each ACL there is an implicit unconditional <code>deny</code>.
</p>
<p>As you can see from the examples above, the conditions and modifiers are
written one to a line, with the first one on the same line as the verb, and
subsequent ones on following lines. If you have a very long condition, you can
continue it onto several physical lines by the usual backslash continuation
mechanism. It is conventional to align the conditions vertically.
</p>
<hr size="6">
<a name="ACL-variables"></a>
<a name="SEC325"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC324" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC326" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.17 ACL variables </h2>

<p>There are some special variables that can be set during ACL processing. They
can be used to pass information between different ACLs, different invocations
of the same ACL in the same SMTP connection, and between ACLs and the routers,
transports, and filters that are used to deliver a message. The names of these
variables must begin with <code>$acl_c</code> or <code>$acl_m</code>, followed either by a digit or
an underscore, but the remainder of the name can be any sequence of
alphanumeric characters and underscores that you choose. There is no limit on
the number of ACL variables. The two sets act as follows:
</p>
<ul class="toc">
<li>
The values of those variables whose names begin with <code>$acl_c</code> persist
throughout an SMTP connection. They are never reset. Thus, a value that is set
while receiving one message is still available when receiving the next message
on the same SMTP connection.

</li><li>
The values of those variables whose names begin with <code>$acl_m</code> persist only
while a message is being received. They are reset afterwards. They are also
reset by MAIL, RSET, EHLO, HELO, and after starting up a TLS session.
</li></ul>

<p>When a message is accepted, the current values of all the ACL variables are
preserved with the message and are subsequently made available at delivery
time. The ACL variables are set by a modifier called <code>set</code>. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">accept hosts = whatever
       set acl_m4 = some value
accept authenticated = *
       set acl_c_auth = yes
</pre></td></tr></table>

<p><strong>Note</strong>: A leading dollar sign is not used when naming a variable that is to
be set. If you want to set a variable without taking any action, you can use a
<code>warn</code> verb without any other modifiers or conditions.
</p>
<a name="IDX2506"></a>
<p>What happens if a syntactically valid but undefined ACL variable is
referenced depends on the setting of the <code>strict_acl_vars</code> option. If it is
false (the default), an empty string is substituted; if it is true, an
error is generated.
</p>
<p>Versions of Exim before 4.64 have a limited set of numbered variables, but
their names are compatible, so there is no problem with upgrading.
</p>
<hr size="6">
<a name="Condition-and-modifier-processing"></a>
<a name="SEC326"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC325" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC327" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.18 Condition and modifier processing </h2>

<p>An exclamation mark preceding a condition negates its result. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny   domains = *.dom.example
      !verify  = recipient
</pre></td></tr></table>

<p>causes the ACL to return &quot;deny&quot; if the recipient domain ends in
<em>dom.example</em> and the recipient address cannot be verified. Sometimes
negation can be used on the right-hand side of a condition. For example, these
two statements are equivalent:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny  hosts = !192.168.3.4
deny !hosts =  192.168.3.4
</pre></td></tr></table>

<p>However, for many conditions (<code>verify</code> being a good example), only left-hand
side negation of the whole condition is possible.
</p>
<p>The arguments of conditions and modifiers are expanded. A forced failure
of an expansion causes a condition to be ignored, that is, it behaves as if the
condition is true. Consider these two statements:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">accept  senders = ${lookup{$host_name}lsearch\
                  {/some/file}{$value}fail}
accept  senders = ${lookup{$host_name}lsearch\
                  {/some/file}{$value}{}}
</pre></td></tr></table>

<p>Each attempts to look up a list of acceptable senders. If the lookup succeeds,
the returned list is searched, but if the lookup fails the behaviour is
different in the two cases. The <code>fail</code> in the first statement causes the
condition to be ignored, leaving no further conditions. The <code>accept</code> verb
therefore succeeds. The second statement, however, generates an empty list when
the lookup fails. No sender can match an empty list, so the condition fails,
and therefore the <code>accept</code> also fails.
</p>
<p>ACL modifiers appear mixed in with conditions in ACL statements. Some of them
specify actions that are taken as the conditions for a statement are checked;
others specify text for messages that are used when access is denied or a
warning is generated. The <code>control</code> modifier affects the way an incoming
message is handled.
</p>
<p>The positioning of the modifiers in an ACL statement important, because the
processing of a verb ceases as soon as its outcome is known. Only those
modifiers that have already been encountered will take effect. For example,
consider this use of the <code>message</code> modifier:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">require message = Can't verify sender
        verify  = sender
        message = Can't verify recipient
        verify  = recipient
        message = This message cannot be used
</pre></td></tr></table>

<p>If sender verification fails, Exim knows that the result of the statement is
&quot;deny&quot;, so it goes no further. The first <code>message</code> modifier has been seen,
so its text is used as the error message. If sender verification succeeds, but
recipient verification fails, the second message is used. If recipient
verification succeeds, the third message becomes &quot;current&quot;, but is never used
because there are no more conditions to cause failure.
</p>
<p>For the <code>deny</code> verb, on the other hand, it is always the last <code>message</code>
modifier that is used, because all the conditions must be true for rejection to
happen. Specifying more than one <code>message</code> modifier does not make sense, and
the message can even be specified after all the conditions. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny   hosts = ...
      !senders = *@my.domain.example
       message = Invalid sender from client host
</pre></td></tr></table>

<p>The &quot;deny&quot; result does not happen until the end of the statement is reached,
by which time Exim has set up the message.
</p>
<hr size="6">
<a name="ACL-modifiers"></a>
<a name="SEC327"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC326" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC328" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.19 ACL modifiers </h2>

<p>The ACL modifiers are as follows:
</p>
<dl compact="compact">
<dt> <strong>add_header</strong>=&lt;<em>text</em>&gt;</dt>
<dd><p>This modifier specifies one or more header lines that are to be added to an
incoming message, assuming, of course, that the message is ultimately
accepted. For details, see section <a href="#SEC330">Adding header lines in ACLs</a>.
</p>
</dd>
<dt> <strong>continue</strong>=&lt;<em>text</em>&gt;</dt>
<dd><a name="IDX2507"></a>
<a name="IDX2508"></a>
<p>This modifier does nothing of itself, and processing of the ACL always
continues with the next condition or modifier. The value of <code>continue</code> is in
the side effects of expanding its argument. Typically this could be used to
update a database. It is really just a syntactic tidiness, to avoid having to
write rather ugly lines like this:
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">condition = ${if eq{0}{&lt;some expansion&gt;}{true}{true}}
</pre></td></tr></table>

<p>Instead, all you need is
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">continue = &lt;some expansion&gt;
</pre></td></tr></table>

</dd>
<dt> <strong>control</strong>=&lt;<em>text</em>&gt;</dt>
<dd><a name="IDX2509"></a>
<p>This modifier affects the subsequent processing of the SMTP connection or of an
incoming message that is accepted. The effect of the first type of control
lasts for the duration of the connection, whereas the effect of the second type
lasts only until the current message has been received. The message-specific
controls always apply to the whole message, not to individual recipients,
even if the <code>control</code> modifier appears in a RCPT ACL.
</p>
<p>As there are now quite a few controls that can be applied, they are described
separately in section <a href="#SEC328">Use of the control modifier</a>. The <code>control</code> modifier can be used
in several different ways. For example:
</p>
<ul class="toc">
<li>
It can be at the end of an <code>accept</code> statement:

<table><tr><td>&nbsp;</td><td><pre class="example">    accept  ...some conditions
            control = queue_only
</pre></td></tr></table>

<p>In this case, the control is applied when this statement yields &quot;accept&quot;, in
other words, when the conditions are all true.
</p>
</li><li>
It can be in the middle of an <code>accept</code> statement:

<table><tr><td>&nbsp;</td><td><pre class="example">    accept  ...some conditions...
            control = queue_only
            ...some more conditions...
</pre></td></tr></table>

<p>If the first set of conditions are true, the control is applied, even if the
statement does not accept because one of the second set of conditions is false.
In this case, some subsequent statement must yield &quot;accept&quot; for the control
to be relevant.
</p>
</li><li>
It can be used with <code>warn</code> to apply the control, leaving the
decision about accepting or denying to a subsequent verb. For
example:

<table><tr><td>&nbsp;</td><td><pre class="example">    warn    ...some conditions...
            control = freeze
    accept  ...
</pre></td></tr></table>

<p>This example of <code>warn</code> does not contain <code>message</code>, <code>log_message</code>, or
<code>logwrite</code>, so it does not add anything to the message and does not write a
log entry.
</p>
</li><li>
If you want to apply a control unconditionally, you can use it with a
<code>require</code> verb. For example:

<table><tr><td>&nbsp;</td><td><pre class="example">    require  control = no_multiline_responses
</pre></td></tr></table>
</li></ul>

</dd>
<dt> <strong>delay</strong>=&lt;<em>time</em>&gt;</dt>
<dd><a name="IDX2510"></a>
<a name="IDX2511"></a>
<p>This modifier may appear in any ACL. It causes Exim to wait for the time
interval before proceeding. However, when testing Exim using the <code>-bh</code>
option, the delay is not actually imposed (an appropriate message is output
instead). The time is given in the usual Exim notation, and the delay happens
as soon as the modifier is processed. In an SMTP session, pending output is
flushed before the delay is imposed.
</p>
<p>Like <code>control</code>, <code>delay</code> can be used with <code>accept</code> or <code>deny</code>, for
example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny    ...some conditions...
        delay = 30s
</pre></td></tr></table>

<p>The delay happens if all the conditions are true, before the statement returns
&quot;deny&quot;. Compare this with:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny    delay = 30s
        ...some conditions...
</pre></td></tr></table>

<p>which waits for 30s before processing the conditions. The <code>delay</code> modifier
can also be used with <code>warn</code> and together with <code>control</code>:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">warn    ...some conditions...
        delay = 2m
        control = freeze
accept  ...
</pre></td></tr></table>

<p>If <code>delay</code> is encountered when the SMTP PIPELINING extension is in use,
responses to several commands are no longer buffered and sent in one packet (as
they would normally be) because all output is flushed before imposing the
delay. This optimization is disabled so that a number of small delays do not
appear to the client as one large aggregated delay that might provoke an
unwanted timeout. You can, however, disable output flushing for <code>delay</code> by
using a <code>control</code> modifier to set <code>no_delay_flush</code>.
</p>
</dd>
<dt> <strong>endpass</strong></dt>
<dd><a name="IDX2512"></a>
<p>This modifier, which has no argument, is recognized only in <code>accept</code> and
<code>discard</code> statements. It marks the boundary between the conditions whose
failure causes control to pass to the next statement, and the conditions whose
failure causes the ACL to return &quot;deny&quot;. This concept has proved to be
confusing to some people, so the use of <code>endpass</code> is no longer recommended as
&quot;best practice&quot;. See the description of <code>accept</code> above for more details.
</p>
</dd>
<dt> <strong>log_message</strong>=&lt;<em>text</em>&gt;</dt>
<dd><a name="IDX2513"></a>
<p>This modifier sets up a message that is used as part of the log message if the
ACL denies access or a <code>warn</code> statement's conditions are true. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">require log_message = wrong cipher suite $tls_cipher
        encrypted   = DES-CBC3-SHA
</pre></td></tr></table>

<p><code>log_message</code> is also used when recipients are discarded by <code>discard</code>. For
example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">discard &lt;some conditions&gt;
        log_message = Discarded $local_part@$domain because...
</pre></td></tr></table>

<p>When access is denied, <code>log_message</code> adds to any underlying error message
that may exist because of a condition failure. For example, while verifying a
recipient address, a <em>:fail:</em> redirection might have already set up a
message.
</p>
<p>The message may be defined before the conditions to which it applies, because
the string expansion does not happen until Exim decides that access is to be
denied. This means that any variables that are set by the condition are
available for inclusion in the message. For example, the <code>$dnslist_</code>&lt;<em>xxx</em>&gt;
variables are set after a DNS black list lookup succeeds. If the expansion of
<code>log_message</code> fails, or if the result is an empty string, the modifier is
ignored.
</p>
<a name="IDX2514"></a>
<p>If you want to use a <code>warn</code> statement to log the result of an address
verification, you can use <code>$acl_verify_message</code> to include the verification
error message.
</p>
<p>If <code>log_message</code> is used with a <code>warn</code> statement, &quot;Warning:&quot; is added to
the start of the logged message. If the same warning log message is requested
more than once while receiving  a single email message, only one copy is
actually logged. If you want to log multiple copies, use <code>logwrite</code> instead
of <code>log_message</code>. In the absence of <code>log_message</code> and <code>logwrite</code>, nothing
is logged for a successful <code>warn</code> statement.
</p>
<p>If <code>log_message</code> is not present and there is no underlying error message (for
example, from the failure of address verification), but <code>message</code> is present,
the <code>message</code> text is used for logging rejections. However, if any text for
logging contains newlines, only the first line is logged. In the absence of
both <code>log_message</code> and <code>message</code>, a default built-in message is used for
logging rejections.
</p>
</dd>
<dt> <strong>log_reject_target</strong>=&lt;<em>log name list</em>&gt;</dt>
<dd><a name="IDX2515"></a>
<a name="IDX2516"></a>
<p>This modifier makes it possible to specify which logs are used for messages
about ACL rejections. Its argument is a colon-separated list of words that can
be &quot;main&quot;, &quot;reject&quot;, or &quot;panic&quot;. The default is &lsquo;<samp>main:reject</samp>&rsquo;. The list
may be empty, in which case a rejection is not logged at all. For example, this
ACL fragment writes no logging information when access is denied:
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">deny &lt;some conditions&gt;
     log_reject_target =
</pre></td></tr></table>

<p>This modifier can be used in SMTP and non-SMTP ACLs. It applies to both
permanent and temporary rejections.
</p>
</dd>
<dt> <strong>logwrite</strong>=&lt;<em>text</em>&gt;</dt>
<dd><a name="IDX2517"></a>
<a name="IDX2518"></a>
<p>This modifier writes a message to a log file as soon as it is encountered when
processing an ACL. (Compare <code>log_message</code>, which, except in the case of
<code>warn</code> and <code>discard</code>, is used only if the ACL statement denies
access.) The <code>logwrite</code> modifier can be used to log special incidents in
ACLs. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">accept &lt;some special conditions&gt;
       control  = freeze
       logwrite = froze message because ...
</pre></td></tr></table>

<p>By default, the message is written to the main log. However, it may begin
with a colon, followed by a comma-separated list of log names, and then
another colon, to specify exactly which logs are to be written. For
example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">logwrite = :main,reject: text for main and reject logs
logwrite = :panic: text for panic log only
</pre></td></tr></table>

</dd>
<dt> <strong>message</strong>=&lt;<em>text</em>&gt;</dt>
<dd><a name="IDX2519"></a>
<p>This modifier sets up a text string that is expanded and used as a response
message when an ACL statement terminates the ACL with an &quot;accept&quot;, &quot;deny&quot;,
or &quot;defer&quot; response. (In the case of the <code>accept</code> and <code>discard</code> verbs,
there is some complication if <code>endpass</code> is involved; see the description of
<code>accept</code> for details.)
</p>
<p>The expansion of the message happens at the time Exim decides that the ACL is
to end, not at the time it processes <code>message</code>. If the expansion fails, or
generates an empty string, the modifier is ignored. Here is an example where
<code>message</code> must be specified first, because the ACL ends with a rejection if
the <code>hosts</code> condition fails:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">require  message = Host not recognized
         hosts = 10.0.0.0/8
</pre></td></tr></table>

<p>(Once a condition has failed, no further conditions or modifiers are
processed.)
</p>
<a name="IDX2520"></a>
<a name="IDX2521"></a>
<p>For ACLs that are triggered by SMTP commands, the message is returned as part
of the SMTP response. The use of <code>message</code> with <code>accept</code> (or <code>discard</code>)
is meaningful only for SMTP, as no message is returned when a non-SMTP message
is accepted. In the case of the connect ACL, accepting with a message modifier
overrides the value of <code>smtp_banner</code>. For the EHLO/HELO ACL, a customized
accept message may not contain more than one line (otherwise it will be
truncated at the first newline and a panic logged), and it cannot affect the
EHLO options.
</p>
<p>When SMTP is involved, the message may begin with an overriding response code,
consisting of three digits optionally followed by an &quot;extended response code&quot;
of the form <em>n.n.n</em>, each code being followed by a space. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny  message = 599 1.2.3 Host not welcome
      hosts = 192.168.34.0/24
</pre></td></tr></table>

<p>The first digit of the supplied response code must be the same as would be sent
by default. A panic occurs if it is not. Exim uses a 550 code when it denies
access, but for the predata ACL, note that the default success code is 354, not
2<em>xx</em>.
</p>
<p>Notwithstanding the previous paragraph, for the QUIT ACL, unlike the others,
the message modifier cannot override the 221 response code.
</p>
<p>The text in a <code>message</code> modifier is literal; any quotes are taken as
literals, but because the string is expanded, backslash escapes are processed
anyway. If the message contains newlines, this gives rise to a multi-line SMTP
response.
</p>
<a name="IDX2522"></a>
<p>If <code>message</code> is used on a statement that verifies an address, the message
specified overrides any message that is generated by the verification process.
However, the original message is available in the variable
<code>$acl_verify_message</code>, so you can incorporate it into your message if you
wish. In particular, if you want the text from <code>:fail:</code> items in <code>redirect</code>
routers to be passed back as part of the SMTP response, you should either not
use a <code>message</code> modifier, or make use of <code>$acl_verify_message</code>.
</p>
<p>For compatibility with previous releases of Exim, a <code>message</code> modifier that
is used with a <code>warn</code> verb behaves in a similar way to the <code>add_header</code>
modifier, but this usage is now deprecated. However, <code>message</code> acts only when
all the conditions are true, wherever it appears in an ACL command, whereas
<code>add_header</code> acts as soon as it is encountered. If <code>message</code> is used with
<code>warn</code> in an ACL that is not concerned with receiving a message, it has no
effect.
</p>
</dd>
<dt> <strong>set</strong>&lt;<em>acl_name</em>&gt;=&lt;<em>value</em>&gt;</dt>
<dd><a name="IDX2523"></a>
<p>This modifier puts a value into one of the ACL variables (see section
<a href="#SEC325">ACL variables</a>).
</p></dd>
</dl>

<hr size="6">
<a name="Use-of-the-control-modifier"></a>
<a name="SEC328"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC327" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC329" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.20 Use of the control modifier </h2>

<p>The <code>control</code> modifier supports the following settings:
</p>
<dl compact="compact">
<dt> <strong>control=allow_auth_unadvertised</strong></dt>
<dd><p>This modifier allows a client host to use the SMTP AUTH command even when it
has not been advertised in response to EHLO. Furthermore, because there are
apparently some really broken clients that do this, Exim will accept AUTH after
HELO (rather than EHLO) when this control is set. It should be used only if you
really need it, and you should limit its use to those broken clients that do
not work without it. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">warn hosts   = 192.168.34.25
     control = allow_auth_unadvertised
</pre></td></tr></table>

<p>Normally, when an Exim server receives an AUTH command, it checks the name of
the authentication mechanism that is given in the command to ensure that it
matches an advertised mechanism. When this control is set, the check that a
mechanism has been advertised is bypassed. Any configured mechanism can be used
by the client. This control is permitted only in the connection and HELO ACLs.
</p>
</dd>
<dt> <strong>control=caseful_local_part</strong></dt>
<dt> <strong>control=caselower_local_part</strong></dt>
<dd><a name="IDX2524"></a>
<a name="IDX2525"></a>
<a name="IDX2526"></a>
<p>These two controls are permitted only in the ACL specified by <code>acl_smtp_rcpt</code>
(that is, during RCPT processing). By default, the contents of <code>$local_part</code>
are lower cased before ACL processing. If &quot;caseful_local_part&quot; is specified,
any uppercase letters in the original local part are restored in <code>$local_part</code>
for the rest of the ACL, or until a control that sets &quot;caselower_local_part&quot;
is encountered.
</p>
<p>These controls affect only the current recipient. Moreover, they apply only to
local part handling that takes place directly in the ACL (for example, as a key
in lookups). If a test to verify the recipient is obeyed, the case-related
handling of the local part during the verification is controlled by the router
configuration (see the <code>caseful_local_part</code> generic router option).
</p>
<p>This facility could be used, for example, to add a spam score to local parts
containing upper case letters. For example, using <code>$acl_m4</code> to accumulate the
spam score:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">warn  control = caseful_local_part
      set acl_m4 = ${eval:\
                     $acl_m4 + \
                     ${if match{$local_part}{[A-Z]}{1}{0}}\
                    }
      control = caselower_local_part
</pre></td></tr></table>

<p>Notice that we put back the lower cased version afterwards, assuming that
is what is wanted for subsequent tests.
</p>
</dd>
<dt> <strong>control=enforce_sync</strong></dt>
<dt> <strong>control=no_enforce_sync</strong></dt>
<dd><a name="IDX2527"></a>
<a name="IDX2528"></a>
<p>These controls make it possible to be selective about when SMTP synchronization
is enforced. The global option <code>smtp_enforce_sync</code> specifies the initial
state of the switch (it is true by default). See the description of this option
in chapter <a href="spec_14.html#SEC162">Main configuration</a> for details of SMTP synchronization checking.
</p>
<p>The effect of these two controls lasts for the remainder of the SMTP
connection. They can appear in any ACL except the one for the non-SMTP
messages. The most straightforward place to put them is in the ACL defined by
<code>acl_smtp_connect</code>, which is run at the start of an incoming SMTP connection,
before the first synchronization check. The expected use is to turn off the
synchronization checks for badly-behaved hosts that you nevertheless need to
work with.
</p>
</dd>
<dt> <strong>control=fakedefer/</strong>&lt;<em>message</em>&gt;</dt>
<dd><a name="IDX2529"></a>
<a name="IDX2530"></a>
<p>This control works in exactly the same way as <code>fakereject</code> (described below)
except that it causes an SMTP 450 response after the message data instead of a
550 response. You must take care when using <code>fakedefer</code> because it causes the
messages to be duplicated when the sender retries. Therefore, you should not
use <code>fakedefer</code> if the message is to be delivered normally.
</p>
</dd>
<dt> <strong>control=fakereject/</strong>&lt;<em>message</em>&gt;</dt>
<dd><a name="IDX2531"></a>
<a name="IDX2532"></a>
<p>This control is permitted only for the MAIL, RCPT, and DATA ACLs, in other
words, only when an SMTP message is being received. If Exim accepts the
message, instead the final 250 response, a 550 rejection message is sent.
However, Exim proceeds to deliver the message as normal. The control applies
only to the current message, not to any subsequent ones that may be received in
the same SMTP connection.
</p>
<p>The text for the 550 response is taken from the <code>control</code> modifier. If no
message is supplied, the following is used:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">550-Your message has been rejected but is being
550-kept for evaluation.
550-If it was a legitimate message, it may still be
550 delivered to the target recipient(s).
</pre></td></tr></table>

<p>This facility should be used with extreme caution.
</p>
</dd>
<dt> <strong>control=freeze</strong></dt>
<dd><a name="IDX2533"></a>
<p>This control is permitted only for the MAIL, RCPT, DATA, and non-SMTP ACLs, in
other words, only when a message is being received. If the message is accepted,
it is placed on Exim's queue and frozen. The control applies only to the
current message, not to any subsequent ones that may be received in the same
SMTP connection.
</p>
<p>This modifier can optionally be followed by &lsquo;<samp>/no_tell</samp>&rsquo;. If the global option
<code>freeze_tell</code> is set, it is ignored for the current message (that is, nobody
is told about the freezing), provided all the <strong>control=freeze</strong> modifiers that
are obeyed for the current message have the &lsquo;<samp>/no_tell</samp>&rsquo; option.
</p>
</dd>
<dt> <strong>control=no_delay_flush</strong></dt>
<dd><a name="IDX2534"></a>
<p>Exim normally flushes SMTP output before implementing a delay in an ACL, to
avoid unexpected timeouts in clients when the SMTP PIPELINING extension is in
use. This control, as long as it is encountered before the <code>delay</code> modifier,
disables such output flushing.
</p>
</dd>
<dt> <strong>control=no_callout_flush</strong></dt>
<dd><a name="IDX2535"></a>
<p>Exim normally flushes SMTP output before performing a callout in an ACL, to
avoid unexpected timeouts in clients when the SMTP PIPELINING extension is in
use. This control, as long as it is encountered before the <code>verify</code> condition
that causes the callout, disables such output flushing.
</p>
</dd>
<dt> <strong>control=no_mbox_unspool</strong></dt>
<dd><p>This control is available when Exim is compiled with the content scanning
extension. Content scanning may require a copy of the current message, or parts
of it, to be written in &quot;mbox format&quot; to a spool file, for passing to a virus
or spam scanner. Normally, such copies are deleted when they are no longer
needed. If this control is set, the copies are not deleted. The control applies
only to the current message, not to any subsequent ones that may be received in
the same SMTP connection. It is provided for debugging purposes and is unlikely
to be useful in production.
</p>
</dd>
<dt> <strong>control=no_multiline_responses</strong></dt>
<dd><a name="IDX2536"></a>
<p>This control is permitted for any ACL except the one for non-SMTP messages.
It seems that there are broken clients in use that cannot handle multiline
SMTP responses, despite the fact that RFC 821 defined them over 20 years ago.
</p>
<p>If this control is set, multiline SMTP responses from ACL rejections are
suppressed. One way of doing this would have been to put out these responses as
one long line. However, RFC 2821 specifies a maximum of 512 bytes per response
(&quot;use multiline responses for more&quot; it says - ha!), and some of the
responses might get close to that. So this facility, which is after all only a
sop to broken clients, is implemented by doing two very easy things:
</p>
<ul class="toc">
<li>
Extra information that is normally output as part of a rejection caused by
sender verification failure is omitted. Only the final line (typically &quot;sender
verification failed&quot;) is sent.

</li><li>
If a <code>message</code> modifier supplies a multiline response, only the first
line is output.
</li></ul>

<p>The setting of the switch can, of course, be made conditional on the
calling host. Its effect lasts until the end of the SMTP connection.
</p>
</dd>
<dt> <strong>control=no_pipelining</strong></dt>
<dd><a name="IDX2537"></a>
<p>This control turns off the advertising of the PIPELINING extension to SMTP in
the current session. To be useful, it must be obeyed before Exim sends its
response to an EHLO command. Therefore, it should normally appear in an ACL
controlled by <code>acl_smtp_connect</code> or <code>acl_smtp_helo</code>. See also
<code>pipelining_advertise_hosts</code>.
</p>
</dd>
<dt> <strong>control=queue_only</strong></dt>
<dd><a name="IDX2538"></a>
<a name="IDX2539"></a>
<p>This control is permitted only for the MAIL, RCPT, DATA, and non-SMTP ACLs, in
other words, only when a message is being received. If the message is accepted,
it is placed on Exim's queue and left there for delivery by a subsequent queue
runner. No immediate delivery process is started. In other words, it has the
effect as the <code>queue_only</code> global option. However, the control applies only
to the current message, not to any subsequent ones that may be received in the
same SMTP connection.
</p>
</dd>
<dt> <strong>control=submission/</strong>&lt;<em>options</em>&gt;</dt>
<dd><a name="IDX2540"></a>
<a name="IDX2541"></a>
<p>This control is permitted only for the MAIL, RCPT, and start of data ACLs (the
latter is the one defined by <code>acl_smtp_predata</code>). Setting it tells Exim that
the current message is a submission from a local MUA. In this case, Exim
operates in &quot;submission mode&quot;, and applies certain fixups to the message if
necessary. For example, it add a <em>Date:</em> header line if one is not present.
This control is not permitted in the <code>acl_smtp_data</code> ACL, because that is too
late (the message has already been created).
</p>
<p>Chapter <a href="spec_44.html#SEC383">Message processing</a> describes the processing that Exim applies to
messages. Section <a href="spec_44.html#SEC384">Submission mode for non-local messages</a> covers the processing that happens in
submission mode; the available options for this control are described there.
The control applies only to the current message, not to any subsequent ones
that may be received in the same SMTP connection.
</p>
</dd>
<dt> <strong>control=suppress_local_fixups</strong></dt>
<dd><a name="IDX2542"></a>
<p>This control applies to locally submitted (non TCP/IP) messages, and is the
complement of &lsquo;<samp>control</samp>&rsquo; &lsquo;<samp>=</samp>&rsquo; &lsquo;<samp>submission</samp>&rsquo;. It disables the fixups that are
normally applied to locally-submitted messages. Specifically:
</p>
<ul class="toc">
<li>
Any <em>Sender:</em> header line is left alone (in this respect, it is a
dynamic version of <code>local_sender_retain</code>).

</li><li>
No <em>Message-ID:</em>, <em>From:</em>, or <em>Date:</em> header lines are added.

</li><li>
There is no check that <em>From:</em> corresponds to the actual sender.
</li></ul>

<p>This control may be useful when a remotely-originated message is accepted,
passed to some scanning program, and then re-submitted for delivery. It can be
used only in the <code>acl_smtp_mail</code>, <code>acl_smtp_rcpt</code>, <code>acl_smtp_predata</code>,
and <code>acl_not_smtp_start</code> ACLs, because it has to be set before the message's
data is read.
</p>
<p><strong>Note:</strong> This control applies only to the current message, not to any others
that are being submitted at the same time using <code>-bs</code> or <code>-bS</code>.
</p></dd>
</dl>

<hr size="6">
<a name="Summary-of-message-fixup-control"></a>
<a name="SEC329"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC328" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC330" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.21 Summary of message fixup control </h2>

<p>All four possibilities for message fixups can be specified:
</p>
<ul class="toc">
<li>
Locally submitted, fixups applied: the default.

</li><li>
Locally submitted, no fixups applied: use &lsquo;<samp>control</samp>&rsquo; &lsquo;<samp>=</samp>&rsquo;
&lsquo;<samp>suppress_local_fixups</samp>&rsquo;.

</li><li>
Remotely submitted, no fixups applied: the default.

</li><li>
Remotely submitted, fixups applied: use &lsquo;<samp>control</samp>&rsquo; &lsquo;<samp>=</samp>&rsquo; &lsquo;<samp>submission</samp>&rsquo;.
</li></ul>

<hr size="6">
<a name="Adding-header-lines-in-ACLs"></a>
<a name="SEC330"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC329" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC331" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.22 Adding header lines in ACLs </h2>

<p>The <code>add_header</code> modifier can be used to add one or more extra header lines
to an incoming message, as in this example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">warn dnslists = sbl.spamhaus.org : \
                dialup.mail-abuse.org
     add_header = X-blacklisted-at: $dnslist_domain
</pre></td></tr></table>

<p>The <code>add_header</code> modifier is permitted in the MAIL, RCPT, PREDATA, DATA,
MIME, and non-SMTP ACLs (in other words, those that are concerned with
receiving a message). The message must ultimately be accepted for
<code>add_header</code> to have any significant effect. You can use <code>add_header</code> with
any ACL verb, including <code>deny</code> (though this is potentially useful only in a
RCPT ACL).
</p>
<p>If the data for the <code>add_header</code> modifier contains one or more newlines that
are not followed by a space or a tab, it is assumed to contain multiple header
lines. Each one is checked for valid syntax; &lsquo;<samp>X-ACL-Warn:</samp>&rsquo; is added to the
front of any line that is not a valid header line.
</p>
<p>Added header lines are accumulated during the MAIL, RCPT, and predata ACLs.
They are added to the message before processing the DATA and MIME ACLs.
However, if an identical header line is requested more than once, only one copy
is actually added to the message. Further header lines may be accumulated
during the DATA and MIME ACLs, after which they are added to the message, again
with duplicates suppressed. Thus, it is possible to add two identical header
lines to an SMTP message, but only if one is added before DATA and one after.
In the case of non-SMTP messages, new headers are accumulated during the
non-SMTP ACLs, and are added to the message after all the ACLs have run. If a
message is rejected after DATA or by the non-SMTP ACL, all added header lines
are included in the entry that is written to the reject log.
</p>
<a name="IDX2543"></a>
<p>Header lines are not visible in string expansions until they are added to the
message. It follows that header lines defined in the MAIL, RCPT, and predata
ACLs are not visible until the DATA ACL and MIME ACLs are run. Similarly,
header lines that are added by the DATA or MIME ACLs are not visible in those
ACLs. Because of this restriction, you cannot use header lines as a way of
passing data between (for example) the MAIL and RCPT ACLs. If you want to do
this, you can use ACL variables, as described in section
<a href="#SEC325">ACL variables</a>.
</p>
<p>The <code>add_header</code> modifier acts immediately it is encountered during the
processing of an ACL. Notice the difference between these two cases:
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">accept add_header = ADDED: some text
       &lt;some condition&gt;

accept &lt;some condition&gt;
       add_header = ADDED: some text
</pre></td></tr></table>

<p>In the first case, the header line is always added, whether or not the
condition is true. In the second case, the header line is added only if the
condition is true. Multiple occurrences of <code>add_header</code> may occur in the same
ACL statement. All those that are encountered before a condition fails are
honoured.
</p>
<a name="IDX2544"></a>
<p>For compatibility with previous versions of Exim, a <code>message</code> modifier for a
<code>warn</code> verb acts in the same way as <code>add_header</code>, except that it takes
effect only if all the conditions are true, even if it appears before some of
them. Furthermore, only the last occurrence of <code>message</code> is honoured. This
usage of <code>message</code> is now deprecated. If both <code>add_header</code> and <code>message</code>
are present on a <code>warn</code> verb, both are processed according to their
specifications.
</p>
<p>By default, new header lines are added to a message at the end of the existing
header lines. However, you can specify that any particular header line should
be added right at the start (before all the <em>Received:</em> lines), immediately
after the first block of <em>Received:</em> lines, or immediately before any line
that is not a <em>Received:</em> or <em>Resent-something:</em> header.
</p>
<p>This is done by specifying &quot;:at_start:&quot;, &quot;:after_received:&quot;, or
&quot;:at_start_rfc:&quot; (or, for completeness, &quot;:at_end:&quot;) before the text of the
header line, respectively. (Header text cannot start with a colon, as there has
to be a header name first.) For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">warn add_header = \
       :after_received:X-My-Header: something or other...
</pre></td></tr></table>

<p>If more than one header line is supplied in a single <code>add_header</code> modifier,
each one is treated independently and can therefore be placed differently. If
you add more than one line at the start, or after the Received: block, they end
up in reverse order.
</p>
<p><strong>Warning</strong>: This facility currently applies only to header lines that are
added in an ACL. It does NOT work for header lines that are added in a
system filter or in a router or transport.
</p>
<hr size="6">
<a name="ACL-conditions"></a>
<a name="SEC331"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC330" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC332" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.23 ACL conditions </h2>

<p>Some of conditions listed in this section are available only when Exim is
compiled with the content-scanning extension. They are included here briefly
for completeness. More detailed descriptions can be found in the discussion on
content scanning in chapter <a href="spec_41.html#SEC358">Content scanning at ACL time</a>.
</p>
<p>Not all conditions are relevant in all circumstances. For example, testing
senders and recipients does not make sense in an ACL that is being run as the
result of the arrival of an ETRN command, and checks on message headers can be
done only in the ACLs specified by <code>acl_smtp_data</code> and <code>acl_not_smtp</code>. You
can use the same condition (with different parameters) more than once in the
same ACL statement. This provides a way of specifying an &quot;and&quot; conjunction.
The conditions are as follows:
</p>
<dl compact="compact">
<dt> <strong>acl=</strong>&lt;<em>nameofaclorACLstringorfilename</em>&gt;</dt>
<dd><a name="IDX2545"></a>
<a name="IDX2546"></a>
<a name="IDX2547"></a>
<p>The possible values of the argument are the same as for the
<code>acl_smtp_</code><em>xxx</em> options. The named or inline ACL is run. If it returns
&quot;accept&quot; the condition is true; if it returns &quot;deny&quot; the condition is
false. If it returns &quot;defer&quot;, the current ACL returns &quot;defer&quot; unless the
condition is on a <code>warn</code> verb. In that case, a &quot;defer&quot; return makes the
condition false. This means that further processing of the <code>warn</code> verb
ceases, but processing of the ACL continues.
</p>
<p>If the nested <code>acl</code> returns &quot;drop&quot; and the outer condition denies access,
the connection is dropped. If it returns &quot;discard&quot;, the verb must be
<code>accept</code> or <code>discard</code>, and the action is taken immediately - no further
conditions are tested.
</p>
<p>ACLs may be nested up to 20 deep; the limit exists purely to catch runaway
loops. This condition allows you to use different ACLs in different
circumstances. For example, different ACLs can be used to handle RCPT commands
for different local users or different local domains.
</p>
</dd>
<dt> <strong>authenticated=</strong>&lt;<em>stringlist</em>&gt;</dt>
<dd><a name="IDX2548"></a>
<a name="IDX2549"></a>
<a name="IDX2550"></a>
<p>If the SMTP connection is not authenticated, the condition is false. Otherwise,
the name of the authenticator is tested against the list. To test for
authentication by any authenticator, you can set
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">authenticated = *
</pre></td></tr></table>

</dd>
<dt> <strong>condition=</strong>&lt;<em>string</em>&gt;</dt>
<dd><a name="IDX2551"></a>
<a name="IDX2552"></a>
<a name="IDX2553"></a>
<a name="IDX2554"></a>
<p>This feature allows you to make up custom conditions. If the result of
expanding the string is an empty string, the number zero, or one of the strings
&quot;no&quot; or &quot;false&quot;, the condition is false. If the result is any non-zero
number, or one of the strings &quot;yes&quot; or &quot;true&quot;, the condition is true. For
any other value, some error is assumed to have occurred, and the ACL returns
&quot;defer&quot;. However, if the expansion is forced to fail, the condition is
ignored. The effect is to treat it as true, whether it is positive or
negative.
</p>
</dd>
<dt> <strong>decode=</strong>&lt;<em>location</em>&gt;</dt>
<dd><a name="IDX2555"></a>
<p>This condition is available only when Exim is compiled with the
content-scanning extension, and it is allowed only in the ACL defined by
<code>acl_smtp_mime</code>. It causes the current MIME part to be decoded into a file.
If all goes well, the condition is true. It is false only if there are
problems such as a syntax error or a memory shortage. For more details, see
chapter <a href="spec_41.html#SEC358">Content scanning at ACL time</a>.
</p>
</dd>
<dt> <strong>demime=</strong>&lt;<em>extensionlist</em>&gt;</dt>
<dd><a name="IDX2556"></a>
<p>This condition is available only when Exim is compiled with the
content-scanning extension. Its use is described in section
<a href="spec_41.html#SEC364">The demime condition</a>.
</p>
</dd>
<dt> <strong>dnslists=</strong>&lt;<em>listofdomainnamesandotherdata</em>&gt;</dt>
<dd><a name="IDX2557"></a>
<a name="IDX2558"></a>
<a name="IDX2559"></a>
<a name="IDX2560"></a>
<p>This condition checks for entries in DNS black lists. These are also known as
&quot;RBL lists&quot;, after the original Realtime Blackhole List, but note that the
use of the lists at <em>mail-abuse.org</em> now carries a charge. There are too many
different variants of this condition to describe briefly here. See sections
<a href="#SEC332">Using DNS lists</a>-<a href="#SEC342">DNS lists and IPv6</a> for details.
</p>
</dd>
<dt> <strong>domains=</strong>&lt;<em>domainlist</em>&gt;</dt>
<dd><a name="IDX2561"></a>
<a name="IDX2562"></a>
<a name="IDX2563"></a>
<a name="IDX2564"></a>
<p>This condition is relevant only after a RCPT command. It checks that the domain
of the recipient address is in the domain list. If percent-hack processing is
enabled, it is done before this test is done. If the check succeeds with a
lookup, the result of the lookup is placed in <code>$domain_data</code> until the next
<code>domains</code> test.
</p>
<p><strong>Note carefully</strong> (because many people seem to fall foul of this): you cannot
use <code>domains</code> in a DATA ACL.
</p>
</dd>
<dt> <strong>encrypted=</strong>&lt;<em>stringlist</em>&gt;</dt>
<dd><a name="IDX2565"></a>
<a name="IDX2566"></a>
<a name="IDX2567"></a>
<p>If the SMTP connection is not encrypted, the condition is false. Otherwise, the
name of the cipher suite in use is tested against the list. To test for
encryption without testing for any specific cipher suite(s), set
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">encrypted = *
</pre></td></tr></table>

</dd>
<dt> <strong>hosts=</strong>&lt;<em>hostlist</em>&gt;</dt>
<dd><a name="IDX2568"></a>
<a name="IDX2569"></a>
<a name="IDX2570"></a>
<p>This condition tests that the calling host matches the host list. If you have
name lookups or wildcarded host names and IP addresses in the same host list,
you should normally put the IP addresses first. For example, you could have:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">accept hosts = 10.9.8.7 : dbm;/etc/friendly/hosts
</pre></td></tr></table>

<p>The lookup in this example uses the host name for its key. This is implied by
the lookup type &quot;dbm&quot;. (For a host address lookup you would use &quot;net-dbm&quot;
and it wouldn't matter which way round you had these two items.)
</p>
<p>The reason for the problem with host names lies in the left-to-right way that
Exim processes lists. It can test IP addresses without doing any DNS lookups,
but when it reaches an item that requires a host name, it fails if it cannot
find a host name to compare with the pattern. If the above list is given in the
opposite order, the <code>accept</code> statement fails for a host whose name cannot be
found, even if its IP address is 10.9.8.7.
</p>
<p>If you really do want to do the name check first, and still recognize the IP
address even if the name lookup fails, you can rewrite the ACL like this:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">accept hosts = dbm;/etc/friendly/hosts
accept hosts = 10.9.8.7
</pre></td></tr></table>

<p>The default action on failing to find the host name is to assume that the host
is not in the list, so the first <code>accept</code> statement fails. The second
statement can then check the IP address.
</p>
<a name="IDX2571"></a>
<p>If a <code>hosts</code> condition is satisfied by means of a lookup, the result
of the lookup is made available in the <code>$host_data</code> variable. This
allows you, for example, to set up a statement like this:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny  hosts = net-lsearch;/some/file
message = $host_data
</pre></td></tr></table>

<p>which gives a custom error message for each denied host.
</p>
</dd>
<dt> <strong>local_parts=</strong>&lt;<em>localpartlist</em>&gt;</dt>
<dd><a name="IDX2572"></a>
<a name="IDX2573"></a>
<a name="IDX2574"></a>
<a name="IDX2575"></a>
<p>This condition is relevant only after a RCPT command. It checks that the local
part of the recipient address is in the list. If percent-hack processing is
enabled, it is done before this test. If the check succeeds with a lookup, the
result of the lookup is placed in <code>$local_part_data</code>, which remains set until
the next <code>local_parts</code> test.
</p>
</dd>
<dt> <strong>malware=</strong>&lt;<em>option</em>&gt;</dt>
<dd><a name="IDX2576"></a>
<a name="IDX2577"></a>
<a name="IDX2578"></a>
<p>This condition is available only when Exim is compiled with the
content-scanning extension. It causes the incoming message to be scanned for
viruses. For details, see chapter <a href="spec_41.html#SEC358">Content scanning at ACL time</a>.
</p>
</dd>
<dt> <strong>mime_regex=</strong>&lt;<em>listofregularexpressions</em>&gt;</dt>
<dd><a name="IDX2579"></a>
<a name="IDX2580"></a>
<p>This condition is available only when Exim is compiled with the
content-scanning extension, and it is allowed only in the ACL defined by
<code>acl_smtp_mime</code>. It causes the current MIME part to be scanned for a match
with any of the regular expressions. For details, see chapter
<a href="spec_41.html#SEC358">Content scanning at ACL time</a>.
</p>
</dd>
<dt> <strong>ratelimit=</strong>&lt;<em>parameters</em>&gt;</dt>
<dd><a name="IDX2581"></a>
<p>This condition can be used to limit the rate at which a user or host submits
messages. Details are given in section <a href="#SEC343">Rate limiting incoming messages</a>.
</p>
</dd>
<dt> <strong>recipients=</strong>&lt;<em>addresslist</em>&gt;</dt>
<dd><a name="IDX2582"></a>
<a name="IDX2583"></a>
<a name="IDX2584"></a>
<p>This condition is relevant only after a RCPT command. It checks the entire
recipient address against a list of recipients.
</p>
</dd>
<dt> <strong>regex=</strong>&lt;<em>listofregularexpressions</em>&gt;</dt>
<dd><a name="IDX2585"></a>
<a name="IDX2586"></a>
<p>This condition is available only when Exim is compiled with the
content-scanning extension, and is available only in the DATA, MIME, and
non-SMTP ACLs. It causes the incoming message to be scanned for a match with
any of the regular expressions. For details, see chapter <a href="spec_41.html#SEC358">Content scanning at ACL time</a>.
</p>
</dd>
<dt> <strong>sender_domains=</strong>&lt;<em>domainlist</em>&gt;</dt>
<dd><a name="IDX2587"></a>
<a name="IDX2588"></a>
<a name="IDX2589"></a>
<a name="IDX2590"></a>
<a name="IDX2591"></a>
<p>This condition tests the domain of the sender of the message against the given
domain list. <strong>Note</strong>: The domain of the sender address is in
<code>$sender_address_domain</code>. It is <em>not</em> put in <code>$domain</code> during the testing
of this condition. This is an exception to the general rule for testing domain
lists. It is done this way so that, if this condition is used in an ACL for a
RCPT command, the recipient's domain (which is in <code>$domain</code>) can be used to
influence the sender checking.
</p>
<p><strong>Warning</strong>: It is a bad idea to use this condition on its own as a control on
relaying, because sender addresses are easily, and commonly, forged.
</p>
</dd>
<dt> <strong>senders=</strong>&lt;<em>addresslist</em>&gt;</dt>
<dd><a name="IDX2592"></a>
<a name="IDX2593"></a>
<a name="IDX2594"></a>
<p>This condition tests the sender of the message against the given list. To test
for a bounce message, which has an empty sender, set
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">senders = :
</pre></td></tr></table>

<p><strong>Warning</strong>: It is a bad idea to use this condition on its own as a control on
relaying, because sender addresses are easily, and commonly, forged.
</p>
</dd>
<dt> <strong>spam=</strong>&lt;<em>username</em>&gt;</dt>
<dd><a name="IDX2595"></a>
<a name="IDX2596"></a>
<p>This condition is available only when Exim is compiled with the
content-scanning extension. It causes the incoming message to be scanned by
SpamAssassin. For details, see chapter <a href="spec_41.html#SEC358">Content scanning at ACL time</a>.
</p>
</dd>
<dt> <strong>verify=certificate</strong></dt>
<dd><a name="IDX2597"></a>
<a name="IDX2598"></a>
<a name="IDX2599"></a>
<a name="IDX2600"></a>
<a name="IDX2601"></a>
<p>This condition is true in an SMTP session if the session is encrypted, and a
certificate was received from the client, and the certificate was verified. The
server requests a certificate only if the client matches <code>tls_verify_hosts</code>
or <code>tls_try_verify_hosts</code> (see chapter <a href="spec_39.html#SEC294">Encrypted SMTP connections using TLS/SSL</a>).
</p>
</dd>
<dt> <strong>verify=csa</strong></dt>
<dd><a name="IDX2602"></a>
<p>This condition checks whether the sending host (the client) is authorized to
send email. Details of how this works are given in section
<a href="#SEC354">Client SMTP authorization (CSA)</a>.
</p>
</dd>
<dt> <strong>verify=header_sender/</strong>&lt;<em>options</em>&gt;</dt>
<dd><a name="IDX2603"></a>
<a name="IDX2604"></a>
<a name="IDX2605"></a>
<a name="IDX2606"></a>
<a name="IDX2607"></a>
<p>This condition is relevant only in an ACL that is run after a message has been
received, that is, in an ACL specified by <code>acl_smtp_data</code> or
<code>acl_not_smtp</code>. It checks that there is a verifiable address in at least one
of the <em>Sender:</em>, <em>Reply-To:</em>, or <em>From:</em> header lines. Such an address
is loosely thought of as a &quot;sender&quot; address (hence the name of the test).
However, an address that appears in one of these headers need not be an address
that accepts bounce messages; only sender addresses in envelopes are required
to accept bounces. Therefore, if you use the callout option on this check, you
might want to arrange for a non-empty address in the MAIL command.
</p>
<p>Details of address verification and the options are given later, starting at
section <a href="#SEC348">Address verification</a> (callouts are described in section
<a href="#SEC349">Callout verification</a>). You can combine this condition with the <code>senders</code>
condition to restrict it to bounce messages only:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny    senders = :
        message = A valid sender header is required for bounces
       !verify  = header_sender
</pre></td></tr></table>

</dd>
<dt> <strong>verify=header_syntax</strong></dt>
<dd><a name="IDX2608"></a>
<a name="IDX2609"></a>
<a name="IDX2610"></a>
<a name="IDX2611"></a>
<p>This condition is relevant only in an ACL that is run after a message has been
received, that is, in an ACL specified by <code>acl_smtp_data</code> or
<code>acl_not_smtp</code>. It checks the syntax of all header lines that can contain
lists of addresses (<em>Sender:</em>, <em>From:</em>, <em>Reply-To:</em>, <em>To:</em>, <em>Cc:</em>,
and <em>Bcc:</em>). Unqualified addresses (local parts without domains) are
permitted only in locally generated messages and from hosts that match
<code>sender_unqualified_hosts</code> or <code>recipient_unqualified_hosts</code>, as
appropriate.
</p>
<p>Note that this condition is a syntax check only. However, a common spamming
ploy used to be to send syntactically invalid headers such as
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">To: @
</pre></td></tr></table>

<p>and this condition can be used to reject such messages, though they are not as
common as they used to be.
</p>
</dd>
<dt> <strong>verify=helo</strong></dt>
<dd><a name="IDX2612"></a>
<a name="IDX2613"></a>
<a name="IDX2614"></a>
<a name="IDX2615"></a>
<a name="IDX2616"></a>
<a name="IDX2617"></a>
<p>This condition is true if a HELO or EHLO command has been received from the
client host, and its contents have been verified. If there has been no previous
attempt to verify the HELO/EHLO contents, it is carried out when this
condition is encountered. See the description of the <code>helo_verify_hosts</code> and
<code>helo_try_verify_hosts</code> options for details of how to request verification
independently of this condition.
</p>
<p>For SMTP input that does not come over TCP/IP (the <code>-bs</code> command line
option), this condition is always true.
</p>
</dd>
<dt> <strong>verify=not_blind</strong></dt>
<dd><a name="IDX2618"></a>
<a name="IDX2619"></a>
<p>This condition checks that there are no blind (bcc) recipients in the message.
Every envelope recipient must appear either in a <em>To:</em> header line or in a
<em>Cc:</em> header line for this condition to be true. Local parts are checked
case-sensitively; domains are checked case-insensitively. If <em>Resent-To:</em> or
<em>Resent-Cc:</em> header lines exist, they are also checked. This condition can be
used only in a DATA or non-SMTP ACL.
</p>
<p>There are, of course, many legitimate messages that make use of blind (bcc)
recipients. This check should not be used on its own for blocking messages.
</p>
</dd>
<dt> <strong>verify=recipient/</strong>&lt;<em>options</em>&gt;</dt>
<dd><a name="IDX2620"></a>
<a name="IDX2621"></a>
<a name="IDX2622"></a>
<a name="IDX2623"></a>
<a name="IDX2624"></a>
<p>This condition is relevant only after a RCPT command. It verifies the current
recipient. Details of address verification are given later, starting at section
<a href="#SEC348">Address verification</a>. After a recipient has been verified, the value
of <code>$address_data</code> is the last value that was set while routing the address.
This applies even if the verification fails. When an address that is being
verified is redirected to a single address, verification continues with the new
address, and in that case, the subsequent value of <code>$address_data</code> is the
value for the child address.
</p>
</dd>
<dt> <strong>verify=reverse_host_lookup</strong></dt>
<dd><a name="IDX2625"></a>
<a name="IDX2626"></a>
<a name="IDX2627"></a>
<p>This condition ensures that a verified host name has been looked up from the IP
address of the client host. (This may have happened already if the host name
was needed for checking a host list, or if the host matched <code>host_lookup</code>.)
Verification ensures that the host name obtained from a reverse DNS lookup, or
one of its aliases, does, when it is itself looked up in the DNS, yield the
original IP address.
</p>
<p>If this condition is used for a locally generated message (that is, when there
is no client host involved), it always succeeds.
</p>
</dd>
<dt> <strong>verify=sender/</strong>&lt;<em>options</em>&gt;</dt>
<dd><a name="IDX2628"></a>
<a name="IDX2629"></a>
<a name="IDX2630"></a>
<a name="IDX2631"></a>
<p>This condition is relevant only after a MAIL or RCPT command, or after a
message has been received (the <code>acl_smtp_data</code> or <code>acl_not_smtp</code> ACLs). If
the message's sender is empty (that is, this is a bounce message), the
condition is true. Otherwise, the sender address is verified.
</p>
<a name="IDX2632"></a>
<a name="IDX2633"></a>
<p>If there is data in the <code>$address_data</code> variable at the end of routing, its
value is placed in <code>$sender_address_data</code> at the end of verification. This
value can be used in subsequent conditions and modifiers in the same ACL
statement. It does not persist after the end of the current statement. If you
want to preserve the value for longer, you can save it in an ACL variable.
</p>
<p>Details of verification are given later, starting at section
<a href="#SEC348">Address verification</a>. Exim caches the result of sender verification,
to avoid doing it more than once per message.
</p>
</dd>
<dt> <strong>verify=sender=</strong>&lt;<em>address</em>&gt;<strong>/</strong>&lt;<em>options</em>&gt;</dt>
<dd><a name="IDX2634"></a>
<p>This is a variation of the previous option, in which a modified address is
verified as a sender.
</p></dd>
</dl>

<hr size="6">
<a name="Using-DNS-lists"></a>
<a name="SEC332"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC331" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC333" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.24 Using DNS lists </h2>

<p>In its simplest form, the <code>dnslists</code> condition tests whether the calling host
is on at least one of a number of DNS lists by looking up the inverted IP
address in one or more DNS domains. For example, if the calling host's IP
address is 192.168.62.43, and the ACL statement is
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny dnslists = blackholes.mail-abuse.org : \
                dialups.mail-abuse.org
</pre></td></tr></table>

<p>the following records are looked up:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">43.62.168.192.blackholes.mail-abuse.org
43.62.168.192.dialups.mail-abuse.org
</pre></td></tr></table>

<p>As soon as Exim finds an existing DNS record, processing of the list stops.
Thus, multiple entries on the list provide an &quot;or&quot; conjunction. If you want
to test that a host is on more than one list (an &quot;and&quot; conjunction), you can
use two separate conditions:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny dnslists = blackholes.mail-abuse.org
     dnslists = dialups.mail-abuse.org
</pre></td></tr></table>

<p>If a DNS lookup times out or otherwise fails to give a decisive answer, Exim
behaves as if the host does not match the list item, that is, as if the DNS
record does not exist. If there are further items in the DNS list, they are
processed.
</p>
<p>This is usually the required action when <code>dnslists</code> is used with <code>deny</code>
(which is the most common usage), because it prevents a DNS failure from
blocking mail. However, you can change this behaviour by putting one of the
following special items in the list:
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">+include_unknown    behave as if the item is on the list
+exclude_unknown    behave as if the item is not on the list (default)
+defer_unknown      give a temporary error
</pre></td></tr></table>

<a name="IDX2635"></a>
<a name="IDX2636"></a>
<a name="IDX2637"></a>
<p>Each of these applies to any subsequent items on the list. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny dnslists = +defer_unknown : foo.bar.example
</pre></td></tr></table>

<p>Testing the list of domains stops as soon as a match is found. If you want to
warn for one list and block for another, you can use two different statements:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny  dnslists = blackholes.mail-abuse.org
warn  message  = X-Warn: sending host is on dialups list
      dnslists = dialups.mail-abuse.org
</pre></td></tr></table>

<p>DNS list lookups are cached by Exim for the duration of the SMTP session,
so a lookup based on the IP address is done at most once for any incoming
connection. Exim does not share information between multiple incoming
connections (but your local name server cache should be active).
</p>
<hr size="6">
<a name="Specifying-the-IP-address-for-a-DNS-list-lookup"></a>
<a name="SEC333"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC332" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC334" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.25 Specifying the IP address for a DNS list lookup </h2>

<p>By default, the IP address that is used in a DNS list lookup is the IP address
of the calling host. However, you can specify another IP address by listing it
after the domain name, introduced by a slash. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny dnslists = black.list.tld/192.168.1.2
</pre></td></tr></table>

<p>This feature is not very helpful with explicit IP addresses; it is intended for
use with IP addresses that are looked up, for example, the IP addresses of the
MX hosts or nameservers of an email sender address. For an example, see section
<a href="#SEC335">Multiple explicit keys for a DNS list</a> below.
</p>
<hr size="6">
<a name="DNS-lists-keyed-on-domain-names"></a>
<a name="SEC334"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC333" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC335" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.26 DNS lists keyed on domain names </h2>

<p>There are some lists that are keyed on domain names rather than inverted IP
addresses (see for example the <em>domain based zones</em> link at
<strong><a href="http://www.rfc-ignorant.org/">http://www.rfc-ignorant.org/</a></strong>). No reversing of components is used
with these lists. You can change the name that is looked up in a DNS list by
listing it after the domain name, introduced by a slash. For example,
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny  message  = Sender's domain is listed at $dnslist_domain
      dnslists = dsn.rfc-ignorant.org/$sender_address_domain
</pre></td></tr></table>

<p>This particular example is useful only in ACLs that are obeyed after the
RCPT or DATA commands, when a sender address is available. If (for
example) the message's sender is <em>user@tld.example</em> the name that is looked
up by this example is
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">tld.example.dsn.rfc-ignorant.org
</pre></td></tr></table>

<p>A single <code>dnslists</code> condition can contain entries for both names and IP
addresses. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny dnslists = sbl.spamhaus.org : \
                dsn.rfc-ignorant.org/$sender_address_domain
</pre></td></tr></table>

<p>The first item checks the sending host's IP address; the second checks a domain
name. The whole condition is true if either of the DNS lookups succeeds.
</p>
<hr size="6">
<a name="Multiple-explicit-keys-for-a-DNS-list"></a>
<a name="SEC335"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC334" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC336" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.27 Multiple explicit keys for a DNS list </h2>

<p>The syntax described above for looking up explicitly-defined values (either
names or IP addresses) in a DNS blacklist is a simplification. After the domain
name for the DNS list, what follows the slash can in fact be a list of items.
As with all lists in Exim, the default separator is a colon. However, because
this is a sublist within the list of DNS blacklist domains, it is necessary
either to double the separators like this:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">dnslists = black.list.tld/name.1::name.2
</pre></td></tr></table>

<p>or to change the separator character, like this:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">dnslists = black.list.tld/&lt;;name.1;name.2
</pre></td></tr></table>

<p>If an item in the list is an IP address, it is inverted before the DNS
blacklist domain is appended. If it is not an IP address, no inversion
occurs. Consider this condition:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">dnslists = black.list.tld/&lt;;192.168.1.2;a.domain
</pre></td></tr></table>

<p>The DNS lookups that occur are:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">2.1.168.192.black.list.tld
a.domain.black.list.tld
</pre></td></tr></table>

<p>Once a DNS record has been found (that matches a specific IP return
address, if specified - see section <a href="#SEC338">Additional matching conditions for DNS lists</a>), no further lookups
are done. If there is a temporary DNS error, the rest of the sublist of domains
or IP addresses is tried. A temporary error for the whole dnslists item occurs
only if no other DNS lookup in this sublist succeeds. In other words, a
successful lookup for any of the items in the sublist overrides a temporary
error for a previous item.
</p>
<p>The ability to supply a list of items after the slash is in some sense just a
syntactic convenience. These two examples have the same effect:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">dnslists = black.list.tld/a.domain : black.list.tld/b.domain
dnslists = black.list.tld/a.domain::b.domain
</pre></td></tr></table>

<p>However, when the data for the list is obtained from a lookup, the second form
is usually much more convenient. Consider this example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny message  = The mail servers for the domain \
                $sender_address_domain \
                are listed at $dnslist_domain ($dnslist_value); \
                see $dnslist_text.
     dnslists = sbl.spamhaus.org/&lt;|${lookup dnsdb {&gt;|a=&lt;|\
                                   ${lookup dnsdb {&gt;|mxh=\
                                   $sender_address_domain} }} }
</pre></td></tr></table>

<p>Note the use of &lsquo;<samp>&gt;|</samp>&rsquo; in the dnsdb lookup to specify the separator for
multiple DNS records. The inner dnsdb lookup produces a list of MX hosts
and the outer dnsdb lookup finds the IP addresses for these hosts. The result
of expanding the condition might be something like this:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">dnslists = sbl.spahmaus.org/&lt;|192.168.2.3|192.168.5.6|...
</pre></td></tr></table>

<p>Thus, this example checks whether or not the IP addresses of the sender
domain's mail servers are on the Spamhaus black list.
</p>
<p>The key that was used for a successful DNS list lookup is put into the variable
<code>$dnslist_matched</code> (see section <a href="#SEC337">Variables set from DNS lists</a>).
</p>
<hr size="6">
<a name="Data-returned-by-DNS-lists"></a>
<a name="SEC336"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC335" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC337" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.28 Data returned by DNS lists </h2>

<p>DNS lists are constructed using address records in the DNS. The original RBL
just used the address 127.0.0.1 on the right hand side of each record, but the
RBL+ list and some other lists use a number of values with different meanings.
The values used on the RBL+ list are:
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">127.1.0.1  RBL
127.1.0.2  DUL
127.1.0.3  DUL and RBL
127.1.0.4  RSS
127.1.0.5  RSS and RBL
127.1.0.6  RSS and DUL
127.1.0.7  RSS and DUL and RBL
</pre></td></tr></table>

<p>Section <a href="#SEC338">Additional matching conditions for DNS lists</a> below describes how you can distinguish between
different values. Some DNS lists may return more than one address record;
see section <a href="#SEC340">Handling multiple DNS records from a DNS list</a> for details of how they are checked.
</p>
<hr size="6">
<a name="Variables-set-from-DNS-lists"></a>
<a name="SEC337"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC336" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC338" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.29 Variables set from DNS lists </h2>

<p>When an entry is found in a DNS list, the variable <code>$dnslist_domain</code> contains
the name of the overall domain that matched (for example,
&lsquo;<samp>spamhaus.example</samp>&rsquo;), <code>$dnslist_matched</code> contains the key within that domain
(for example, &lsquo;<samp>192.168.5.3</samp>&rsquo;), and <code>$dnslist_value</code> contains the data from
the DNS record. When the key is an IP address, it is not reversed in
<code>$dnslist_matched</code> (though it is, of course, in the actual lookup). In simple
cases, for example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny dnslists = spamhaus.example
</pre></td></tr></table>

<p>the key is also available in another variable (in this case,
<code>$sender_host_address</code>). In more complicated cases, however, this is not true.
For example, using a data lookup (as described in section <a href="#SEC335">Multiple explicit keys for a DNS list</a>)
might generate a dnslists lookup like this:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny dnslists = spamhaus.example/&lt;|192.168.1.2|192.168.6.7|...
</pre></td></tr></table>

<p>If this condition succeeds, the value in <code>$dnslist_matched</code> might be
&lsquo;<samp>192.168.6.7</samp>&rsquo; (for example).
</p>
<p>If more than one address record is returned by the DNS lookup, all the IP
addresses are included in <code>$dnslist_value</code>, separated by commas and spaces.
The variable <code>$dnslist_text</code> contains the contents of any associated TXT
record. For lists such as RBL+ the TXT record for a merged entry is often not
very meaningful. See section <a href="#SEC341">Detailed information from merged DNS lists</a> for a way of obtaining more
information.
</p>
<p>You can use the DNS list variables in <code>message</code> or <code>log_message</code> modifiers
- although these appear before the condition in the ACL, they are not
expanded until after it has failed. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny    hosts = !+local_networks
        message = $sender_host_address is listed \
                  at $dnslist_domain
        dnslists = rbl-plus.mail-abuse.example
</pre></td></tr></table>

<hr size="6">
<a name="Additional-matching-conditions-for-DNS-lists"></a>
<a name="SEC338"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC337" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC339" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.30 Additional matching conditions for DNS lists </h2>

<p>You can add an equals sign and an IP address after a <code>dnslists</code> domain name
in order to restrict its action to DNS records with a matching right hand side.
For example,
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny dnslists = rblplus.mail-abuse.org=127.0.0.2
</pre></td></tr></table>

<p>rejects only those hosts that yield 127.0.0.2. Without this additional data,
any address record is considered to be a match. For the moment, we assume
that the DNS lookup returns just one record. Section <a href="#SEC340">Handling multiple DNS records from a DNS list</a>
describes how multiple records are handled.
</p>
<p>More than one IP address may be given for checking, using a comma as a
separator. These are alternatives - if any one of them matches, the
<code>dnslists</code> condition is true. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny  dnslists = a.b.c=127.0.0.2,127.0.0.3
</pre></td></tr></table>

<p>If you want to specify a constraining address list and also specify names or IP
addresses to be looked up, the constraining address list must be specified
first. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny dnslists = dsn.rfc-ignorant.org\
                =127.0.0.2/$sender_address_domain
</pre></td></tr></table>

<p>If the character &lsquo;<samp>&amp;</samp>&rsquo; is used instead of &lsquo;<samp>=</samp>&rsquo;, the comparison for each
listed IP address is done by a bitwise &quot;and&quot; instead of by an equality test.
In other words, the listed addresses are used as bit masks. The comparison is
true if all the bits in the mask are present in the address that is being
tested. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">dnslists = a.b.c&amp;0.0.0.3
</pre></td></tr></table>

<p>matches if the address is <em>x.x.x.</em>3, <em>x.x.x.</em>7, <em>x.x.x.</em>11, etc. If you
want to test whether one bit or another bit is present (as opposed to both
being present), you must use multiple values. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">dnslists = a.b.c&amp;0.0.0.1,0.0.0.2
</pre></td></tr></table>

<p>matches if the final component of the address is an odd number or two times
an odd number.
</p>
<hr size="6">
<a name="Negated-DNS-matching-conditions"></a>
<a name="SEC339"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC338" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC340" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.31 Negated DNS matching conditions </h2>

<p>You can supply a negative list of IP addresses as part of a <code>dnslists</code>
condition. Whereas
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny  dnslists = a.b.c=127.0.0.2,127.0.0.3
</pre></td></tr></table>

<p>means &quot;deny if the host is in the black list at the domain <em>a.b.c</em> and the
IP address yielded by the list is either 127.0.0.2 or 127.0.0.3&quot;,
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny  dnslists = a.b.c!=127.0.0.2,127.0.0.3
</pre></td></tr></table>

<p>means &quot;deny if the host is in the black list at the domain <em>a.b.c</em> and the
IP address yielded by the list is not 127.0.0.2 and not 127.0.0.3&quot;. In other
words, the result of the test is inverted if an exclamation mark appears before
the &lsquo;<samp>=</samp>&rsquo; (or the &lsquo;<samp>&amp;</samp>&rsquo;) sign.
</p>
<p><strong>Note</strong>: This kind of negation is not the same as negation in a domain,
host, or address list (which is why the syntax is different).
</p>
<p>If you are using just one list, the negation syntax does not gain you much. The
previous example is precisely equivalent to
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny  dnslists = a.b.c
     !dnslists = a.b.c=127.0.0.2,127.0.0.3
</pre></td></tr></table>

<p>However, if you are using multiple lists, the negation syntax is clearer.
Consider this example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny  dnslists = sbl.spamhaus.org : \
                 list.dsbl.org : \
                 dnsbl.njabl.org!=127.0.0.3 : \
                 relays.ordb.org
</pre></td></tr></table>

<p>Using only positive lists, this would have to be:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny  dnslists = sbl.spamhaus.org : \
                 list.dsbl.org
deny  dnslists = dnsbl.njabl.org
     !dnslists = dnsbl.njabl.org=127.0.0.3
deny  dnslists = relays.ordb.org
</pre></td></tr></table>

<p>which is less clear, and harder to maintain.
</p>
<hr size="6">
<a name="Handling-multiple-DNS-records-from-a-DNS-list"></a>
<a name="SEC340"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC339" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC341" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.32 Handling multiple DNS records from a DNS list </h2>

<p>A DNS lookup for a <code>dnslists</code> condition may return more than one DNS record,
thereby providing more than one IP address. When an item in a <code>dnslists</code> list
is followed by &lsquo;<samp>=</samp>&rsquo; or &lsquo;<samp>&amp;</samp>&rsquo; and a list of IP addresses, in order to restrict
the match to specific results from the DNS lookup, there are two ways in which
the checking can be handled. For example, consider the condition:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">dnslists = a.b.c=127.0.0.1
</pre></td></tr></table>

<p>What happens if the DNS lookup for the incoming IP address yields both
127.0.0.1 and 127.0.0.2 by means of two separate DNS records? Is the
condition true because at least one given value was found, or is it false
because at least one of the found values was not listed? And how does this
affect negated conditions? Both possibilities are provided for with the help of
additional separators &lsquo;<samp>==</samp>&rsquo; and &lsquo;<samp>=&amp;</samp>&rsquo;.
</p>
<ul class="toc">
<li>
If &lsquo;<samp>=</samp>&rsquo; or &lsquo;<samp>&amp;</samp>&rsquo; is used, the condition is true if any one of the looked up
IP addresses matches one of the listed addresses. For the example above, the
condition is true because 127.0.0.1 matches.

</li><li>
If &lsquo;<samp>==</samp>&rsquo; or &lsquo;<samp>=&amp;</samp>&rsquo; is used, the condition is true only if every one of the
looked up IP addresses matches one of the listed addresses. If the condition is
changed to:

<table><tr><td>&nbsp;</td><td><pre class="example">dnslists = a.b.c==127.0.0.1
</pre></td></tr></table>

<p>and the DNS lookup yields both 127.0.0.1 and 127.0.0.2, the condition is
false because 127.0.0.2 is not listed. You would need to have:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">dnslists = a.b.c==127.0.0.1,127.0.0.2
</pre></td></tr></table>

<p>for the condition to be true.
</p></li></ul>

<p>When &lsquo;<samp>!</samp>&rsquo; is used to negate IP address matching, it inverts the result, giving
the precise opposite of the behaviour above. Thus:
</p>
<ul class="toc">
<li>
If &lsquo;<samp>!=</samp>&rsquo; or &lsquo;<samp>!&amp;</samp>&rsquo; is used, the condition is true if none of the looked up IP
addresses matches one of the listed addresses. Consider:

<table><tr><td>&nbsp;</td><td><pre class="example">dnslists = a.b.c!&amp;0.0.0.1
</pre></td></tr></table>

<p>If the DNS lookup yields both 127.0.0.1 and 127.0.0.2, the condition is
false because 127.0.0.1 matches.
</p>
</li><li>
If &lsquo;<samp>!==</samp>&rsquo; or &lsquo;<samp>!=&amp;</samp>&rsquo; is used, the condition is true there is at least one
looked up IP address that does not match. Consider:

<table><tr><td>&nbsp;</td><td><pre class="example">dnslists = a.b.c!=&amp;0.0.0.1
</pre></td></tr></table>

<p>If the DNS lookup yields both 127.0.0.1 and 127.0.0.2, the condition is
true, because 127.0.0.2 does not match. You would need to have:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">dnslists = a.b.c!=&amp;0.0.0.1,0.0.0.2
</pre></td></tr></table>

<p>for the condition to be false.
</p></li></ul>

<p>When the DNS lookup yields only a single IP address, there is no difference
between &lsquo;<samp>=</samp>&rsquo; and &lsquo;<samp>==</samp>&rsquo; and between &lsquo;<samp>&amp;</samp>&rsquo; and &lsquo;<samp>=&amp;</samp>&rsquo;.
</p>
<hr size="6">
<a name="Detailed-information-from-merged-DNS-lists"></a>
<a name="SEC341"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC340" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC342" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.33 Detailed information from merged DNS lists </h2>

<p>When the facility for restricting the matching IP values in a DNS list is used,
the text from the TXT record that is set in <code>$dnslist_text</code> may not reflect
the true reason for rejection. This happens when lists are merged and the IP
address in the A record is used to distinguish them; unfortunately there is
only one TXT record. One way round this is not to use merged lists, but that
can be inefficient because it requires multiple DNS lookups where one would do
in the vast majority of cases when the host of interest is not on any of the
lists.
</p>
<p>A less inefficient way of solving this problem is available. If
two domain names, comma-separated, are given, the second is used first to
do an initial check, making use of any IP value restrictions that are set.
If there is a match, the first domain is used, without any IP value
restrictions, to get the TXT record. As a byproduct of this, there is also
a check that the IP being tested is indeed on the first list. The first
domain is the one that is put in <code>$dnslist_domain</code>. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">reject message  = \
         rejected because $sender_host_address is blacklisted \
         at $dnslist_domain\n$dnslist_text
       dnslists = \
         sbl.spamhaus.org,sbl-xbl.spamhaus.org=127.0.0.2 : \
         dul.dnsbl.sorbs.net,dnsbl.sorbs.net=127.0.0.10
</pre></td></tr></table>

<p>For the first blacklist item, this starts by doing a lookup in
<em>sbl-xbl.spamhaus.org</em> and testing for a 127.0.0.2 return. If there is a
match, it then looks in <em>sbl.spamhaus.org</em>, without checking the return
value, and as long as something is found, it looks for the corresponding TXT
record. If there is no match in <em>sbl-xbl.spamhaus.org</em>, nothing more is done.
The second blacklist item is processed similarly.
</p>
<p>If you are interested in more than one merged list, the same list must be
given several times, but because the results of the DNS lookups are cached,
the DNS calls themselves are not repeated. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">reject dnslists = \
         http.dnsbl.sorbs.net,dnsbl.sorbs.net=127.0.0.2 : \
         socks.dnsbl.sorbs.net,dnsbl.sorbs.net=127.0.0.3 : \
         misc.dnsbl.sorbs.net,dnsbl.sorbs.net=127.0.0.4 : \
         dul.dnsbl.sorbs.net,dnsbl.sorbs.net=127.0.0.10
</pre></td></tr></table>

<p>In this case there is one lookup in <em>dnsbl.sorbs.net</em>, and if none of the IP
values matches (or if no record is found), this is the only lookup that is
done. Only if there is a match is one of the more specific lists consulted.
</p>
<hr size="6">
<a name="DNS-lists-and-IPv6"></a>
<a name="SEC342"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC341" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC343" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.34 DNS lists and IPv6 </h2>

<p>If Exim is asked to do a dnslist lookup for an IPv6 address, it inverts it
nibble by nibble. For example, if the calling host's IP address is
3ffe:ffff:836f:0a00:000a:0800:200a:c031, Exim might look up
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">1.3.0.c.a.0.0.2.0.0.8.0.a.0.0.0.0.0.a.0.f.6.3.8.
  f.f.f.f.e.f.f.3.blackholes.mail-abuse.org
</pre></td></tr></table>

<p>(split over two lines here to fit on the page). Unfortunately, some of the DNS
lists contain wildcard records, intended for IPv4, that interact badly with
IPv6. For example, the DNS entry
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">*.3.some.list.example.    A    127.0.0.1
</pre></td></tr></table>

<p>is probably intended to put the entire 3.0.0.0/8 IPv4 network on the list.
Unfortunately, it also matches the entire 3::/4 IPv6 network.
</p>
<p>You can exclude IPv6 addresses from DNS lookups by making use of a suitable
<code>condition</code> condition, as in this example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny   condition = ${if isip4{$sender_host_address}}
       dnslists  = some.list.example
</pre></td></tr></table>

<hr size="6">
<a name="Rate-limiting-incoming-messages"></a>
<a name="SEC343"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC342" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC344" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.35 Rate limiting incoming messages </h2>

<p>The <code>ratelimit</code> ACL condition can be used to measure and control the rate at
which clients can send email. This is more powerful than the
<code>smtp_ratelimit_*</code> options, because those options control the rate of
commands in a single SMTP session only, whereas the <code>ratelimit</code> condition
works across all connections (concurrent and sequential) from the same client
host. The syntax of the <code>ratelimit</code> condition is:
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">ratelimit = &lt;m&gt; / &lt;p&gt; / &lt;options&gt; / &lt;key&gt;
</pre></td></tr></table>

<p>If the average client sending rate is less than <em>m</em> messages per time
period <em>p</em> then the condition is false; otherwise it is true.
</p>
<p>As a side-effect, the <code>ratelimit</code> condition sets the expansion variable
<code>$sender_rate</code> to the client's computed rate, <code>$sender_rate_limit</code> to the
configured value of <em>m</em>, and <code>$sender_rate_period</code> to the configured value
of <em>p</em>.
</p>
<p>The parameter <em>p</em> is the smoothing time constant, in the form of an Exim
time interval, for example, &lsquo;<samp>8h</samp>&rsquo; for eight hours. A larger time constant
means that it takes Exim longer to forget a client's past behaviour. The
parameter <em>m</em> is the maximum number of messages that a client is permitted to
send in each time interval. It also specifies the number of messages permitted
in a fast burst. By increasing both <em>m</em> and <em>p</em> but keeping <em>m/p</em>
constant, you can allow a client to send more messages in a burst without
changing its overall sending rate limit. Conversely, if <em>m</em> and <em>p</em> are
both small, messages must be sent at an even rate.
</p>
<p>There is a script in &lsquo;<tt>util/ratelimit.pl</tt>&rsquo; which extracts sending rates from
log files, to assist with choosing appropriate settings for <em>m</em> and <em>p</em>
when deploying the <code>ratelimit</code> ACL condition. The script prints usage
instructions when it is run with no arguments.
</p>
<p>The key is used to look up the data for calculating the client's average
sending rate. This data is stored in a database maintained by Exim in its spool
directory, alongside the retry and other hints databases. The default key is
<code>$sender_host_address</code>, which applies the limit to each client host IP address.
By changing the key you can change how Exim identifies clients for the purpose
of ratelimiting. For example, to limit the sending rate of each authenticated
user, independent of the computer they are sending from, set the key to
<code>$authenticated_id</code>. You must ensure that the lookup key is meaningful; for
example, <code>$authenticated_id</code> is only meaningful if the client has
authenticated, and you can check with the <code>authenticated</code> ACL condition.
</p>
<p>If you want to limit the rate at which a recipient receives messages, you can
use the key &lsquo;<samp>$local_part@$domain</samp>&rsquo; with the <code>per_rcpt</code> option (see below) in
a RCPT ACL.
</p>
<p>Internally, Exim includes the smoothing constant <em>p</em> and the options in the
lookup key because they alter the meaning of the stored data. This is not true
for the limit <em>m</em>, so you can alter the configured maximum rate and Exim will
still remember clients' past behaviour, but if you alter the other ratelimit
parameters Exim forgets past behaviour.
</p>
<p>Each <code>ratelimit</code> condition can have up to three options. One option
specifies what Exim measures the rate of, and the second specifies how Exim
handles excessively fast clients. The third option can be &lsquo;<samp>noupdate</samp>&rsquo;, to
disable updating of the ratelimiting database (see section <a href="#SEC347">Reading ratelimit data without updating</a>).
The options are separated by a slash, like the other parameters. They may
appear in any order.
</p>
<hr size="6">
<a name="Ratelimit-options-for-what-is-being-measured"></a>
<a name="SEC344"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC343" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC345" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.36 Ratelimit options for what is being measured </h2>

<p>The <code>per_conn</code> option limits the client's connection rate.
</p>
<p>The <code>per_mail</code> option limits the client's rate of sending messages. This is
the default if none of the <code>per_*</code> options is specified.
</p>
<p>The <code>per_byte</code> option limits the sender's email bandwidth. Note that it is
best to use this option in the DATA ACL; if it is used in an earlier ACL it
relies on the SIZE parameter on the MAIL command, which may be inaccurate or
completely missing. You can follow the limit <em>m</em> in the configuration with K,
M, or G to specify limits in kilobytes, megabytes, or gigabytes, respectively.
</p>
<p>The <code>per_rcpt</code> option causes Exim to limit the rate at which
recipients are accepted. To be effective, it would need to be used in
either the <code>acl_smtp_rcpt</code> or the <code>acl_not_smtp</code> ACL. In the
<code>acl_smtp_rcpt</code> ACL, the number of recipients is incremented by one.
In the case of a locally submitted message in the <code>acl_not_smtp</code> ACL,
the number of recipients incremented is equal to <code>$recipients_count</code>
for the entire message. Note that in either case the rate limiting
engine will see a message with many recipients as a large high-speed
burst.
</p>
<p>The <code>per_cmd</code> option causes Exim to recompute the rate every time the
condition is processed. This can be used to limit the SMTP command rate.
This command is essentially an alias of <code>per_rcpt</code> to make it clear
that the effect is to limit the rate at which individual commands,
rather than recipients, are accepted.
</p>
<hr size="6">
<a name="Ratelimit-options-for-handling-fast-clients"></a>
<a name="SEC345"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC344" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC346" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.37 Ratelimit options for handling fast clients </h2>

<p>If a client's average rate is greater than the maximum, the rate limiting
engine can react in two possible ways, depending on the presence of the
<code>strict</code> or <code>leaky</code> options. This is independent of the other
counter-measures (such as rejecting the message) that may be specified by the
rest of the ACL. The default mode is leaky, which avoids a sender's
over-aggressive retry rate preventing it from getting any email through.
</p>
<p>The <code>strict</code> option means that the client's recorded rate is always updated.
The effect of this is that Exim measures the client's average rate of attempts
to send email, which can be much higher than the maximum it is actually
allowed. If the client is over the limit it may be subjected to
counter-measures in the ACL until it slows down below the maximum rate. The
smoothing period determines the time it takes for a high sending rate to decay
exponentially to 37% of its peak value, which means that you can work out the
time (the number of smoothing periods) that a client is subjected to
counter-measures after an over-limit burst with this formula:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">ln(peakrate/maxrate)
</pre></td></tr></table>

<p>The <code>leaky</code> (default) option means that the client's recorded rate is not
updated if it is above the limit. The effect of this is that Exim measures the
client's average rate of successfully sent email, which cannot be greater than
the maximum allowed. If the client is over the limit it may suffer some
counter-measures (as specified in the ACL), but it will still be able to send
email at the configured maximum rate, whatever the rate of its attempts. This
is generally the better choice if you have clients that retry automatically.
</p>
<hr size="6">
<a name="Using-rate-limiting"></a>
<a name="SEC346"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC345" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC347" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.38 Using rate limiting </h2>

<p>Exim's other ACL facilities are used to define what counter-measures are taken
when the rate limit is exceeded. This might be anything from logging a warning
(for example, while measuring existing sending rates in order to define
policy), through time delays to slow down fast senders, up to rejecting the
message. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example"># Log all senders' rates
warn ratelimit = 0 / 1h / strict
     log_message = Sender rate $sender_rate / $sender_rate_period

# Slow down fast senders; note the need to truncate $sender_rate
# at the decimal point.
warn ratelimit = 100 / 1h / per_rcpt / strict
     delay     = ${eval: ${sg{$sender_rate}{[.].*}{}} - \
                   $sender_rate_limit }s

# Keep authenticated users under control
deny authenticated = *
     ratelimit = 100 / 1d / strict / $authenticated_id

# System-wide rate limit
defer message = Sorry, too busy. Try again later.
     ratelimit = 10 / 1s / $primary_hostname

# Restrict incoming rate from each host, with a default
# set using a macro and special cases looked up in a table.
defer message = Sender rate exceeds $sender_rate_limit \
               messages per $sender_rate_period
     ratelimit = ${lookup {$sender_host_address} \
                   cdb {DB/ratelimits.cdb} \
                   {$value} {RATELIMIT} }
</pre></td></tr></table>

<p><strong>Warning</strong>: If you have a busy server with a lot of <code>ratelimit</code> tests,
especially with the <code>per_rcpt</code> option, you may suffer from a performance
bottleneck caused by locking on the ratelimit hints database. Apart from
making your ACLs less complicated, you can reduce the problem by using a
RAM disk for Exim's hints directory (usually &lsquo;<tt>/var/spool/exim/db/</tt>&rsquo;). However
this means that Exim will lose its hints data after a reboot (including retry
hints, the callout cache, and ratelimit data).
</p>
<hr size="6">
<a name="Reading-ratelimit-data-without-updating"></a>
<a name="SEC347"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC346" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC348" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.39 Reading ratelimit data without updating </h2>

<p>If the <code>noupdate</code> option is present on a <code>ratelimit</code> ACL condition, Exim
computes the rate and checks the limit as normal, but it does not update the
saved data. This means that, in relevant ACLs, it is possible to lookup the
existence of a specified (or auto-generated) ratelimit key without incrementing
the ratelimit counter for that key. In order for this to be useful, another ACL
entry must set the rate for the same key (otherwise it will always be zero).
For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">acl_check_connect:
  deny ratelimit = 100 / 5m / strict / noupdate
       log_message = RATE: $sender_rate/$sender_rate_period \
                     (max $sender_rate_limit)
</pre></td></tr></table>

<table><tr><td>&nbsp;</td><td><pre class="display">... some other logic and tests...
</pre></td></tr></table>

<table><tr><td>&nbsp;</td><td><pre class="example">acl_check_mail:
  warn ratelimit = 100 / 5m / strict / per_cmd
       condition = ${if le{$sender_rate}{$sender_rate_limit}}
       logwrite  = RATE UPDATE: $sender_rate/$sender_rate_period \
                     (max $sender_rate_limit)
</pre></td></tr></table>

<p>In this example, the rate is tested and used to deny access (when it is too
high) in the connect ACL, but the actual computation of the remembered rate
happens later, on a per-command basis, in another ACL.
</p>
<hr size="6">
<a name="Address-verification"></a>
<a name="SEC348"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC347" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC349" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.40 Address verification </h2>

<p>Several of the <code>verify</code> conditions described in section
<a href="#SEC331">ACL conditions</a> cause addresses to be verified. Section
<a href="#SEC352">Sender address verification reporting</a> discusses the reporting of sender verification failures.
The verification conditions can be followed by options that modify the
verification process. The options are separated from the keyword and from each
other by slashes, and some of them contain parameters. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">verify = sender/callout
verify = recipient/defer_ok/callout=10s,defer_ok
</pre></td></tr></table>

<p>The first stage of address verification, which always happens, is to run the
address through the routers, in &quot;verify mode&quot;. Routers can detect the
difference between verification and routing for delivery, and their actions can
be varied by a number of generic options such as <code>verify</code> and <code>verify_only</code>
(see chapter <a href="spec_15.html#SEC186">Generic options for routers</a>). If routing fails, verification fails.
The available options are as follows:
</p>
<ul class="toc">
<li>
If the <code>callout</code> option is specified, successful routing to one or more
remote hosts is followed by a &quot;callout&quot; to those hosts as an additional
check. Callouts and their sub-options are discussed in the next section.

</li><li>
If there is a defer error while doing verification routing, the ACL
normally returns &quot;defer&quot;. However, if you include <code>defer_ok</code> in the
options, the condition is forced to be true instead. Note that this is a main
verification option as well as a suboption for callouts.

</li><li>
The <code>no_details</code> option is covered in section <a href="#SEC352">Sender address verification reporting</a>, which
discusses the reporting of sender address verification failures.

</li><li>
The <code>success_on_redirect</code> 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 <a href="#SEC353">Redirection while verifying</a>.
</li></ul>

<a name="IDX2638"></a>
<a name="IDX2639"></a>
<a name="IDX2640"></a>
<a name="IDX2641"></a>
<p>After an address verification failure, <code>$acl_verify_message</code> contains the
error message that is associated with the failure. It can be preserved by
coding like this:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">warn  !verify = sender
       set acl_m0 = $acl_verify_message
</pre></td></tr></table>

<p>If you are writing your own custom rejection message or log message when
denying access, you can use this variable to include information about the
verification failure.
</p>
<p>In addition, <code>$sender_verify_failure</code> or <code>$recipient_verify_failure</code> (as
appropriate) contains one of the following words:
</p>
<ul class="toc">
<li>
<code>qualify</code>: The address was unqualified (no domain), and the message
was neither local nor came from an exempted host.

</li><li>
<code>route</code>: Routing failed.

</li><li>
<code>mail</code>: Routing succeeded, and a callout was attempted; rejection
occurred at or before the MAIL command (that is, on initial
connection, HELO, or MAIL).

</li><li>
<code>recipient</code>: The RCPT command in a callout was rejected.

</li><li>
<code>postmaster</code>: The postmaster check in a callout was rejected.
</li></ul>

<p>The main use of these variables is expected to be to distinguish between
rejections of MAIL and rejections of RCPT in callouts.
</p>
<hr size="6">
<a name="Callout-verification"></a>
<a name="SEC349"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC348" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC350" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.41 Callout verification </h2>

<p>For non-local addresses, routing verifies the domain, but is unable to do any
checking of the local part. There are situations where some means of verifying
the local part is desirable. One way this can be done is to make an SMTP
<em>callback</em> to a delivery host for the sender address or a <em>callforward</em> to
a subsequent host for a recipient address, to see if the host accepts the
address. We use the term <em>callout</em> to cover both cases. Note that for a
sender address, the callback is not to the client host that is trying to
deliver the message, but to one of the hosts that accepts incoming mail for the
sender's domain.
</p>
<p>Exim does not do callouts by default. If you want them to happen, you must
request them by setting appropriate options on the <code>verify</code> condition, as
described below. This facility should be used with care, because it can add a
lot of resource usage to the cost of verifying an address. However, Exim does
cache the results of callouts, which helps to reduce the cost. Details of
caching are in section <a href="#SEC351">Callout caching</a>.
</p>
<p>Recipient callouts are usually used only between hosts that are controlled by
the same administration. For example, a corporate gateway host could use
callouts to check for valid recipients on an internal mailserver. A successful
callout does not guarantee that a real delivery to the address would succeed;
on the other hand, a failing callout does guarantee that a delivery would fail.
</p>
<p>If the <code>callout</code> option is present on a condition that verifies an address, a
second stage of verification occurs if the address is successfully routed to
one or more remote hosts. The usual case is routing by a <code>dnslookup</code> or a
<code>manualroute</code> router, where the router specifies the hosts. However, if a
router that does not set up hosts routes to an <code>smtp</code> transport with a
<code>hosts</code> setting, the transport's hosts are used. If an <code>smtp</code> transport has
<code>hosts_override</code> set, its hosts are always used, whether or not the router
supplies a host list.
</p>
<p>The port that is used is taken from the transport, if it is specified and is a
remote transport. (For routers that do verification only, no transport need be
specified.) Otherwise, the default SMTP port is used. If a remote transport
specifies an outgoing interface, this is used; otherwise the interface is not
specified. Likewise, the text that is used for the HELO command is taken from
the transport's <code>helo_data</code> option; if there is no transport, the value of
<code>$smtp_active_hostname</code> is used.
</p>
<p>For a sender callout check, Exim makes SMTP connections to the remote hosts, to
test whether a bounce message could be delivered to the sender address. The
following SMTP commands are sent:
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">HELO &lt;local host name&gt;
MAIL FROM:&lt;&gt;
RCPT TO:&lt;the address to be tested&gt;
QUIT
</pre></td></tr></table>

<p>LHLO is used instead of HELO if the transport's <code>protocol</code> option is
set to &quot;lmtp&quot;.
</p>
<p>A recipient callout check is similar. By default, it also uses an empty address
for the sender. This default is chosen because most hosts do not make use of
the sender address when verifying a recipient. Using the same address means
that a single cache entry can be used for each recipient. Some sites, however,
do make use of the sender address when verifying. These are catered for by the
<code>use_sender</code> and <code>use_postmaster</code> options, described in the next section.
</p>
<p>If the response to the RCPT command is a 2<em>xx</em> code, the verification
succeeds. If it is 5<em>xx</em>, the verification fails. For any other condition,
Exim tries the next host, if any. If there is a problem with all the remote
hosts, the ACL yields &quot;defer&quot;, unless the <code>defer_ok</code> parameter of the
<code>callout</code> option is given, in which case the condition is forced to succeed.
</p>
<a name="IDX2642"></a>
<p>A callout may take a little time. For this reason, Exim normally flushes SMTP
output before performing a callout in an ACL, to avoid unexpected timeouts in
clients when the SMTP PIPELINING extension is in use. The flushing can be
disabled by using a <code>control</code> modifier to set <code>no_callout_flush</code>.
</p>
<hr size="6">
<a name="Additional-parameters-for-callouts"></a>
<a name="SEC350"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC349" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC351" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.42 Additional parameters for callouts </h2>

<p>The <code>callout</code> option can be followed by an equals sign and a number of
optional parameters, separated by commas. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">verify = recipient/callout=10s,defer_ok
</pre></td></tr></table>

<p>The old syntax, which had <code>callout_defer_ok</code> and <code>check_postmaster</code> as
separate verify options, is retained for backwards compatibility, but is now
deprecated. The additional parameters for <code>callout</code> are as follows:
</p>
<dl compact="compact">
<dt> &lt;<em>atimeinterval</em>&gt;</dt>
<dd><a name="IDX2643"></a>
<p>This specifies the timeout that applies for the callout attempt to each host.
For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">verify = sender/callout=5s
</pre></td></tr></table>

<p>The default is 30 seconds. The timeout is used for each response from the
remote host. It is also used for the initial connection, unless overridden by
the <code>connect</code> parameter.
</p>
</dd>
<dt> <strong>connect=</strong>&lt;<em>timeinterval</em>&gt;</dt>
<dd><a name="IDX2644"></a>
<p>This parameter makes it possible to set a different (usually smaller) timeout
for making the SMTP connection. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">verify = sender/callout=5s,connect=1s
</pre></td></tr></table>

<p>If not specified, this timeout defaults to the general timeout value.
</p>
</dd>
<dt> <strong>defer_ok</strong></dt>
<dd><a name="IDX2645"></a>
<p>When this parameter is present, failure to contact any host, or any other kind
of temporary error, is treated as success by the ACL. However, the cache is not
updated in this circumstance.
</p>
</dd>
<dt> <strong>fullpostmaster</strong></dt>
<dd><a name="IDX2646"></a>
<p>This operates like the <code>postmaster</code> option (see below), but if the check for
<em>postmaster@domain</em> fails, it tries just <em>postmaster</em>, without a domain, in
accordance with the specification in RFC 2821. The RFC states that the
unqualified address <em>postmaster</em> should be accepted.
</p>
</dd>
<dt> <strong>mailfrom=</strong>&lt;<em>emailaddress</em>&gt;</dt>
<dd><a name="IDX2647"></a>
<p>When verifying addresses in header lines using the <code>header_sender</code>
verification option, Exim behaves by default as if the addresses are envelope
sender addresses from a message. Callout verification therefore tests to see
whether a bounce message could be delivered, by using an empty address in the
MAIL command. However, it is arguable that these addresses might never be used
as envelope senders, and could therefore justifiably reject bounce messages
(empty senders). The <code>mailfrom</code> callout parameter allows you to specify what
address to use in the MAIL command. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">require  verify = header_sender/callout=mailfrom=abcd@x.y.z
</pre></td></tr></table>

<p>This parameter is available only for the <code>header_sender</code> verification option.
</p>
</dd>
<dt> <strong>maxwait=</strong>&lt;<em>timeinterval</em>&gt;</dt>
<dd><a name="IDX2648"></a>
<p>This parameter sets an overall timeout for performing a callout verification.
For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">verify = sender/callout=5s,maxwait=30s
</pre></td></tr></table>

<p>This timeout defaults to four times the callout timeout for individual SMTP
commands. The overall timeout applies when there is more than one host that can
be tried. The timeout is checked before trying the next host. This prevents
very long delays if there are a large number of hosts and all are timing out
(for example, when network connections are timing out).
</p>
</dd>
<dt> <strong>no_cache</strong></dt>
<dd><a name="IDX2649"></a>
<a name="IDX2650"></a>
<p>When this parameter is given, the callout cache is neither read nor updated.
</p>
</dd>
<dt> <strong>postmaster</strong></dt>
<dd><a name="IDX2651"></a>
<p>When this parameter is set, a successful callout check is followed by a similar
check for the local part <em>postmaster</em> at the same domain. If this address is
rejected, the callout fails (but see <code>fullpostmaster</code> above). The result of
the postmaster check is recorded in a cache record; if it is a failure, this is
used to fail subsequent callouts for the domain without a connection being
made, until the cache record expires.
</p>
</dd>
<dt> <strong>postmaster_mailfrom=</strong>&lt;<em>emailaddress</em>&gt;</dt>
<dd><p>The postmaster check uses an empty sender in the MAIL command by default.
You can use this parameter to do a postmaster check using a different address.
For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">require  verify = sender/callout=postmaster_mailfrom=abc@x.y.z
</pre></td></tr></table>

<p>If both <code>postmaster</code> and <code>postmaster_mailfrom</code> are present, the rightmost
one overrides. The <code>postmaster</code> parameter is equivalent to this example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">require  verify = sender/callout=postmaster_mailfrom=
</pre></td></tr></table>

<p><strong>Warning</strong>: The caching arrangements for postmaster checking do not take
account of the sender address. It is assumed that either the empty address or
a fixed non-empty address will be used. All that Exim remembers is that the
postmaster check for the domain succeeded or failed.
</p>
</dd>
<dt> <strong>random</strong></dt>
<dd><a name="IDX2652"></a>
<p>When this parameter is set, before doing the normal callout check, Exim does a
check for a &quot;random&quot; local part at the same domain. The local part is not
really random - it is defined by the expansion of the option
<code>callout_random_local_part</code>, which defaults to
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">$primary_host_name-$tod_epoch-testing
</pre></td></tr></table>

<p>The idea here is to try to determine whether the remote host accepts all local
parts without checking. If it does, there is no point in doing callouts for
specific local parts. If the &quot;random&quot; check succeeds, the result is saved in
a cache record, and used to force the current and subsequent callout checks to
succeed without a connection being made, until the cache record expires.
</p>
</dd>
<dt> <strong>use_postmaster</strong></dt>
<dd><a name="IDX2653"></a>
<p>This parameter applies to recipient callouts only. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny  !verify = recipient/callout=use_postmaster
</pre></td></tr></table>

<a name="IDX2654"></a>
<p>It causes a non-empty postmaster address to be used in the MAIL command when
performing the callout for the recipient, and also for a &quot;random&quot; check if
that is configured. The local part of the address is &lsquo;<samp>postmaster</samp>&rsquo; and the
domain is the contents of <code>$qualify_domain</code>.
</p>
</dd>
<dt> <strong>use_sender</strong></dt>
<dd><p>This option applies to recipient callouts only. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">require  verify = recipient/callout=use_sender
</pre></td></tr></table>

<p>It causes the message's actual sender address to be used in the MAIL
command when performing the callout, instead of an empty address. There is no
need to use this option unless you know that the called hosts make use of the
sender when checking recipients. If used indiscriminately, it reduces the
usefulness of callout caching.
</p></dd>
</dl>

<p>If you use any of the parameters that set a non-empty sender for the MAIL
command (<code>mailfrom</code>, <code>postmaster_mailfrom</code>, <code>use_postmaster</code>, or
<code>use_sender</code>), you should think about possible loops. Recipient checking is
usually done between two hosts that are under the same management, and the host
that receives the callouts is not normally configured to do callouts itself.
Therefore, it is normally safe to use <code>use_postmaster</code> or <code>use_sender</code> in
these circumstances.
</p>
<p>However, if you use a non-empty sender address for a callout to an arbitrary
host, there is the likelihood that the remote host will itself initiate a
callout check back to your host. As it is checking what appears to be a message
sender, it is likely to use an empty address in MAIL, thus avoiding a
callout loop. However, to be on the safe side it would be best to set up your
own ACLs so that they do not do sender verification checks when the recipient
is the address you use for header sender or postmaster callout checking.
</p>
<p>Another issue to think about when using non-empty senders for callouts is
caching. When you set <code>mailfrom</code> or <code>use_sender</code>, the cache record is keyed
by the sender/recipient combination; thus, for any given recipient, many more
actual callouts are performed than when an empty sender or postmaster is used.
</p>
<hr size="6">
<a name="Callout-caching"></a>
<a name="SEC351"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC350" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC352" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.43 Callout caching </h2>

<p>Exim caches the results of callouts in order to reduce the amount of resources
used, unless you specify the <code>no_cache</code> parameter with the <code>callout</code>
option. A hints database called &quot;callout&quot; is used for the cache. Two
different record types are used: one records the result of a callout check for
a specific address, and the other records information that applies to the
entire domain (for example, that it accepts the local part <em>postmaster</em>).
</p>
<p>When an original callout fails, a detailed SMTP error message is given about
the failure. However, for subsequent failures use the cache data, this message
is not available.
</p>
<p>The expiry times for negative and positive address cache records are
independent, and can be set by the global options <code>callout_negative_expire</code>
(default 2h) and <code>callout_positive_expire</code> (default 24h), respectively.
</p>
<p>If a host gives a negative response to an SMTP connection, or rejects any
commands up to and including
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">MAIL FROM:&lt;&gt;
</pre></td></tr></table>

<p>(but not including the MAIL command with a non-empty address),
any callout attempt is bound to fail. Exim remembers such failures in a
domain cache record, which it uses to fail callouts for the domain without
making new connections, until the domain record times out. There are two
separate expiry times for domain cache records:
<code>callout_domain_negative_expire</code> (default 3h) and
<code>callout_domain_positive_expire</code> (default 7d).
</p>
<p>Domain records expire when the negative expiry time is reached if callouts
cannot be made for the domain, or if the postmaster check failed.
Otherwise, they expire when the positive expiry time is reached. This
ensures that, for example, a host that stops accepting &quot;random&quot; local parts
will eventually be noticed.
</p>
<p>The callout caching mechanism is based on the domain of the address that is
being tested. If the domain routes to several hosts, it is assumed that their
behaviour will be the same.
</p>
<hr size="6">
<a name="Sender-address-verification-reporting"></a>
<a name="SEC352"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC351" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC353" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.44 Sender address verification reporting </h2>

<p>See section <a href="#SEC348">Address verification</a> for a general discussion of
verification. When sender verification fails in an ACL, the details of the
failure are given as additional output lines before the 550 response to the
relevant SMTP command (RCPT or DATA). For example, if sender callout is in use,
you might see:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">MAIL FROM:&lt;xyz@abc.example&gt;
250 OK
RCPT TO:&lt;pqr@def.example&gt;
550-Verification failed for &lt;xyz@abc.example&gt;
550-Called:   192.168.34.43
550-Sent:     RCPT TO:&lt;xyz@abc.example&gt;
550-Response: 550 Unknown local part xyz in &lt;xyz@abc.example&gt;
550 Sender verification failed
</pre></td></tr></table>

<p>If more than one RCPT command fails in the same way, the details are given
only for the first of them. However, some administrators do not want to send
out this much information. You can suppress the details by adding
&lsquo;<samp>/no_details</samp>&rsquo; to the ACL statement that requests sender verification. For
example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">verify = sender/no_details
</pre></td></tr></table>

<hr size="6">
<a name="Redirection-while-verifying"></a>
<a name="SEC353"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC352" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC354" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.45 Redirection while verifying </h2>

<p>A dilemma arises when a local address is redirected by aliasing or forwarding
during verification: should the generated addresses themselves be verified,
or should the successful expansion of the original address be enough to verify
it? By default, Exim takes the following pragmatic approach:
</p>
<ul class="toc">
<li>
When an incoming address is redirected to just one child address, verification
continues with the child address, and if that fails to verify, the original
verification also fails.

</li><li>
When an incoming address is redirected to more than one child address,
verification does not continue. A success result is returned.
</li></ul>

<p>This seems the most reasonable behaviour for the common use of aliasing as a
way of redirecting different local parts to the same mailbox. It means, for
example, that a pair of alias entries of the form
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">A.Wol:   aw123
aw123:   :fail: Gone away, no forwarding address
</pre></td></tr></table>

<p>work as expected, with both local parts causing verification failure. When a
redirection generates more than one address, the behaviour is more like a
mailing list, where the existence of the alias itself is sufficient for
verification to succeed.
</p>
<p>It is possible, however, to change the default behaviour so that all successful
redirections count as successful verifications, however many new addresses are
generated. This is specified by the <code>success_on_redirect</code> verification
option. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">require verify = recipient/success_on_redirect/callout=10s
</pre></td></tr></table>

<p>In this example, verification succeeds if a router generates a new address, and
the callout does not occur, because no address was routed to a remote host.
</p>
<p>When verification is being tested via the <code>-bv</code> option, the treatment of
redirections is as just described, unless the <code>-v</code> or any debugging option is
also specified. In that case, full verification is done for every generated
address and a report is output for each of them.
</p>
<hr size="6">
<a name="Client-SMTP-authorization-_005bCSA_005d"></a>
<a name="SEC354"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC353" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC355" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.46 Client SMTP authorization (CSA) </h2>

<p>Client SMTP Authorization is a system that allows a site to advertise
which machines are and are not permitted to send email. This is done by placing
special SRV records in the DNS; these are looked up using the client's HELO
domain. At the time of writing, CSA is still an Internet Draft. Client SMTP
Authorization checks in Exim are performed by the ACL condition:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">verify = csa
</pre></td></tr></table>

<p>This fails if the client is not authorized. If there is a DNS problem, or if no
valid CSA SRV record is found, or if the client is authorized, the condition
succeeds. These three cases can be distinguished using the expansion variable
<code>$csa_status</code>, which can take one of the values &quot;fail&quot;, &quot;defer&quot;,
&quot;unknown&quot;, or &quot;ok&quot;. The condition does not itself defer because that would
be likely to cause problems for legitimate email.
</p>
<p>The error messages produced by the CSA code include slightly more
detail. If <code>$csa_status</code> is &quot;defer&quot;, this may be because of problems
looking up the CSA SRV record, or problems looking up the CSA target
address record. There are four reasons for <code>$csa_status</code> being &quot;fail&quot;:
</p>
<ul class="toc">
<li>
The client's host name is explicitly not authorized.

</li><li>
The client's IP address does not match any of the CSA target IP addresses.

</li><li>
The client's host name is authorized but it has no valid target IP addresses
(for example, the target's addresses are IPv6 and the client is using IPv4).

</li><li>
The client's host name has no CSA SRV record but a parent domain has asserted
that all subdomains must be explicitly authorized.
</li></ul>

<p>The <code>csa</code> verification condition can take an argument which is the domain to
use for the DNS query. The default is:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">verify = csa/$sender_helo_name
</pre></td></tr></table>

<p>This implementation includes an extension to CSA. If the query domain
is an address literal such as [192.0.2.95], or if it is a bare IP
address, Exim searches for CSA SRV records in the reverse DNS as if
the HELO domain was (for example) <em>95.2.0.192.in-addr.arpa</em>. Therefore it is
meaningful to say:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">verify = csa/$sender_host_address
</pre></td></tr></table>

<p>In fact, this is the check that Exim performs if the client does not say HELO.
This extension can be turned off by setting the main configuration option
<code>dns_csa_use_reverse</code> to be false.
</p>
<p>If a CSA SRV record is not found for the domain itself, a search
is performed through its parent domains for a record which might be
making assertions about subdomains. The maximum depth of this search is limited
using the main configuration option <code>dns_csa_search_limit</code>, which is 5 by
default. Exim does not look for CSA SRV records in a top level domain, so the
default settings handle HELO domains as long as seven
(<em>hostname.five.four.three.two.one.com</em>). This encompasses the vast majority
of legitimate HELO domains.
</p>
<p>The <em>dnsdb</em> lookup also has support for CSA. Although <em>dnsdb</em> also supports
direct SRV lookups, this is not sufficient because of the extra parent domain
search behaviour of CSA, and (as with PTR lookups) <em>dnsdb</em> also turns IP
addresses into lookups in the reverse DNS space. The result of a successful
lookup such as:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">${lookup dnsdb {csa=$sender_helo_name}}
</pre></td></tr></table>

<p>has two space-separated fields: an authorization code and a target host name.
The authorization code can be &quot;Y&quot; for yes, &quot;N&quot; for no, &quot;X&quot; for explicit
authorization required but absent, or &quot;?&quot; for unknown.
</p>
<hr size="6">
<a name="Bounce-address-tag-validation"></a>
<a name="SEC355"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC354" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC356" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.47 Bounce address tag validation </h2>

<p>Bounce address tag validation (BATV) is a scheme whereby the envelope senders
of outgoing messages have a cryptographic, timestamped &quot;tag&quot; added to them.
Genuine incoming bounce messages should therefore always be addressed to
recipients that have a valid tag. This scheme is a way of detecting unwanted
bounce messages caused by sender address forgeries (often called &quot;collateral
spam&quot;), because the recipients of such messages do not include valid tags.
</p>
<p>There are two expansion items to help with the implementation of the BATV
&quot;prvs&quot; (private signature) scheme in an Exim configuration. This scheme signs
the original envelope sender address by using a simple key to add a hash of the
address and some time-based randomizing information. The <code>prvs</code> expansion
item creates a signed address, and the <code>prvscheck</code> expansion item checks one.
The syntax of these expansion items is described in section
<a href="spec_11.html#SEC142">Expansion items</a>.
</p>
<p>As an example, suppose the secret per-address keys are stored in an MySQL
database. A query to look up the key for an address could be defined as a macro
like this:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">PRVSCHECK_SQL = ${lookup mysql{SELECT secret FROM batv_prvs \
                WHERE sender='${quote_mysql:$prvscheck_address}'\
                }{$value}}
</pre></td></tr></table>

<p>Suppose also that the senders who make use of BATV are defined by an address
list called <code>batv_senders</code>. Then, in the ACL for RCPT commands, you could
use this:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example"># Bounces: drop unsigned addresses for BATV senders
deny message = This address does not send an unsigned reverse path
     senders = :
     recipients = +batv_senders

# Bounces: In case of prvs-signed address, check signature.
deny message = Invalid reverse path signature.
     senders = :
     condition  = ${prvscheck {$local_part@$domain}\
                  {PRVSCHECK_SQL}{1}}
     !condition = $prvscheck_result
</pre></td></tr></table>

<p>The first statement rejects recipients for bounce messages that are addressed
to plain BATV sender addresses, because it is known that BATV senders do not
send out messages with plain sender addresses. The second statement rejects
recipients that are prvs-signed, but with invalid signatures (either because
the key is wrong, or the signature has timed out).
</p>
<p>A non-prvs-signed address is not rejected by the second statement, because the
<code>prvscheck</code> expansion yields an empty string if its first argument is not a
prvs-signed address, thus causing the <code>condition</code> condition to be false. If
the first argument is a syntactically valid prvs-signed address, the yield is
the third string (in this case &quot;1&quot;), whether or not the cryptographic and
timeout checks succeed. The <code>$prvscheck_result</code> variable contains the result
of the checks (empty for failure, &quot;1&quot; for success).
</p>
<p>There are two more issues you must consider when implementing prvs-signing.
Firstly, you need to ensure that prvs-signed addresses are not blocked by your
ACLs. A prvs-signed address contains a slash character, but the default Exim
configuration contains this statement in the RCPT ACL:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny    message       = Restricted characters in address
        domains       = +local_domains
        local_parts   = ^[.] : ^.*[@%!/|]
</pre></td></tr></table>

<p>This is a conservative rule that blocks local parts that contain slashes. You
should remove the slash in the last line.
</p>
<p>Secondly, you have to ensure that the routers accept prvs-signed addresses and
deliver them correctly. The easiest way to handle this is to use a <code>redirect</code>
router to remove the signature with a configuration along these lines:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">batv_redirect:
  driver = redirect
  data = ${prvscheck {$local_part@$domain}{PRVSCHECK_SQL}}
</pre></td></tr></table>

<p>This works because, if the third argument of <code>prvscheck</code> is empty, the result
of the expansion of a prvs-signed address is the decoded value of the original
address. This router should probably be the first of your routers that handles
local addresses.
</p>
<p>To create BATV-signed addresses in the first place, a transport of this form
can be used:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">external_smtp_batv:
  driver = smtp
  return_path = ${prvs {$return_path} \
                       {${lookup mysql{SELECT \
                       secret FROM batv_prvs WHERE \
                       sender='${quote_mysql:$sender_address}'} \
                       {$value}fail}}}
</pre></td></tr></table>

<p>If no key can be found for the existing return path, no signing takes place.
</p>
<hr size="6">
<a name="Using-an-ACL-to-control-relaying"></a>
<a name="SEC356"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC355" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC357" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.48 Using an ACL to control relaying </h2>

<p>An MTA is said to <em>relay</em> a message if it receives it from some host and
delivers it directly to another host as a result of a remote address contained
within it. Redirecting a local address via an alias or forward file and then
passing the message on to another host is not relaying,
<a name="IDX2655"></a>
but a redirection as a result of the &quot;percent hack&quot; is.
</p>
<p>Two kinds of relaying exist, which are termed &quot;incoming&quot; and &quot;outgoing&quot;.
A host which is acting as a gateway or an MX backup is concerned with incoming
relaying from arbitrary hosts to a specific set of domains. On the other hand,
a host which is acting as a smart host for a number of clients is concerned
with outgoing relaying from those clients to the Internet at large. Often the
same host is fulfilling both functions,
but in principle these two kinds of relaying are entirely independent. What is
not wanted is the transmission of mail from arbitrary remote hosts through your
system to arbitrary domains.
</p>
<p>You can implement relay control by means of suitable statements in the ACL that
runs for each RCPT command. For convenience, it is often easiest to use
Exim's named list facility to define the domains and hosts involved. For
example, suppose you want to do the following:
</p>
<ul class="toc">
<li>
Deliver a number of domains to mailboxes on the local host (or process them
locally in some other way). Let's say these are <em>my.dom1.example</em> and
<em>my.dom2.example</em>.

</li><li>
Relay mail for a number of other domains for which you are the secondary MX.
These might be <em>friend1.example</em> and <em>friend2.example</em>.

</li><li>
Relay mail from the hosts on your local LAN, to whatever domains are involved.
Suppose your LAN is 192.168.45.0/24.
</li></ul>

<p>In the main part of the configuration, you put the following definitions:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">domainlist local_domains = my.dom1.example : my.dom2.example
domainlist relay_domains = friend1.example : friend2.example
hostlist   relay_hosts   = 192.168.45.0/24
</pre></td></tr></table>

<p>Now you can use these definitions in the ACL that is run for every RCPT
command:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">acl_check_rcpt:
  accept domains = +local_domains : +relay_domains
  accept hosts   = +relay_hosts
</pre></td></tr></table>

<p>The first statement accepts any RCPT command that contains an address in
the local or relay domains. For any other domain, control passes to the second
statement, which accepts the command only if it comes from one of the relay
hosts. In practice, you will probably want to make your ACL more sophisticated
than this, for example, by including sender and recipient verification. The
default configuration includes a more comprehensive example, which is described
in chapter <a href="spec_7.html#SEC79">The default configuration file</a>.
</p>
<hr size="6">
<a name="Checking-a-relay-configuration"></a>
<a name="SEC357"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC356" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC308" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 40.49 Checking a relay configuration </h2>

<p>You can check the relay characteristics of your configuration in the same way
that you can test any ACL behaviour for an incoming SMTP connection, by using
the <code>-bh</code> option to run a fake SMTP session with which you interact.
</p>
<p>For specifically testing for unwanted relaying, the host
<em>relay-test.mail-abuse.org</em> provides a useful service. If you telnet to this
host from the host on which Exim is running, using the normal telnet port, you
will see a normal telnet connection message and then quite a long delay. Be
patient. The remote host is making an SMTP connection back to your host, and
trying a number of common probes to test for open relay vulnerability. The
results of the tests will eventually appear on your terminal.
<a name="IDX2656"></a>
</p>
<hr size="6">
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="spec_41.html#SEC358" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<p>
 <font size="-1">
  This document was generated on <i>September, 10 2009</i> using <a href="http://www.nongnu.org/texi2html/"><i>texi2html 1.78</i></a>.
 </font>
 <br>

</p>
</body>
</html>