+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+
+<?sdop
+ foot_right_recto="&chaptertitle; (&chapternumber;)"
+ foot_right_verso="&chaptertitle; (&chapternumber;)"
+ toc_chapter_blanks="yes,yes"
+ table_warn_overflow="overprint"
+?>
+<book>
+<bookinfo>
+<title>Specification of the Exim Mail Transfer Agent</title>
+<titleabbrev>The Exim MTA</titleabbrev>
+<date>
+01 Jun 2020
+</date>
+<author><firstname>Exim</firstname><surname>Maintainers</surname></author>
+<authorinitials>EM</authorinitials>
+<revhistory><revision>
+<revnumber>4.94</revnumber>
+<date>01 Jun 2020</date>
+ <authorinitials>EM</authorinitials>
+</revision></revhistory>
+<copyright><year>
+2020
+ </year><holder>University of Cambridge</holder></copyright>
+</bookinfo>
+<chapter id="CHID1">
+<title>Introduction</title>
+
+<indexterm role="variable">
+ <primary>$1, $2, etc.</primary>
+ <see><emphasis>numerical variables</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>address</primary>
+ <secondary>rewriting</secondary>
+ <see><emphasis>rewriting</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>Bounce Address Tag Validation</primary>
+ <see><emphasis>BATV</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>Client SMTP Authorization</primary>
+ <see><emphasis>CSA</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>CR character</primary>
+ <see><emphasis>carriage return</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>CRL</primary>
+ <see><emphasis>certificate revocation list</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>delivery</primary>
+ <secondary>failure report</secondary>
+ <see><emphasis>bounce message</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>dialup</primary>
+ <see><emphasis>intermittently connected hosts</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>exiscan</primary>
+ <see><emphasis>content scanning</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>failover</primary>
+ <see><emphasis>fallback</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>fallover</primary>
+ <see><emphasis>fallback</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>filter</primary>
+ <secondary>Sieve</secondary>
+ <see><emphasis>Sieve filter</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>ident</primary>
+ <see><emphasis>RFC 1413</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>LF character</primary>
+ <see><emphasis>linefeed</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>maximum</primary>
+ <seealso><emphasis>limit</emphasis></seealso>
+</indexterm>
+<indexterm role="concept">
+ <primary>monitor</primary>
+ <see><emphasis>Exim monitor</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>no_<emphasis>xxx</emphasis></primary>
+ <see>entry for xxx</see>
+</indexterm>
+<indexterm role="concept">
+ <primary>NUL</primary>
+ <see><emphasis>binary zero</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>passwd file</primary>
+ <see><emphasis>/etc/passwd</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>process id</primary>
+ <see><emphasis>pid</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>RBL</primary>
+ <see><emphasis>DNS list</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>redirection</primary>
+ <see><emphasis>address redirection</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>return path</primary>
+ <seealso><emphasis>envelope sender</emphasis></seealso>
+</indexterm>
+<indexterm role="concept">
+ <primary>scanning</primary>
+ <see><emphasis>content scanning</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>SSL</primary>
+ <see><emphasis>TLS</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>string</primary>
+ <secondary>expansion</secondary>
+ <see><emphasis>expansion</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>top bit</primary>
+ <see><emphasis>8-bit characters</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>variables</primary>
+ <see><emphasis>expansion, variables</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>zero, binary</primary>
+ <see><emphasis>binary zero</emphasis></see>
+</indexterm>
+
+<para>
+Exim is a mail transfer agent (MTA) for hosts that are running Unix or
+Unix-like operating systems. It was designed on the assumption that it would be
+run on hosts that are permanently connected to the Internet. However, it can be
+used on intermittently connected hosts with suitable configuration adjustments.
+</para>
+<para>
+Configuration files currently exist for the following operating systems: AIX,
+BSD/OS (aka BSDI), Darwin (Mac OS X), DGUX, Dragonfly, FreeBSD, GNU/Hurd,
+GNU/Linux, HI-OSF (Hitachi), HI-UX, HP-UX, IRIX, MIPS RISCOS, NetBSD, OpenBSD,
+OpenUNIX, QNX, SCO, SCO SVR4.2 (aka UNIX-SV), Solaris (aka SunOS5), SunOS4,
+Tru64-Unix (formerly Digital UNIX, formerly DEC-OSF1), Ultrix, and UnixWare.
+Some of these operating systems are no longer current and cannot easily be
+tested, so the configuration files may no longer work in practice.
+</para>
+<para>
+There are also configuration files for compiling Exim in the Cygwin environment
+that can be installed on systems running Windows. However, this document does
+not contain any information about running Exim in the Cygwin environment.
+</para>
+<para>
+The terms and conditions for the use and distribution of Exim are contained in
+the file <filename>NOTICE</filename>. Exim is distributed under the terms of the GNU General
+Public Licence, a copy of which may be found in the file <filename>LICENCE</filename>.
+</para>
+<para>
+The use, supply, or promotion of Exim for the purpose of sending bulk,
+unsolicited electronic mail is incompatible with the basic aims of Exim,
+which revolve around the free provision of a service that enhances the quality
+of personal communications. The author of Exim regards indiscriminate
+mass-mailing as an antisocial, irresponsible abuse of the Internet.
+</para>
+<para>
+Exim owes a great deal to Smail 3 and its author, Ron Karr. Without the
+experience of running and working on the Smail 3 code, I could never have
+contemplated starting to write a new MTA. Many of the ideas and user interfaces
+were originally taken from Smail 3, though the actual code of Exim is entirely
+new, and has developed far beyond the initial concept.
+</para>
+<para>
+Many people, both in Cambridge and around the world, have contributed to the
+development and the testing of Exim, and to porting it to various operating
+systems. I am grateful to them all. The distribution now contains a file called
+<filename>ACKNOWLEDGMENTS</filename>, in which I have started recording the names of
+contributors.
+</para>
+<section id="SECID1">
+<title>Exim documentation</title>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>documentation</primary>
+</indexterm>
+This edition of the Exim specification applies to version 4.94 of Exim.
+Substantive changes from the 4.93 edition are marked in some
+renditions of this document; this paragraph is so marked if the rendition is
+capable of showing a change indicator.
+</para>
+<para>
+This document is very much a reference manual; it is not a tutorial. The reader
+is expected to have some familiarity with the SMTP mail transfer protocol and
+with general Unix system administration. Although there are some discussions
+and examples in places, the information is mostly organized in a way that makes
+it easy to look up, rather than in a natural order for sequential reading.
+Furthermore, this manual aims to cover every aspect of Exim in detail, including
+a number of rarely-used, special-purpose features that are unlikely to be of
+very wide interest.
+</para>
+<para>
+<indexterm role="concept">
+<primary>books about Exim</primary>
+</indexterm>
+An <quote>easier</quote> discussion of Exim which provides more in-depth explanatory,
+introductory, and tutorial material can be found in a book entitled <emphasis>The Exim
+SMTP Mail Server</emphasis> (second edition, 2007), published by UIT Cambridge
+(<emphasis role="bold"><ulink url="https://www.uit.co.uk/exim-book/">https://www.uit.co.uk/exim-book/</ulink></emphasis>).
+</para>
+<para>
+The book also contains a chapter that gives a general introduction to SMTP and
+Internet mail. Inevitably, however, the book is unlikely to be fully up-to-date
+with the latest release of Exim. (Note that the earlier book about Exim,
+published by O’Reilly, covers Exim 3, and many things have changed in Exim 4.)
+</para>
+<para>
+<indexterm role="concept">
+<primary>Debian</primary>
+<secondary>information sources</secondary>
+</indexterm>
+If you are using a Debian distribution of Exim, you will find information about
+Debian-specific features in the file
+<filename>/usr/share/doc/exim4-base/README.Debian</filename>.
+The command <command>man update-exim.conf</command> is another source of Debian-specific
+information.
+</para>
+<para>
+<indexterm role="concept">
+<primary><filename>doc/NewStuff</filename></primary>
+</indexterm>
+<indexterm role="concept">
+<primary><filename>doc/ChangeLog</filename></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>change log</primary>
+</indexterm>
+As Exim develops, there may be features in newer versions that have not
+yet made it into this document, which is updated only when the most significant
+digit of the fractional part of the version number changes. Specifications of
+new features that are not yet in this manual are placed in the file
+<filename>doc/NewStuff</filename> in the Exim distribution.
+</para>
+<para>
+Some features may be classified as <quote>experimental</quote>. These may change
+incompatibly while they are developing, or even be withdrawn. For this reason,
+they are not documented in this manual. Information about experimental features
+can be found in the file <filename>doc/experimental.txt</filename>.
+</para>
+<para>
+All changes to Exim (whether new features, bug fixes, or other kinds of
+change) are noted briefly in the file called <filename>doc/ChangeLog</filename>.
+</para>
+<para>
+<indexterm role="concept">
+<primary><filename>doc/spec.txt</filename></primary>
+</indexterm>
+This specification itself is available as an ASCII file in <filename>doc/spec.txt</filename> so
+that it can easily be searched with a text editor. Other files in the <filename>doc</filename>
+directory are:
+</para>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="100pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><filename>OptionLists.txt</filename></entry>
+<entry>list of all options in alphabetical order</entry>
+</row>
+<row>
+<entry><filename>dbm.discuss.txt</filename></entry>
+<entry>discussion about DBM libraries</entry>
+</row>
+<row>
+<entry><filename>exim.8</filename></entry>
+<entry>a man page of Exim’s command line options</entry>
+</row>
+<row>
+<entry><filename>experimental.txt</filename></entry>
+<entry>documentation of experimental features</entry>
+</row>
+<row>
+<entry><filename>filter.txt</filename></entry>
+<entry>specification of the filter language</entry>
+</row>
+<row>
+<entry><filename>Exim3.upgrade</filename></entry>
+<entry>upgrade notes from release 2 to release 3</entry>
+</row>
+<row>
+<entry><filename>Exim4.upgrade</filename></entry>
+<entry>upgrade notes from release 3 to release 4</entry>
+</row>
+<row>
+<entry><filename>openssl.txt</filename></entry>
+<entry>installing a current OpenSSL release</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+The main specification and the specification of the filtering language are also
+available in other formats (HTML, PostScript, PDF, and Texinfo). Section
+<xref linkend="SECTavail"/> below tells you how to get hold of these.
+</para>
+</section>
+<section id="SECID2">
+<title>FTP site and websites</title>
+<para>
+<indexterm role="concept">
+<primary>website</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>FTP site</primary>
+</indexterm>
+The primary site for Exim source distributions is the <option>exim.org</option> FTP site,
+available over HTTPS, HTTP and FTP. These services, and the <option>exim.org</option>
+website, are hosted at the University of Cambridge.
+</para>
+<para>
+<indexterm role="concept">
+<primary>wiki</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>FAQ</primary>
+</indexterm>
+As well as Exim distribution tar files, the Exim website contains a number of
+differently formatted versions of the documentation. A recent addition to the
+online information is the Exim wiki (<emphasis role="bold"><ulink url="https://wiki.exim.org">https://wiki.exim.org</ulink></emphasis>),
+which contains what used to be a separate FAQ, as well as various other
+examples, tips, and know-how that have been contributed by Exim users.
+The wiki site should always redirect to the correct place, which is currently
+provided by GitHub, and is open to editing by anyone with a GitHub account.
+</para>
+<para>
+<indexterm role="concept">
+<primary>Bugzilla</primary>
+</indexterm>
+An Exim Bugzilla exists at <emphasis role="bold"><ulink url="https://bugs.exim.org">https://bugs.exim.org</ulink></emphasis>. You can use
+this to report bugs, and also to add items to the wish list. Please search
+first to check that you are not duplicating a previous entry.
+Please do not ask for configuration help in the bug-tracker.
+</para>
+</section>
+<section id="SECID3">
+<title>Mailing lists</title>
+<para>
+<indexterm role="concept">
+<primary>mailing lists</primary>
+<secondary>for Exim users</secondary>
+</indexterm>
+The following Exim mailing lists exist:
+</para>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="140pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><emphasis>exim-announce@exim.org</emphasis></entry>
+<entry>Moderated, low volume announcements list</entry>
+</row>
+<row>
+<entry><emphasis>exim-users@exim.org</emphasis></entry>
+<entry>General discussion list</entry>
+</row>
+<row>
+<entry><emphasis>exim-dev@exim.org</emphasis></entry>
+<entry>Discussion of bugs, enhancements, etc.</entry>
+</row>
+<row>
+<entry><emphasis>exim-cvs@exim.org</emphasis></entry>
+<entry>Automated commit messages from the VCS</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+You can subscribe to these lists, change your existing subscriptions, and view
+or search the archives via the mailing lists link on the Exim home page.
+<indexterm role="concept">
+<primary>Debian</primary>
+<secondary>mailing list for</secondary>
+</indexterm>
+If you are using a Debian distribution of Exim, you may wish to subscribe to
+the Debian-specific mailing list <emphasis>pkg-exim4-users@lists.alioth.debian.org</emphasis>
+via this web page:
+</para>
+<literallayout>
+<emphasis role="bold"><ulink url="https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/pkg-exim4-users">https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/pkg-exim4-users</ulink></emphasis>
+</literallayout>
+<para>
+Please ask Debian-specific questions on that list and not on the general Exim
+lists.
+</para>
+</section>
+<section id="SECID5">
+<title>Bug reports</title>
+<para>
+<indexterm role="concept">
+<primary>bug reports</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>reporting bugs</primary>
+</indexterm>
+Reports of obvious bugs can be emailed to <emphasis>bugs@exim.org</emphasis> or reported
+via the Bugzilla (<emphasis role="bold"><ulink url="https://bugs.exim.org">https://bugs.exim.org</ulink></emphasis>). However, if you are unsure
+whether some behaviour is a bug or not, the best thing to do is to post a
+message to the <emphasis>exim-dev</emphasis> mailing list and have it discussed.
+</para>
+</section>
+<section id="SECTavail">
+<title>Where to find the Exim distribution</title>
+<para>
+<indexterm role="concept">
+<primary>FTP site</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>HTTPS download site</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>distribution</primary>
+<secondary>FTP site</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>distribution</primary>
+<secondary>https site</secondary>
+</indexterm>
+The master distribution site for the Exim distribution is
+</para>
+<literallayout>
+<emphasis role="bold"><ulink url="https://downloads.exim.org/">https://downloads.exim.org/</ulink></emphasis>
+</literallayout>
+<para>
+The service is available over HTTPS, HTTP and FTP.
+We encourage people to migrate to HTTPS.
+</para>
+<para>
+The content served at <emphasis role="bold"><ulink url="https://downloads.exim.org/">https://downloads.exim.org/</ulink></emphasis> is identical to the
+content served at <emphasis role="bold"><ulink url="https://ftp.exim.org/pub/exim">https://ftp.exim.org/pub/exim</ulink></emphasis> and
+<emphasis role="bold"><ulink url="ftp://ftp.exim.org/pub/exim">ftp://ftp.exim.org/pub/exim</ulink></emphasis>.
+</para>
+<para>
+If accessing via a hostname containing <emphasis>ftp</emphasis>, then the file references that
+follow are relative to the <filename>exim</filename> directories at these sites.
+If accessing via the hostname <emphasis>downloads</emphasis> then the subdirectories described
+here are top-level directories.
+</para>
+<para>
+There are now quite a number of independent mirror sites around
+the world. Those that I know about are listed in the file called <filename>Mirrors</filename>.
+</para>
+<para>
+Within the top exim directory there are subdirectories called <filename>exim3</filename> (for
+previous Exim 3 distributions), <filename>exim4</filename> (for the latest Exim 4
+distributions), and <filename>Testing</filename> for testing versions. In the <filename>exim4</filename>
+subdirectory, the current release can always be found in files called
+</para>
+<literallayout>
+<filename>exim-n.nn.tar.xz</filename>
+<filename>exim-n.nn.tar.gz</filename>
+<filename>exim-n.nn.tar.bz2</filename>
+</literallayout>
+<para>
+where <emphasis>n.nn</emphasis> is the highest such version number in the directory. The three
+files contain identical data; the only difference is the type of compression.
+The <filename>.xz</filename> file is usually the smallest, while the <filename>.gz</filename> file is the
+most portable to old systems.
+</para>
+<para>
+<indexterm role="concept">
+<primary>distribution</primary>
+<secondary>signing details</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>distribution</primary>
+<secondary>public key</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>public key for signed distribution</primary>
+</indexterm>
+The distributions will be PGP signed by an individual key of the Release
+Coordinator. This key will have a uid containing an email address in the
+<emphasis>exim.org</emphasis> domain and will have signatures from other people, including
+other Exim maintainers. We expect that the key will be in the "strong set" of
+PGP keys. There should be a trust path to that key from the Exim Maintainer’s
+PGP keys, a version of which can be found in the release directory in the file
+<filename>Exim-Maintainers-Keyring.asc</filename>. All keys used will be available in public keyserver pools,
+such as <emphasis>pool.sks-keyservers.net</emphasis>.
+</para>
+<para>
+At the time of the last update, releases were being made by Jeremy Harris and signed
+with key <emphasis>0xBCE58C8CE41F32DF</emphasis>. Other recent keys used for signing are those
+of Heiko Schlittermann, <emphasis>0x26101B62F69376CE</emphasis>,
+and of Phil Pennock, <emphasis>0x4D1E900E14C1CC04</emphasis>.
+</para>
+<para>
+The signatures for the tar bundles are in:
+</para>
+<literallayout>
+<filename>exim-n.nn.tar.xz.asc</filename>
+<filename>exim-n.nn.tar.gz.asc</filename>
+<filename>exim-n.nn.tar.bz2.asc</filename>
+</literallayout>
+<para>
+For each released version, the log of changes is made available in a
+separate file in the directory <filename>ChangeLogs</filename> so that it is possible to
+find out what has changed without having to download the entire distribution.
+</para>
+<para>
+<indexterm role="concept">
+<primary>documentation</primary>
+<secondary>available formats</secondary>
+</indexterm>
+The main distribution contains ASCII versions of this specification and other
+documentation; other formats of the documents are available in separate files
+inside the <filename>exim4</filename> directory of the FTP site:
+</para>
+<literallayout>
+<filename>exim-html-n.nn.tar.gz</filename>
+<filename>exim-pdf-n.nn.tar.gz</filename>
+<filename>exim-postscript-n.nn.tar.gz</filename>
+<filename>exim-texinfo-n.nn.tar.gz</filename>
+</literallayout>
+<para>
+These tar files contain only the <filename>doc</filename> directory, not the complete
+distribution, and are also available in <filename>.bz2</filename> and <filename>.xz</filename> forms.
+</para>
+</section>
+<section id="SECID6">
+<title>Limitations</title>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>limitations of Exim</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>bang paths</primary>
+<secondary>not handled by Exim</secondary>
+</indexterm>
+Exim is designed for use as an Internet MTA, and therefore handles addresses in
+RFC 2822 domain format only. It cannot handle UUCP <quote>bang paths</quote>, though
+simple two-component bang paths can be converted by a straightforward rewriting
+configuration. This restriction does not prevent Exim from being interfaced to
+UUCP as a transport mechanism, provided that domain addresses are used.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>domainless addresses</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>address</primary>
+<secondary>without domain</secondary>
+</indexterm>
+Exim insists that every address it handles has a domain attached. For incoming
+local messages, domainless addresses are automatically qualified with a
+configured domain value. Configuration options specify from which remote
+systems unqualified addresses are acceptable. These are then qualified on
+arrival.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>external</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>external transports</primary>
+</indexterm>
+The only external transport mechanisms that are currently implemented are SMTP
+and LMTP over a TCP/IP network (including support for IPv6). However, a pipe
+transport is available, and there are facilities for writing messages to files
+and pipes, optionally in <emphasis>batched SMTP</emphasis> format; these facilities can be used
+to send messages to other transport mechanisms such as UUCP, provided they can
+handle domain-style addresses. Batched SMTP input is also catered for.
+</para>
+</listitem>
+<listitem>
+<para>
+Exim is not designed for storing mail for dial-in hosts. When the volumes of
+such mail are large, it is better to get the messages <quote>delivered</quote> into files
+(that is, off Exim’s queue) and subsequently passed on to the dial-in hosts by
+other means.
+</para>
+</listitem>
+<listitem>
+<para>
+Although Exim does have basic facilities for scanning incoming messages, these
+are not comprehensive enough to do full virus or spam scanning. Such operations
+are best carried out using additional specialized software packages. If you
+compile Exim with the content-scanning extension, straightforward interfaces to
+a number of common scanners are provided.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID7">
+<title>Runtime configuration</title>
+<para>
+Exim’s runtime configuration is held in a single text file that is divided
+into a number of sections. The entries in this file consist of keywords and
+values, in the style of Smail 3 configuration files. A default configuration
+file which is suitable for simple online installations is provided in the
+distribution, and is described in chapter <xref linkend="CHAPdefconfil"/> below.
+</para>
+</section>
+<section id="SECID8">
+<title>Calling interface</title>
+<para>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary>command line interface</secondary>
+</indexterm>
+Like many MTAs, Exim has adopted the Sendmail command line interface so that it
+can be a straight replacement for <filename>/usr/lib/sendmail</filename> or
+<filename>/usr/sbin/sendmail</filename> when sending mail, but you do not need to know anything
+about Sendmail in order to run Exim. For actions other than sending messages,
+Sendmail-compatible options also exist, but those that produce output (for
+example, <option>-bp</option>, which lists the messages in the queue) do so in Exim’s own
+format. There are also some additional options that are compatible with Smail
+3, and some further options that are new to Exim. Chapter <xref linkend="CHAPcommandline"/>
+documents all Exim’s command line options. This information is automatically
+made into the man page that forms part of the Exim distribution.
+</para>
+<para>
+Control of messages in the queue can be done via certain privileged command
+line options. There is also an optional monitor program called <emphasis>eximon</emphasis>,
+which displays current information in an X window, and which contains a menu
+interface to Exim’s command line administration options.
+</para>
+</section>
+<section id="SECID9">
+<title>Terminology</title>
+<para>
+<indexterm role="concept">
+<primary>terminology definitions</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>body of message</primary>
+<secondary>definition of</secondary>
+</indexterm>
+The <emphasis>body</emphasis> of a message is the actual data that the sender wants to transmit.
+It is the last part of a message and is separated from the <emphasis>header</emphasis> (see
+below) by a blank line.
+</para>
+<para>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>definition of</secondary>
+</indexterm>
+When a message cannot be delivered, it is normally returned to the sender in a
+delivery failure message or a <quote>non-delivery report</quote> (NDR). The term
+<emphasis>bounce</emphasis> is commonly used for this action, and the error reports are often
+called <emphasis>bounce messages</emphasis>. This is a convenient shorthand for <quote>delivery
+failure error report</quote>. Such messages have an empty sender address in the
+message’s <emphasis>envelope</emphasis> (see below) to ensure that they cannot themselves give
+rise to further bounce messages.
+</para>
+<para>
+The term <emphasis>default</emphasis> appears frequently in this manual. It is used to qualify a
+value which is used in the absence of any setting in the configuration. It may
+also qualify an action which is taken unless a configuration setting specifies
+otherwise.
+</para>
+<para>
+The term <emphasis>defer</emphasis> is used when the delivery of a message to a specific
+destination cannot immediately take place for some reason (a remote host may be
+down, or a user’s local mailbox may be full). Such deliveries are <emphasis>deferred</emphasis>
+until a later time.
+</para>
+<para>
+The word <emphasis>domain</emphasis> is sometimes used to mean all but the first component of a
+host’s name. It is <emphasis>not</emphasis> used in that sense here, where it normally refers to
+the part of an email address following the @ sign.
+</para>
+<para>
+<indexterm role="concept">
+<primary>envelope, definition of</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>definition of</secondary>
+</indexterm>
+A message in transit has an associated <emphasis>envelope</emphasis>, as well as a header and a
+body. The envelope contains a sender address (to which bounce messages should
+be delivered), and any number of recipient addresses. References to the
+sender or the recipients of a message usually mean the addresses in the
+envelope. An MTA uses these addresses for delivery, and for returning bounce
+messages, not the addresses that appear in the header lines.
+</para>
+<para>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>header, definition of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header section</primary>
+<secondary>definition of</secondary>
+</indexterm>
+The <emphasis>header</emphasis> of a message is the first part of a message’s text, consisting
+of a number of lines, each of which has a name such as <emphasis>From:</emphasis>, <emphasis>To:</emphasis>,
+<emphasis>Subject:</emphasis>, etc. Long header lines can be split over several text lines by
+indenting the continuations. The header is separated from the body by a blank
+line.
+</para>
+<para>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>definition of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain</primary>
+<secondary>definition of</secondary>
+</indexterm>
+The term <emphasis>local part</emphasis>, which is taken from RFC 2822, is used to refer to the
+part of an email address that precedes the @ sign. The part that follows the
+@ sign is called the <emphasis>domain</emphasis> or <emphasis>mail domain</emphasis>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>local delivery</primary>
+<secondary>definition of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>remote delivery, definition of</primary>
+</indexterm>
+The terms <emphasis>local delivery</emphasis> and <emphasis>remote delivery</emphasis> are used to distinguish
+delivery to a file or a pipe on the local host from delivery by SMTP over
+TCP/IP to another host. As far as Exim is concerned, all hosts other than the
+host it is running on are <emphasis>remote</emphasis>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>return path</primary>
+<secondary>definition of</secondary>
+</indexterm>
+<emphasis>Return path</emphasis> is another name that is used for the sender address in a
+message’s envelope.
+</para>
+<para>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>definition of</secondary>
+</indexterm>
+The term <emphasis>queue</emphasis> is used to refer to the set of messages awaiting delivery
+because this term is in widespread use in the context of MTAs. However, in
+Exim’s case, the reality is more like a pool than a queue, because there is
+normally no ordering of waiting messages.
+</para>
+<para>
+<indexterm role="concept">
+<primary>queue runner</primary>
+<secondary>definition of</secondary>
+</indexterm>
+The term <emphasis>queue runner</emphasis> is used to describe a process that scans the queue
+and attempts to deliver those messages whose retry times have come. This term
+is used by other MTAs and also relates to the command <option>runq</option>, but in Exim
+the waiting messages are normally processed in an unpredictable order.
+</para>
+<para>
+<indexterm role="concept">
+<primary>spool directory</primary>
+<secondary>definition of</secondary>
+</indexterm>
+The term <emphasis>spool directory</emphasis> is used for a directory in which Exim keeps the
+messages in its queue – that is, those that it is in the process of
+delivering. This should not be confused with the directory in which local
+mailboxes are stored, which is called a <quote>spool directory</quote> by some people. In
+the Exim documentation, <quote>spool</quote> is always used in the first sense.
+</para>
+</section>
+</chapter>
+
+<chapter id="CHID2">
+<title>Incorporated code</title>
+<para>
+<indexterm role="concept">
+<primary>incorporated code</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>regular expressions</primary>
+<secondary>library</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>PCRE</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>OpenDMARC</primary>
+</indexterm>
+A number of pieces of external code are included in the Exim distribution.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Regular expressions are supported in the main Exim program and in the
+Exim monitor using the freely-distributable PCRE library, copyright
+© University of Cambridge. The source to PCRE is no longer shipped with
+Exim, so you will need to use the version of PCRE shipped with your system,
+or obtain and install the full version of the library from
+<emphasis role="bold"><ulink url="ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre">ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre</ulink></emphasis>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>cdb</primary>
+<secondary>acknowledgment</secondary>
+</indexterm>
+Support for the cdb (Constant DataBase) lookup method is provided by code
+contributed by Nigel Metheringham of (at the time he contributed it) Planet
+Online Ltd. The implementation is completely contained within the code of Exim.
+It does not link against an external cdb library. The code contains the
+following statements:
+</para>
+<blockquote>
+<para>
+Copyright © 1998 Nigel Metheringham, Planet Online Ltd
+</para>
+<para>
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+This code implements Dan Bernstein’s Constant DataBase (cdb) spec. Information,
+the spec and sample code for cdb can be obtained from
+<emphasis role="bold"><ulink url="https://cr.yp.to/cdb.html">https://cr.yp.to/cdb.html</ulink></emphasis>. This implementation borrows
+some code from Dan Bernstein’s implementation (which has no license
+restrictions applied to it).
+</para>
+</blockquote>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>SPA authentication</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Samba project</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Microsoft Secure Password Authentication</primary>
+</indexterm>
+Client support for Microsoft’s <emphasis>Secure Password Authentication</emphasis> is provided
+by code contributed by Marc Prud’hommeaux. Server support was contributed by
+Tom Kistner. This includes code taken from the Samba project, which is released
+under the Gnu GPL.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>Cyrus</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>pwcheck</emphasis> daemon</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>pwauthd</emphasis> daemon</primary>
+</indexterm>
+Support for calling the Cyrus <emphasis>pwcheck</emphasis> and <emphasis>saslauthd</emphasis> daemons is provided
+by code taken from the Cyrus-SASL library and adapted by Alexander S.
+Sabourenkov. The permission notice appears below, in accordance with the
+conditions expressed therein.
+</para>
+<blockquote>
+<para>
+Copyright © 2001 Carnegie Mellon University. All rights reserved.
+</para>
+<para>
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+</para>
+</listitem>
+<listitem>
+<para>
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.
+</para>
+</listitem>
+<listitem>
+<para>
+The name <quote>Carnegie Mellon University</quote> must not be used to
+endorse or promote products derived from this software without
+prior written permission. For permission or any other legal
+details, please contact
+</para>
+<literallayout>
+ Office of Technology Transfer
+ Carnegie Mellon University
+ 5000 Forbes Avenue
+ Pittsburgh, PA 15213-3890
+ (412) 268-4387, fax: (412) 268-7395
+ tech-transfer@andrew.cmu.edu
+</literallayout>
+</listitem>
+<listitem>
+<para>
+Redistributions of any form whatsoever must retain the following
+acknowledgment:
+</para>
+<para>
+<quote>This product includes software developed by Computing Services
+at Carnegie Mellon University (<emphasis role="bold"><ulink url="https://www.cmu.edu/computing/">https://www.cmu.edu/computing/</ulink></emphasis>.</quote>
+</para>
+<para>
+CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+</para>
+</listitem>
+</orderedlist>
+</blockquote>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>Exim monitor</primary>
+<secondary>acknowledgment</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>X-windows</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Athena</primary>
+</indexterm>
+The Exim Monitor program, which is an X-Window application, includes
+modified versions of the Athena StripChart and TextPop widgets.
+This code is copyright by DEC and MIT, and their permission notice appears
+below, in accordance with the conditions expressed therein.
+</para>
+<blockquote>
+<para>
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+</para>
+<para>
+All Rights Reserved
+</para>
+<para>
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+</para>
+<para>
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+</para>
+</blockquote>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>opendmarc</primary>
+<secondary>acknowledgment</secondary>
+</indexterm>
+The DMARC implementation uses the OpenDMARC library which is Copyrighted by
+The Trusted Domain Project. Portions of Exim source which use OpenDMARC
+derived code are indicated in the respective source files. The full OpenDMARC
+license is provided in the LICENSE.opendmarc file contained in the distributed
+source code.
+</para>
+</listitem>
+<listitem>
+<para>
+Many people have contributed code fragments, some large, some small, that were
+not covered by any specific license requirements. It is assumed that the
+contributors are happy to see their code incorporated into Exim under the GPL.
+</para>
+</listitem>
+</itemizedlist>
+</chapter>
+
+<chapter id="CHID11">
+<title>How Exim receives and delivers mail</title>
+<titleabbrev>Receiving and delivering mail</titleabbrev>
+<section id="SECID10">
+<title>Overall philosophy</title>
+<para>
+<indexterm role="concept">
+<primary>design philosophy</primary>
+</indexterm>
+Exim is designed to work efficiently on systems that are permanently connected
+to the Internet and are handling a general mix of mail. In such circumstances,
+most messages can be delivered immediately. Consequently, Exim does not
+maintain independent queues of messages for specific domains or hosts, though
+it does try to send several messages in a single SMTP connection after a host
+has been down, and it also maintains per-host retry information.
+</para>
+</section>
+<section id="SECID11">
+<title>Policy control</title>
+<para>
+<indexterm role="concept">
+<primary>policy control</primary>
+<secondary>overview</secondary>
+</indexterm>
+Policy controls are now an important feature of MTAs that are connected to the
+Internet. Perhaps their most important job is to stop MTAs from being abused as
+<quote>open relays</quote> by misguided individuals who send out vast amounts of
+unsolicited junk and want to disguise its source. Exim provides flexible
+facilities for specifying policy controls on incoming mail:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>introduction</secondary>
+</indexterm>
+Exim 4 (unlike previous versions of Exim) implements policy controls on
+incoming mail by means of <emphasis>Access Control Lists</emphasis> (ACLs). Each list is a
+series of statements that may either grant or deny access. ACLs can be used at
+several places in the SMTP dialogue while receiving a message from a remote
+host. However, the most common places are after each RCPT command, and at the
+very end of the message. The sysadmin can specify conditions for accepting or
+rejecting individual recipients or the entire message, respectively, at these
+two points (see chapter <xref linkend="CHAPACL"/>). Denial of access results in an SMTP
+error code.
+</para>
+</listitem>
+<listitem>
+<para>
+An ACL is also available for locally generated, non-SMTP messages. In this
+case, the only available actions are to accept or deny the entire message.
+</para>
+</listitem>
+<listitem>
+<para>
+When Exim is compiled with the content-scanning extension, facilities are
+provided in the ACL mechanism for passing the message to external virus and/or
+spam scanning software. The result of such a scan is passed back to the ACL,
+which can then use it to decide what to do with the message.
+</para>
+</listitem>
+<listitem>
+<para>
+When a message has been received, either from a remote host or from the local
+host, but before the final acknowledgment has been sent, a locally supplied C
+function called <function>local_scan()</function> can be run to inspect the message and decide
+whether to accept it or not (see chapter <xref linkend="CHAPlocalscan"/>). If the message
+is accepted, the list of recipients can be modified by the function.
+</para>
+</listitem>
+<listitem>
+<para>
+Using the <function>local_scan()</function> mechanism is another way of calling external scanner
+software. The <option>SA-Exim</option> add-on package works this way. It does not require
+Exim to be compiled with the content-scanning extension.
+</para>
+</listitem>
+<listitem>
+<para>
+After a message has been accepted, a further checking mechanism is available in
+the form of the <emphasis>system filter</emphasis> (see chapter <xref linkend="CHAPsystemfilter"/>). This
+runs at the start of every delivery process.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID12">
+<title>User filters</title>
+<para>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>introduction</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+</indexterm>
+In a conventional Exim configuration, users are able to run private filters by
+setting up appropriate <filename>.forward</filename> files in their home directories. See
+chapter <xref linkend="CHAPredirect"/> (about the <command>redirect</command> router) for the
+configuration needed to support this, and the separate document entitled
+<emphasis>Exim’s interfaces to mail filtering</emphasis> for user details. Two different kinds
+of filtering are available:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Sieve filters are written in the standard filtering language that is defined
+by RFC 3028.
+</para>
+</listitem>
+<listitem>
+<para>
+Exim filters are written in a syntax that is unique to Exim, but which is more
+powerful than Sieve, which it pre-dates.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+User filters are run as part of the routing process, described below.
+</para>
+</section>
+<section id="SECTmessiden">
+<title>Message identification</title>
+<para>
+<indexterm role="concept">
+<primary>message ids</primary>
+<secondary>details of format</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>format</primary>
+<secondary>of message id</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>id of message</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>base62</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>base36</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Darwin</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Cygwin</primary>
+</indexterm>
+Every message handled by Exim is given a <emphasis>message id</emphasis> which is sixteen
+characters long. It is divided into three parts, separated by hyphens, for
+example <literal>16VDhn-0001bo-D3</literal>. Each part is a sequence of letters and digits,
+normally encoding numbers in base 62. However, in the Darwin operating
+system (Mac OS X) and when Exim is compiled to run under Cygwin, base 36
+(avoiding the use of lower case letters) is used instead, because the message
+id is used to construct filenames, and the names of files in those systems are
+not always case-sensitive.
+</para>
+<para>
+<indexterm role="concept">
+<primary>pid (process id)</primary>
+<secondary>re-use of</secondary>
+</indexterm>
+The detail of the contents of the message id have changed as Exim has evolved.
+Earlier versions relied on the operating system not re-using a process id (pid)
+within one second. On modern operating systems, this assumption can no longer
+be made, so the algorithm had to be changed. To retain backward compatibility,
+the format of the message id was retained, which is why the following rules are
+somewhat eccentric:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The first six characters of the message id are the time at which the message
+started to be received, to a granularity of one second. That is, this field
+contains the number of seconds since the start of the epoch (the normal Unix
+way of representing the date and time of day).
+</para>
+</listitem>
+<listitem>
+<para>
+After the first hyphen, the next six characters are the id of the process that
+received the message.
+</para>
+</listitem>
+<listitem>
+<para>
+There are two different possibilities for the final two characters:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>localhost_number</option></primary>
+</indexterm>
+If <option>localhost_number</option> is not set, this value is the fractional part of the
+time of reception, normally in units of 1/2000 of a second, but for systems
+that must use base 36 instead of base 62 (because of case-insensitive file
+systems), the units are 1/1000 of a second.
+</para>
+</listitem>
+<listitem>
+<para>
+If <option>localhost_number</option> is set, it is multiplied by 200 (100) and added to
+the fractional part of the time, which in this case is in units of 1/200
+(1/100) of a second.
+</para>
+</listitem>
+</orderedlist>
+</listitem>
+</itemizedlist>
+<para>
+After a message has been received, Exim waits for the clock to tick at the
+appropriate resolution before proceeding, so that if another message is
+received by the same process, or by another process with the same (re-used)
+pid, it is guaranteed that the time will be different. In most cases, the clock
+will already have ticked while the message was being received.
+</para>
+</section>
+<section id="SECID13">
+<title>Receiving mail</title>
+<para>
+<indexterm role="concept">
+<primary>receiving mail</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>reception</secondary>
+</indexterm>
+The only way Exim can receive mail from another host is using SMTP over
+TCP/IP, in which case the sender and recipient addresses are transferred using
+SMTP commands. However, from a locally running process (such as a user’s MUA),
+there are several possibilities:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If the process runs Exim with the <option>-bm</option> option, the message is read
+non-interactively (usually via a pipe), with the recipients taken from the
+command line, or from the body of the message if <option>-t</option> is also used.
+</para>
+</listitem>
+<listitem>
+<para>
+If the process runs Exim with the <option>-bS</option> option, the message is also read
+non-interactively, but in this case the recipients are listed at the start of
+the message in a series of SMTP RCPT commands, terminated by a DATA
+command. This is called <quote>batch SMTP</quote> format,
+but it isn’t really SMTP. The SMTP commands are just another way of passing
+envelope addresses in a non-interactive submission.
+</para>
+</listitem>
+<listitem>
+<para>
+If the process runs Exim with the <option>-bs</option> option, the message is read
+interactively, using the SMTP protocol. A two-way pipe is normally used for
+passing data between the local process and the Exim process.
+This is <quote>real</quote> SMTP and is handled in the same way as SMTP over TCP/IP. For
+example, the ACLs for SMTP commands are used for this form of submission.
+</para>
+</listitem>
+<listitem>
+<para>
+A local process may also make a TCP/IP call to the host’s loopback address
+(127.0.0.1) or any other of its IP addresses. When receiving messages, Exim
+does not treat the loopback address specially. It treats all such connections
+in the same way as connections from other hosts.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+<indexterm role="concept">
+<primary>message sender, constructed by Exim</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>constructed by Exim</secondary>
+</indexterm>
+In the three cases that do not involve TCP/IP, the sender address is
+constructed from the login name of the user that called Exim and a default
+qualification domain (which can be set by the <option>qualify_domain</option> configuration
+option). For local or batch SMTP, a sender address that is passed using the
+SMTP MAIL command is ignored. However, the system administrator may allow
+certain users (<quote>trusted users</quote>) to specify a different sender addresses
+unconditionally, or all users to specify certain forms of different sender
+address. The <option>-f</option> option or the SMTP MAIL command is used to specify these
+different addresses. See section <xref linkend="SECTtrustedadmin"/> for details of trusted
+users, and the <option>untrusted_set_sender</option> option for a way of allowing untrusted
+users to change sender addresses.
+</para>
+<para>
+Messages received by either of the non-interactive mechanisms are subject to
+checking by the non-SMTP ACL if one is defined. Messages received using SMTP
+(either over TCP/IP or interacting with a local process) can be checked by a
+number of ACLs that operate at different times during the SMTP session. Either
+individual recipients or the entire message can be rejected if local policy
+requirements are not met. The <function>local_scan()</function> function (see chapter
+<xref linkend="CHAPlocalscan"/>) is run for all incoming messages.
+</para>
+<para>
+Exim can be configured not to start a delivery process when a message is
+received; this can be unconditional, or depend on the number of incoming SMTP
+connections or the system load. In these situations, new messages wait on the
+queue until a queue runner process picks them up. However, in standard
+configurations under normal conditions, delivery is started as soon as a
+message is received.
+</para>
+</section>
+<section id="SECID14">
+<title>Handling an incoming message</title>
+<para>
+<indexterm role="concept">
+<primary>spool directory</primary>
+<secondary>files that hold a message</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>how a message is held</secondary>
+</indexterm>
+When Exim accepts a message, it writes two files in its spool directory. The
+first contains the envelope information, the current status of the message, and
+the header lines, and the second contains the body of the message. The names of
+the two spool files consist of the message id, followed by <literal>-H</literal> for the
+file containing the envelope and header, and <literal>-D</literal> for the data file.
+</para>
+<para>
+<indexterm role="concept">
+<primary>spool directory</primary>
+<secondary><filename>input</filename> sub-directory</secondary>
+</indexterm>
+By default, all these message files are held in a single directory called
+<filename>input</filename> inside the general Exim spool directory. Some operating systems do
+not perform very well if the number of files in a directory gets large; to
+improve performance in such cases, the <option>split_spool_directory</option> option can be
+used. This causes Exim to split up the input files into 62 sub-directories
+whose names are single letters or digits. When this is done, the queue is
+processed one sub-directory at a time instead of all at once, which can improve
+overall performance even when there are not enough files in each directory to
+affect file system performance.
+</para>
+<para>
+The envelope information consists of the address of the message’s sender and
+the addresses of the recipients. This information is entirely separate from
+any addresses contained in the header lines. The status of the message includes
+a list of recipients who have already received the message. The format of the
+first spool file is described in chapter <xref linkend="CHAPspool"/>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>addresses</secondary>
+</indexterm>
+Address rewriting that is specified in the rewrite section of the configuration
+(see chapter <xref linkend="CHAPrewrite"/>) is done once and for all on incoming addresses,
+both in the header lines and the envelope, at the time the message is accepted.
+If during the course of delivery additional addresses are generated (for
+example, via aliasing), these new addresses are rewritten as soon as they are
+generated. At the time a message is actually delivered (transported) further
+rewriting can take place; because this is a transport option, it can be
+different for different forms of delivery. It is also possible to specify the
+addition or removal of certain header lines at the time the message is
+delivered (see chapters <xref linkend="CHAProutergeneric"/> and
+<xref linkend="CHAPtransportgeneric"/>).
+</para>
+</section>
+<section id="SECID15">
+<title>Life of a message</title>
+<para>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>life of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>frozen</secondary>
+</indexterm>
+A message remains in the spool directory until it is completely delivered to
+its recipients or to an error address, or until it is deleted by an
+administrator or by the user who originally created it. In cases when delivery
+cannot proceed – for example when a message can neither be delivered to its
+recipients nor returned to its sender, the message is marked <quote>frozen</quote> on the
+spool, and no more deliveries are attempted.
+</para>
+<para>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>thawing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>thawing frozen</secondary>
+</indexterm>
+An administrator can <quote>thaw</quote> such messages when the problem has been
+corrected, and can also freeze individual messages by hand if necessary. In
+addition, an administrator can force a delivery error, causing a bounce message
+to be sent.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>timeout_frozen_after</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>ignore_bounce_errors_after</option></primary>
+</indexterm>
+There are options called <option>ignore_bounce_errors_after</option> and
+<option>timeout_frozen_after</option>, which discard frozen messages after a certain time.
+The first applies only to frozen bounces, the second to all frozen messages.
+</para>
+<para>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>log file for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>file for each message</secondary>
+</indexterm>
+While Exim is working on a message, it writes information about each delivery
+attempt to its main log file. This includes successful, unsuccessful, and
+delayed deliveries for each recipient (see chapter <xref linkend="CHAPlog"/>). The log
+lines are also written to a separate <emphasis>message log</emphasis> file for each message.
+These logs are solely for the benefit of the administrator and are normally
+deleted along with the spool files when processing of a message is complete.
+The use of individual message logs can be disabled by setting
+<option>no_message_logs</option>; this might give an improvement in performance on very busy
+systems.
+</para>
+<para>
+<indexterm role="concept">
+<primary>journal file</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>journal</secondary>
+</indexterm>
+All the information Exim itself needs to set up a delivery is kept in the first
+spool file, along with the header lines. When a successful delivery occurs, the
+address is immediately written at the end of a journal file, whose name is the
+message id followed by <literal>-J</literal>. At the end of a delivery run, if there are some
+addresses left to be tried again later, the first spool file (the <literal>-H</literal> file)
+is updated to indicate which these are, and the journal file is then deleted.
+Updating the spool file is done by writing a new file and renaming it, to
+minimize the possibility of data loss.
+</para>
+<para>
+Should the system or Exim crash after a successful delivery but before
+the spool file has been updated, the journal is left lying around. The next
+time Exim attempts to deliver the message, it reads the journal file and
+updates the spool file before proceeding. This minimizes the chances of double
+deliveries caused by crashes.
+</para>
+</section>
+<section id="SECTprocaddress">
+<title>Processing an address for delivery</title>
+<para>
+<indexterm role="concept">
+<primary>drivers</primary>
+<secondary>definition of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>definition of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>definition of</secondary>
+</indexterm>
+The main delivery processing elements of Exim are called <emphasis>routers</emphasis> and
+<emphasis>transports</emphasis>, and collectively these are known as <emphasis>drivers</emphasis>. Code for a
+number of them is provided in the source distribution, and compile-time options
+specify which ones are included in the binary. Runtime options specify which
+ones are actually used for delivering messages.
+</para>
+<para>
+<indexterm role="concept">
+<primary>drivers</primary>
+<secondary>instance definition</secondary>
+</indexterm>
+Each driver that is specified in the runtime configuration is an <emphasis>instance</emphasis>
+of that particular driver type. Multiple instances are allowed; for example,
+you can set up several different <command>smtp</command> transports, each with different
+option values that might specify different ports or different timeouts. Each
+instance has its own identifying name. In what follows we will normally use the
+instance name when discussing one particular instance (that is, one specific
+configuration of the driver), and the generic driver name when discussing
+the driver’s features in general.
+</para>
+<para>
+A <emphasis>router</emphasis> is a driver that operates on an address, either determining how
+its delivery should happen, by assigning it to a specific transport, or
+converting the address into one or more new addresses (for example, via an
+alias file). A router may also explicitly choose to fail an address, causing it
+to be bounced.
+</para>
+<para>
+A <emphasis>transport</emphasis> is a driver that transmits a copy of the message from Exim’s
+spool to some destination. There are two kinds of transport: for a <emphasis>local</emphasis>
+transport, the destination is a file or a pipe on the local host, whereas for a
+<emphasis>remote</emphasis> transport the destination is some other host. A message is passed
+to a specific transport as a result of successful routing. If a message has
+several recipients, it may be passed to a number of different transports.
+</para>
+<para>
+<indexterm role="concept">
+<primary>preconditions</primary>
+<secondary>definition of</secondary>
+</indexterm>
+An address is processed by passing it to each configured router instance in
+turn, subject to certain preconditions, until a router accepts the address or
+specifies that it should be bounced. We will describe this process in more
+detail shortly. First, as a simple example, we consider how each recipient
+address in a message is processed in a small configuration of three routers.
+</para>
+<para>
+To make this a more concrete example, it is described in terms of some actual
+routers, but remember, this is only an example. You can configure Exim’s
+routers in many different ways, and there may be any number of routers in a
+configuration.
+</para>
+<para>
+The first router that is specified in a configuration is often one that handles
+addresses in domains that are not recognized specifically by the local host.
+Typically these are addresses for arbitrary domains on the Internet. A precondition
+is set up which looks for the special domains known to the host (for example,
+its own domain name), and the router is run for addresses that do <emphasis>not</emphasis>
+match. Typically, this is a router that looks up domains in the DNS in order to
+find the hosts to which this address routes. If it succeeds, the address is
+assigned to a suitable SMTP transport; if it does not succeed, the router is
+configured to fail the address.
+</para>
+<para>
+The second router is reached only when the domain is recognized as one that
+<quote>belongs</quote> to the local host. This router does redirection – also known as
+aliasing and forwarding. When it generates one or more new addresses from the
+original, each of them is routed independently from the start. Otherwise, the
+router may cause an address to fail, or it may simply decline to handle the
+address, in which case the address is passed to the next router.
+</para>
+<para>
+The final router in many configurations is one that checks to see if the
+address belongs to a local mailbox. The precondition may involve a check to
+see if the local part is the name of a login account, or it may look up the
+local part in a file or a database. If its preconditions are not met, or if
+the router declines, we have reached the end of the routers. When this happens,
+the address is bounced.
+</para>
+</section>
+<section id="SECID16">
+<title>Processing an address for verification</title>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>for verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>verifying address</primary>
+<secondary>overview</secondary>
+</indexterm>
+As well as being used to decide how to deliver to an address, Exim’s routers
+are also used for <emphasis>address verification</emphasis>. Verification can be requested as
+one of the checks to be performed in an ACL for incoming messages, on both
+sender and recipient addresses, and it can be tested using the <option>-bv</option> and
+<option>-bvs</option> command line options.
+</para>
+<para>
+When an address is being verified, the routers are run in <quote>verify mode</quote>. This
+does not affect the way the routers work, but it is a state that can be
+detected. By this means, a router can be skipped or made to behave differently
+when verifying. A common example is a configuration in which the first router
+sends all messages to a message-scanning program unless they have been
+previously scanned. Thus, the first router accepts all addresses without any
+checking, making it useless for verifying. Normally, the <option>no_verify</option> option
+would be set for such a router, causing it to be skipped in verify mode.
+</para>
+</section>
+<section id="SECTrunindrou">
+<title>Running an individual router</title>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>running details</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>preconditions</primary>
+<secondary>checking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>result of running</secondary>
+</indexterm>
+As explained in the example above, a number of preconditions are checked before
+running a router. If any are not met, the router is skipped, and the address is
+passed to the next router. When all the preconditions on a router <emphasis>are</emphasis> met,
+the router is run. What happens next depends on the outcome, which is one of
+the following:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<emphasis>accept</emphasis>: The router accepts the address, and either assigns it to a
+transport or generates one or more <quote>child</quote> addresses. Processing the
+original address ceases
+<indexterm role="option">
+<primary><option>unseen</option></primary>
+</indexterm>
+unless the <option>unseen</option> option is set on the router. This option
+can be used to set up multiple deliveries with different routing (for example,
+for keeping archive copies of messages). When <option>unseen</option> is set, the address is
+passed to the next router. Normally, however, an <emphasis>accept</emphasis> return marks the
+end of routing.
+</para>
+<para>
+Any child addresses generated by the router are processed independently,
+starting with the first router by default. It is possible to change this by
+setting the <option>redirect_router</option> option to specify which router to start at for
+child addresses. Unlike <option>pass_router</option> (see below) the router specified by
+<option>redirect_router</option> may be anywhere in the router configuration.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>pass</emphasis>: The router recognizes the address, but cannot handle it itself. It
+requests that the address be passed to another router. By default, the address
+is passed to the next router, but this can be changed by setting the
+<option>pass_router</option> option. However, (unlike <option>redirect_router</option>) the named router
+must be below the current router (to avoid loops).
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>decline</emphasis>: The router declines to accept the address because it does not
+recognize it at all. By default, the address is passed to the next router, but
+this can be prevented by setting the <option>no_more</option> option. When <option>no_more</option> is
+set, all the remaining routers are skipped. In effect, <option>no_more</option> converts
+<emphasis>decline</emphasis> into <emphasis>fail</emphasis>.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>fail</emphasis>: The router determines that the address should fail, and queues it for
+the generation of a bounce message. There is no further processing of the
+original address unless <option>unseen</option> is set on the router.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>defer</emphasis>: The router cannot handle the address at the present time. (A
+database may be offline, or a DNS lookup may have timed out.) No further
+processing of the address happens in this delivery attempt. It is tried again
+next time the message is considered for delivery.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>error</emphasis>: There is some error in the router (for example, a syntax error in
+its configuration). The action is as for defer.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+If an address reaches the end of the routers without having been accepted by
+any of them, it is bounced as unrouteable. The default error message in this
+situation is <quote>unrouteable address</quote>, but you can set your own message by
+making use of the <option>cannot_route_message</option> option. This can be set for any
+router; the value from the last router that <quote>saw</quote> the address is used.
+</para>
+<para>
+Sometimes while routing you want to fail a delivery when some conditions are
+met but others are not, instead of passing the address on for further routing.
+You can do this by having a second router that explicitly fails the delivery
+when the relevant conditions are met. The <command>redirect</command> router has a <quote>fail</quote>
+facility for this purpose.
+</para>
+</section>
+<section id="SECID17">
+<title>Duplicate addresses</title>
+<para>
+<indexterm role="concept">
+<primary>case of local parts</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>address duplicate, discarding</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>duplicate addresses</primary>
+</indexterm>
+Once routing is complete, Exim scans the addresses that are assigned to local
+and remote transports and discards any duplicates that it finds. During this
+check, local parts are treated case-sensitively. This happens only when
+actually delivering a message; when testing routers with <option>-bt</option>, all the
+routed addresses are shown.
+</para>
+</section>
+<section id="SECTrouprecon">
+<title>Router preconditions</title>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>preconditions, order of processing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>preconditions</primary>
+<secondary>order of processing</secondary>
+</indexterm>
+The preconditions that are tested for each router are listed below, in the
+order in which they are tested. The individual configuration options are
+described in more detail in chapter <xref linkend="CHAProutergeneric"/>.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>affix</primary>
+<secondary>router precondition</secondary>
+</indexterm>
+The <option>local_part_prefix</option> and <option>local_part_suffix</option> options can specify that
+the local parts handled by the router may or must have certain prefixes and/or
+suffixes. If a mandatory affix (prefix or suffix) is not present, the router is
+skipped. These conditions are tested first. When an affix is present, it is
+removed from the local part before further processing, including the evaluation
+of any other conditions.
+</para>
+</listitem>
+<listitem>
+<para>
+Routers can be designated for use only when not verifying an address, that is,
+only when routing it for delivery (or testing its delivery routing). If the
+<option>verify</option> option is set false, the router is skipped when Exim is verifying an
+address.
+Setting the <option>verify</option> option actually sets two options, <option>verify_sender</option> and
+<option>verify_recipient</option>, which independently control the use of the router for
+sender and recipient verification. You can set these options directly if
+you want a router to be used for only one type of verification.
+Note that cutthrough delivery is classed as a recipient verification for this purpose.
+</para>
+</listitem>
+<listitem>
+<para>
+If the <option>address_test</option> option is set false, the router is skipped when Exim is
+run with the <option>-bt</option> option to test an address routing. This can be helpful
+when the first router sends all new messages to a scanner of some sort; it
+makes it possible to use <option>-bt</option> to test subsequent delivery routing without
+having to simulate the effect of the scanner.
+</para>
+</listitem>
+<listitem>
+<para>
+Routers can be designated for use only when verifying an address, as
+opposed to routing it for delivery. The <option>verify_only</option> option controls this.
+Again, cutthrough delivery counts as a verification.
+</para>
+</listitem>
+<listitem>
+<para>
+Individual routers can be explicitly skipped when running the routers to
+check an address given in the SMTP EXPN command (see the <option>expn</option> option).
+</para>
+</listitem>
+<listitem>
+<para>
+If the <option>domains</option> option is set, the domain of the address must be in the set
+of domains that it defines.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part_prefix</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part_prefix_v</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part_suffix</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part_suffix_v</varname></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>affix</primary>
+<secondary>router precondition</secondary>
+</indexterm>
+If the <option>local_parts</option> option is set, the local part of the address must be in
+the set of local parts that it defines. If <option>local_part_prefix</option> or
+<option>local_part_suffix</option> is in use, the prefix or suffix is removed from the local
+part before this check. If you want to do precondition tests on local parts
+that include affixes, you can do so by using a <option>condition</option> option (see below)
+</para>
+<para revisionflag="changed">
+that uses the variables <varname>$local_part</varname>, <varname>$local_part_prefix</varname>,
+<varname>$local_part_prefix_v</varname>, <varname>$local_part_suffix</varname>
+and <varname>$local_part_suffix_v</varname> as necessary.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_user_uid</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_user_gid</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$home</varname></primary>
+</indexterm>
+If the <option>check_local_user</option> option is set, the local part must be the name of
+an account on the local host. If this check succeeds, the uid and gid of the
+local user are placed in <varname>$local_user_uid</varname> and <varname>$local_user_gid</varname> and the
+user’s home directory is placed in <varname>$home</varname>; these values can be used in the
+remaining preconditions.
+</para>
+</listitem>
+<listitem>
+<para>
+If the <option>router_home_directory</option> option is set, it is expanded at this point,
+because it overrides the value of <varname>$home</varname>. If this expansion were left till
+later, the value of <varname>$home</varname> as set by <option>check_local_user</option> would be used in
+subsequent tests. Having two different values of <varname>$home</varname> in the same router
+could lead to confusion.
+</para>
+</listitem>
+<listitem>
+<para>
+If the <option>senders</option> option is set, the envelope sender address must be in the
+set of addresses that it defines.
+</para>
+</listitem>
+<listitem>
+<para>
+If the <option>require_files</option> option is set, the existence or non-existence of
+specified files is tested.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>customizing</primary>
+<secondary>precondition</secondary>
+</indexterm>
+If the <option>condition</option> option is set, it is evaluated and tested. This option
+uses an expanded string to allow you to set up your own custom preconditions.
+Expanded strings are described in chapter <xref linkend="CHAPexpand"/>.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Note that <option>require_files</option> comes near the end of the list, so you cannot use
+it to check for the existence of a file in which to lookup up a domain, local
+part, or sender. However, as these options are all expanded, you can use the
+<option>exists</option> expansion condition to make such tests within each condition. The
+<option>require_files</option> option is intended for checking files that the router may be
+going to use internally, or which are needed by a specific transport (for
+example, <filename>.procmailrc</filename>).
+</para>
+</section>
+<section id="SECID18">
+<title>Delivery in detail</title>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>in detail</secondary>
+</indexterm>
+When a message is to be delivered, the sequence of events is as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If a system-wide filter file is specified, the message is passed to it. The
+filter may add recipients to the message, replace the recipients, discard the
+message, cause a new message to be generated, or cause the message delivery to
+fail. The format of the system filter file is the same as for Exim user filter
+files, described in the separate document entitled <emphasis>Exim’s interfaces to mail
+filtering</emphasis>.
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary>not available for system filter</secondary>
+</indexterm>
+(<emphasis role="bold">Note</emphasis>: Sieve cannot be used for system filter files.)
+</para>
+<para>
+Some additional features are available in system filters – see chapter
+<xref linkend="CHAPsystemfilter"/> for details. Note that a message is passed to the system
+filter only once per delivery attempt, however many recipients it has. However,
+if there are several delivery attempts because one or more addresses could not
+be immediately delivered, the system filter is run each time. The filter
+condition <option>first_delivery</option> can be used to detect the first run of the system
+filter.
+</para>
+</listitem>
+<listitem>
+<para>
+Each recipient address is offered to each configured router, in turn, subject to
+its preconditions, until one is able to handle it. If no router can handle the
+address, that is, if they all decline, the address is failed. Because routers
+can be targeted at particular domains, several locally handled domains can be
+processed entirely independently of each other.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>routing</primary>
+<secondary>loops in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>loop</primary>
+<secondary>while routing</secondary>
+</indexterm>
+A router that accepts an address may assign it to a local or a remote
+transport. However, the transport is not run at this time. Instead, the address
+is placed on a list for the particular transport, which will be run later.
+Alternatively, the router may generate one or more new addresses (typically
+from alias, forward, or filter files). New addresses are fed back into this
+process from the top, but in order to avoid loops, a router ignores any address
+which has an identically-named ancestor that was processed by itself.
+</para>
+</listitem>
+<listitem>
+<para>
+When all the routing has been done, addresses that have been successfully
+handled are passed to their assigned transports. When local transports are
+doing real local deliveries, they handle only one address at a time, but if a
+local transport is being used as a pseudo-remote transport (for example, to
+collect batched SMTP messages for transmission by some other means) multiple
+addresses can be handled. Remote transports can always handle more than one
+address at a time, but can be configured not to do so, or to restrict multiple
+addresses to the same domain.
+</para>
+</listitem>
+<listitem>
+<para>
+Each local delivery to a file or a pipe runs in a separate process under a
+non-privileged uid, and these deliveries are run one at a time. Remote
+deliveries also run in separate processes, normally under a uid that is private
+to Exim (<quote>the Exim user</quote>), but in this case, several remote deliveries can be
+run in parallel. The maximum number of simultaneous remote deliveries for any
+one message is set by the <option>remote_max_parallel</option> option.
+The order in which deliveries are done is not defined, except that all local
+deliveries happen before any remote deliveries.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>queue runner</primary>
+</indexterm>
+When it encounters a local delivery during a queue run, Exim checks its retry
+database to see if there has been a previous temporary delivery failure for the
+address before running the local transport. If there was a previous failure,
+Exim does not attempt a new delivery until the retry time for the address is
+reached. However, this happens only for delivery attempts that are part of a
+queue run. Local deliveries are always attempted when delivery immediately
+follows message reception, even if retry times are set for them. This makes for
+better behaviour if one particular message is causing problems (for example,
+causing quota overflow, or provoking an error in a filter file).
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>retry in remote transports</secondary>
+</indexterm>
+Remote transports do their own retry handling, since an address may be
+deliverable to one of a number of hosts, each of which may have a different
+retry time. If there have been previous temporary failures and no host has
+reached its retry time, no delivery is attempted, whether in a queue run or
+not. See chapter <xref linkend="CHAPretry"/> for details of retry strategies.
+</para>
+</listitem>
+<listitem>
+<para>
+If there were any permanent errors, a bounce message is returned to an
+appropriate address (the sender in the common case), with details of the error
+for each failing address. Exim can be configured to send copies of bounce
+messages to other addresses.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>deferral</secondary>
+</indexterm>
+If one or more addresses suffered a temporary failure, the message is left on
+the queue, to be tried again later. Delivery of these addresses is said to be
+<emphasis>deferred</emphasis>.
+</para>
+</listitem>
+<listitem>
+<para>
+When all the recipient addresses have either been delivered or bounced,
+handling of the message is complete. The spool files and message log are
+deleted, though the message log can optionally be preserved if required.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID19">
+<title>Retry mechanism</title>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>retry mechanism</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>description of mechanism</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue runner</primary>
+</indexterm>
+Exim’s mechanism for retrying messages that fail to get delivered at the first
+attempt is the queue runner process. You must either run an Exim daemon that
+uses the <option>-q</option> option with a time interval to start queue runners at regular
+intervals or use some other means (such as <emphasis>cron</emphasis>) to start them. If you do
+not arrange for queue runners to be run, messages that fail temporarily at the
+first attempt will remain in your queue forever. A queue runner process works
+its way through the queue, one message at a time, trying each delivery that has
+passed its retry time.
+You can run several queue runners at once.
+</para>
+<para>
+Exim uses a set of configured rules to determine when next to retry the failing
+address (see chapter <xref linkend="CHAPretry"/>). These rules also specify when Exim
+should give up trying to deliver to the address, at which point it generates a
+bounce message. If no retry rules are set for a particular host, address, and
+error combination, no retries are attempted, and temporary errors are treated
+as permanent.
+</para>
+</section>
+<section id="SECID20">
+<title>Temporary delivery failure</title>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>temporary failure</secondary>
+</indexterm>
+There are many reasons why a message may not be immediately deliverable to a
+particular address. Failure to connect to a remote machine (because it, or the
+connection to it, is down) is one of the most common. Temporary failures may be
+detected during routing as well as during the transport stage of delivery.
+Local deliveries may be delayed if NFS files are unavailable, or if a mailbox
+is on a file system where the user is over quota. Exim can be configured to
+impose its own quotas on local mailboxes; where system quotas are set they will
+also apply.
+</para>
+<para>
+If a host is unreachable for a period of time, a number of messages may be
+waiting for it by the time it recovers, and sending them in a single SMTP
+connection is clearly beneficial. Whenever a delivery to a remote host is
+deferred,
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>deferred deliveries</secondary>
+</indexterm>
+Exim makes a note in its hints database, and whenever a successful
+SMTP delivery has happened, it looks to see if any other messages are waiting
+for the same host. If any are found, they are sent over the same SMTP
+connection, subject to a configuration limit as to the maximum number in any
+one connection.
+</para>
+</section>
+<section id="SECID21">
+<title>Permanent delivery failure</title>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>permanent failure</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>when generated</secondary>
+</indexterm>
+When a message cannot be delivered to some or all of its intended recipients, a
+bounce message is generated. Temporary delivery failures turn into permanent
+errors when their timeout expires. All the addresses that fail in a given
+delivery attempt are listed in a single message. If the original message has
+many recipients, it is possible for some addresses to fail in one delivery
+attempt and others to fail subsequently, giving rise to more than one bounce
+message. The wording of bounce messages can be customized by the administrator.
+See chapter <xref linkend="CHAPemsgcust"/> for details.
+</para>
+<para>
+<indexterm role="concept">
+<primary><emphasis>X-Failed-Recipients:</emphasis> header line</primary>
+</indexterm>
+Bounce messages contain an <emphasis>X-Failed-Recipients:</emphasis> header line that lists the
+failed addresses, for the benefit of programs that try to analyse such messages
+automatically.
+</para>
+<para>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>recipient of</secondary>
+</indexterm>
+A bounce message is normally sent to the sender of the original message, as
+obtained from the message’s envelope. For incoming SMTP messages, this is the
+address given in the MAIL command. However, when an address is expanded via a
+forward or alias file, an alternative address can be specified for delivery
+failures of the generated addresses. For a mailing list expansion (see section
+<xref linkend="SECTmailinglists"/>) it is common to direct bounce messages to the manager
+of the list.
+</para>
+</section>
+<section id="SECID22">
+<title>Failures to deliver bounce messages</title>
+<para>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>failure to deliver</secondary>
+</indexterm>
+If a bounce message (either locally generated or received from a remote host)
+itself suffers a permanent delivery failure, the message is left in the queue,
+but it is frozen, awaiting the attention of an administrator. There are options
+that can be used to make Exim discard such failed messages, or to keep them
+for only a short time (see <option>timeout_frozen_after</option> and
+<option>ignore_bounce_errors_after</option>).
+</para>
+</section>
+</chapter>
+
+<chapter id="CHID3">
+<title>Building and installing Exim</title>
+<para>
+<indexterm role="concept" id="IIDbuex" class="startofrange">
+<primary>building Exim</primary>
+</indexterm>
+</para>
+<section id="SECID23">
+<title>Unpacking</title>
+<para>
+Exim is distributed as a gzipped or bzipped tar file which, when unpacked,
+creates a directory with the name of the current release (for example,
+<filename>exim-4.94</filename>) into which the following files are placed:
+</para>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="140pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry> <filename>ACKNOWLEDGMENTS</filename></entry>
+<entry>contains some acknowledgments</entry>
+</row>
+<row>
+<entry> <filename>CHANGES</filename></entry>
+<entry>contains a reference to where changes are documented</entry>
+</row>
+<row>
+<entry> <filename>LICENCE</filename></entry>
+<entry>the GNU General Public Licence</entry>
+</row>
+<row>
+<entry> <filename>Makefile</filename></entry>
+<entry>top-level make file</entry>
+</row>
+<row>
+<entry> <filename>NOTICE</filename></entry>
+<entry>conditions for the use of Exim</entry>
+</row>
+<row>
+<entry> <filename>README</filename></entry>
+<entry>list of files, directories and simple build instructions</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Other files whose names begin with <filename>README</filename> may also be present. The
+following subdirectories are created:
+</para>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="140pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry> <filename>Local</filename></entry>
+<entry>an empty directory for local configuration files</entry>
+</row>
+<row>
+<entry> <filename>OS</filename></entry>
+<entry>OS-specific files</entry>
+</row>
+<row>
+<entry> <filename>doc</filename></entry>
+<entry>documentation files</entry>
+</row>
+<row>
+<entry> <filename>exim_monitor</filename></entry>
+<entry>source files for the Exim monitor</entry>
+</row>
+<row>
+<entry> <filename>scripts</filename></entry>
+<entry>scripts used in the build process</entry>
+</row>
+<row>
+<entry> <filename>src</filename></entry>
+<entry>remaining source files</entry>
+</row>
+<row>
+<entry> <filename>util</filename></entry>
+<entry>independent utilities</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+The main utility programs are contained in the <filename>src</filename> directory and are built
+with the Exim binary. The <filename>util</filename> directory contains a few optional scripts
+that may be useful to some sites.
+</para>
+</section>
+<section id="SECID24">
+<title>Multiple machine architectures and operating systems</title>
+<para>
+<indexterm role="concept">
+<primary>building Exim</primary>
+<secondary>multiple OS/architectures</secondary>
+</indexterm>
+The building process for Exim is arranged to make it easy to build binaries for
+a number of different architectures and operating systems from the same set of
+source files. Compilation does not take place in the <filename>src</filename> directory.
+Instead, a <emphasis>build directory</emphasis> is created for each architecture and operating
+system.
+<indexterm role="concept">
+<primary>symbolic link</primary>
+<secondary>to build directory</secondary>
+</indexterm>
+Symbolic links to the sources are installed in this directory, which is where
+the actual building takes place. In most cases, Exim can discover the machine
+architecture and operating system for itself, but the defaults can be
+overridden if necessary.
+<indexterm role="concept">
+<primary>compiler</primary>
+<secondary>requirements</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>compiler</primary>
+<secondary>version</secondary>
+</indexterm>
+A C99-capable compiler will be required for the build.
+</para>
+</section>
+<section id="SECTpcre">
+<title>PCRE library</title>
+<para>
+<indexterm role="concept">
+<primary>PCRE library</primary>
+</indexterm>
+Exim no longer has an embedded PCRE library as the vast majority of
+modern systems include PCRE as a system library, although you may need to
+install the PCRE package or the PCRE development package for your operating
+system. If your system has a normal PCRE installation the Exim build
+process will need no further configuration. If the library or the
+headers are in an unusual location you will need to either set the PCRE_LIBS
+and INCLUDE directives appropriately,
+or set PCRE_CONFIG=yes to use the installed <command>pcre-config</command> command.
+If your operating system has no
+PCRE support then you will need to obtain and build the current PCRE
+from <emphasis role="bold"><ulink url="ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/">ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/</ulink></emphasis>.
+More information on PCRE is available at <emphasis role="bold"><ulink url="https://www.pcre.org/">https://www.pcre.org/</ulink></emphasis>.
+</para>
+</section>
+<section id="SECTdb">
+<title>DBM libraries</title>
+<para>
+<indexterm role="concept">
+<primary>DBM libraries</primary>
+<secondary>discussion of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>DBM files used for</secondary>
+</indexterm>
+Even if you do not use any DBM files in your configuration, Exim still needs a
+DBM library in order to operate, because it uses indexed files for its hints
+databases. Unfortunately, there are a number of DBM libraries in existence, and
+different operating systems often have different ones installed.
+</para>
+<para>
+<indexterm role="concept">
+<primary>Solaris</primary>
+<secondary>DBM library for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>IRIX, DBM library for</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>BSD, DBM library for</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Linux, DBM library for</primary>
+</indexterm>
+If you are using Solaris, IRIX, one of the modern BSD systems, or a modern
+Linux distribution, the DBM configuration should happen automatically, and you
+may be able to ignore this section. Otherwise, you may have to learn more than
+you would like about DBM libraries from what follows.
+</para>
+<para>
+<indexterm role="concept">
+<primary><emphasis>ndbm</emphasis> DBM library</primary>
+</indexterm>
+Licensed versions of Unix normally contain a library of DBM functions operating
+via the <emphasis>ndbm</emphasis> interface, and this is what Exim expects by default. Free
+versions of Unix seem to vary in what they contain as standard. In particular,
+some early versions of Linux have no default DBM library, and different
+distributors have chosen to bundle different libraries with their packaged
+versions. However, the more recent releases seem to have standardized on the
+Berkeley DB library.
+</para>
+<para>
+Different DBM libraries have different conventions for naming the files they
+use. When a program opens a file called <filename>dbmfile</filename>, there are several
+possibilities:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+A traditional <emphasis>ndbm</emphasis> implementation, such as that supplied as part of
+Solaris, operates on two files called <filename>dbmfile.dir</filename> and <filename>dbmfile.pag</filename>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><emphasis>gdbm</emphasis> DBM library</primary>
+</indexterm>
+The GNU library, <emphasis>gdbm</emphasis>, operates on a single file. If used via its <emphasis>ndbm</emphasis>
+compatibility interface it makes two different hard links to it with names
+<filename>dbmfile.dir</filename> and <filename>dbmfile.pag</filename>, but if used via its native interface, the
+filename is used unmodified.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>Berkeley DB library</primary>
+</indexterm>
+The Berkeley DB package, if called via its <emphasis>ndbm</emphasis> compatibility interface,
+operates on a single file called <filename>dbmfile.db</filename>, but otherwise looks to the
+programmer exactly the same as the traditional <emphasis>ndbm</emphasis> implementation.
+</para>
+</listitem>
+<listitem>
+<para>
+If the Berkeley package is used in its native mode, it operates on a single
+file called <filename>dbmfile</filename>; the programmer’s interface is somewhat different to
+the traditional <emphasis>ndbm</emphasis> interface.
+</para>
+</listitem>
+<listitem>
+<para>
+To complicate things further, there are several very different versions of the
+Berkeley DB package. Version 1.85 was stable for a very long time, releases
+2.<emphasis>x</emphasis> and 3.<emphasis>x</emphasis> were current for a while, but the latest versions when Exim last revamped support were numbered 4.<emphasis>x</emphasis>.
+Maintenance of some of the earlier releases has ceased. All versions of
+Berkeley DB could be obtained from
+<emphasis role="bold"><ulink url="http://www.sleepycat.com/">http://www.sleepycat.com/</ulink></emphasis>, which is now a redirect to their new owner’s
+page with far newer versions listed.
+It is probably wise to plan to move your storage configurations away from
+Berkeley DB format, as today there are smaller and simpler alternatives more
+suited to Exim’s usage model.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><emphasis>tdb</emphasis> DBM library</primary>
+</indexterm>
+Yet another DBM library, called <emphasis>tdb</emphasis>, is available from
+<emphasis role="bold"><ulink url="https://sourceforge.net/projects/tdb/files/">https://sourceforge.net/projects/tdb/files/</ulink></emphasis>. It has its own interface, and also
+operates on a single file.
+</para>
+</listitem>
+</orderedlist>
+<para>
+<indexterm role="concept">
+<primary>USE_DB</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>DBM libraries</primary>
+<secondary>configuration for building</secondary>
+</indexterm>
+Exim and its utilities can be compiled to use any of these interfaces. In order
+to use any version of the Berkeley DB package in native mode, you must set
+USE_DB in an appropriate configuration file (typically
+<filename>Local/Makefile</filename>). For example:
+</para>
+<literallayout class="monospaced">
+USE_DB=yes
+</literallayout>
+<para>
+Similarly, for gdbm you set USE_GDBM, and for tdb you set USE_TDB. An
+error is diagnosed if you set more than one of these.
+</para>
+<para>
+At the lowest level, the build-time configuration sets none of these options,
+thereby assuming an interface of type (1). However, some operating system
+configuration files (for example, those for the BSD operating systems and
+Linux) assume type (4) by setting USE_DB as their default, and the
+configuration files for Cygwin set USE_GDBM. Anything you set in
+<filename>Local/Makefile</filename>, however, overrides these system defaults.
+</para>
+<para>
+As well as setting USE_DB, USE_GDBM, or USE_TDB, it may also be
+necessary to set DBMLIB, to cause inclusion of the appropriate library, as
+in one of these lines:
+</para>
+<literallayout class="monospaced">
+DBMLIB = -ldb
+DBMLIB = -ltdb
+</literallayout>
+<para>
+Settings like that will work if the DBM library is installed in the standard
+place. Sometimes it is not, and the library’s header file may also not be in
+the default path. You may need to set INCLUDE to specify where the header
+file is, and to specify the path to the library more fully in DBMLIB, as in
+this example:
+</para>
+<literallayout class="monospaced">
+INCLUDE=-I/usr/local/include/db-4.1
+DBMLIB=/usr/local/lib/db-4.1/libdb.a
+</literallayout>
+<para>
+There is further detailed discussion about the various DBM libraries in the
+file <filename>doc/dbm.discuss.txt</filename> in the Exim distribution.
+</para>
+</section>
+<section id="SECID25">
+<title>Pre-building configuration</title>
+<para>
+<indexterm role="concept">
+<primary>building Exim</primary>
+<secondary>pre-building configuration</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>configuration for building Exim</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><filename>Local/Makefile</filename></primary>
+</indexterm>
+<indexterm role="concept">
+<primary><filename>src/EDITME</filename></primary>
+</indexterm>
+Before building Exim, a local configuration file that specifies options
+independent of any operating system has to be created with the name
+<filename>Local/Makefile</filename>. A template for this file is supplied as the file
+<filename>src/EDITME</filename>, and it contains full descriptions of all the option settings
+therein. These descriptions are therefore not repeated here. If you are
+building Exim for the first time, the simplest thing to do is to copy
+<filename>src/EDITME</filename> to <filename>Local/Makefile</filename>, then read it and edit it appropriately.
+</para>
+<para>
+There are three settings that you must supply, because Exim will not build
+without them. They are the location of the runtime configuration file
+(CONFIGURE_FILE), the directory in which Exim binaries will be installed
+(BIN_DIRECTORY), and the identity of the Exim user (EXIM_USER and
+maybe EXIM_GROUP as well). The value of CONFIGURE_FILE can in fact be
+a colon-separated list of filenames; Exim uses the first of them that exists.
+</para>
+<para>
+There are a few other parameters that can be specified either at build time or
+at runtime, to enable the same binary to be used on a number of different
+machines. However, if the locations of Exim’s spool directory and log file
+directory (if not within the spool directory) are fixed, it is recommended that
+you specify them in <filename>Local/Makefile</filename> instead of at runtime, so that errors
+detected early in Exim’s execution (such as a malformed configuration file) can
+be logged.
+</para>
+<para>
+<indexterm role="concept">
+<primary>content scanning</primary>
+<secondary>specifying at build time</secondary>
+</indexterm>
+Exim’s interfaces for calling virus and spam scanning software directly from
+access control lists are not compiled by default. If you want to include these
+facilities, you need to set
+</para>
+<literallayout class="monospaced">
+WITH_CONTENT_SCAN=yes
+</literallayout>
+<para>
+in your <filename>Local/Makefile</filename>. For details of the facilities themselves, see
+chapter <xref linkend="CHAPexiscan"/>.
+</para>
+<para>
+<indexterm role="concept">
+<primary><filename>Local/eximon.conf</filename></primary>
+</indexterm>
+<indexterm role="concept">
+<primary><filename>exim_monitor/EDITME</filename></primary>
+</indexterm>
+If you are going to build the Exim monitor, a similar configuration process is
+required. The file <filename>exim_monitor/EDITME</filename> must be edited appropriately for
+your installation and saved under the name <filename>Local/eximon.conf</filename>. If you are
+happy with the default settings described in <filename>exim_monitor/EDITME</filename>,
+<filename>Local/eximon.conf</filename> can be empty, but it must exist.
+</para>
+<para>
+This is all the configuration that is needed in straightforward cases for known
+operating systems. However, the building process is set up so that it is easy
+to override options that are set by default or by operating-system-specific
+configuration files, for example, to change the C compiler, which
+defaults to <option>gcc</option>. See section <xref linkend="SECToverride"/> below for details of how to
+do this.
+</para>
+</section>
+<section id="SECID26">
+<title>Support for iconv()</title>
+<para>
+<indexterm role="concept">
+<primary><function>iconv()</function> support</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>RFC 2047</primary>
+</indexterm>
+The contents of header lines in messages may be encoded according to the rules
+described RFC 2047. This makes it possible to transmit characters that are not
+in the ASCII character set, and to label them as being in a particular
+character set. When Exim is inspecting header lines by means of the <option>$h_</option>
+mechanism, it decodes them, and translates them into a specified character set
+(default is set at build time). The translation is possible only if the operating system
+supports the <function>iconv()</function> function.
+</para>
+<para>
+However, some of the operating systems that supply <function>iconv()</function> do not support
+very many conversions. The GNU <option>libiconv</option> library (available from
+<emphasis role="bold"><ulink url="https://www.gnu.org/software/libiconv/">https://www.gnu.org/software/libiconv/</ulink></emphasis>) can be installed on such
+systems to remedy this deficiency, as well as on systems that do not supply
+<function>iconv()</function> at all. After installing <option>libiconv</option>, you should add
+</para>
+<literallayout class="monospaced">
+HAVE_ICONV=yes
+</literallayout>
+<para>
+to your <filename>Local/Makefile</filename> and rebuild Exim.
+</para>
+</section>
+<section id="SECTinctlsssl">
+<title>Including TLS/SSL encryption support</title>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>including support for TLS</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>encryption</primary>
+<secondary>including support for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>OpenSSL</primary>
+<secondary>building Exim with</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>GnuTLS</primary>
+<secondary>building Exim with</secondary>
+</indexterm>
+Exim is usually built to support encrypted SMTP connections, using the STARTTLS
+command as per RFC 2487. It can also support clients that expect to
+start a TLS session immediately on connection to a non-standard port (see the
+<option>tls_on_connect_ports</option> runtime option and the <option>-tls-on-connect</option> command
+line option).
+</para>
+<para>
+If you want to build Exim with TLS support, you must first install either the
+OpenSSL or GnuTLS library. There is no cryptographic code in Exim itself for
+implementing SSL.
+</para>
+<para>
+If you do not want TLS support you should set
+</para>
+<literallayout class="monospaced">
+DISABLE_TLS=yes
+</literallayout>
+<para>
+in <filename>Local/Makefile</filename>.
+</para>
+<para>
+If OpenSSL is installed, you should set
+</para>
+<literallayout class="monospaced">
+USE_OPENSL=yes
+TLS_LIBS=-lssl -lcrypto
+</literallayout>
+<para>
+in <filename>Local/Makefile</filename>. You may also need to specify the locations of the
+OpenSSL library and include files. For example:
+</para>
+<literallayout class="monospaced">
+USE_OPENSSL=yes
+TLS_LIBS=-L/usr/local/openssl/lib -lssl -lcrypto
+TLS_INCLUDE=-I/usr/local/openssl/include/
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>pkg-config</primary>
+<secondary>OpenSSL</secondary>
+</indexterm>
+If you have <emphasis>pkg-config</emphasis> available, then instead you can just use:
+</para>
+<literallayout class="monospaced">
+USE_OPENSSL=yes
+USE_OPENSSL_PC=openssl
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>USE_GNUTLS</primary>
+</indexterm>
+If GnuTLS is installed, you should set
+</para>
+<literallayout class="monospaced">
+USE_GNUTLS=yes
+TLS_LIBS=-lgnutls -ltasn1 -lgcrypt
+</literallayout>
+<para>
+in <filename>Local/Makefile</filename>, and again you may need to specify the locations of the
+library and include files. For example:
+</para>
+<literallayout class="monospaced">
+USE_GNUTLS=yes
+TLS_LIBS=-L/usr/gnu/lib -lgnutls -ltasn1 -lgcrypt
+TLS_INCLUDE=-I/usr/gnu/include
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>pkg-config</primary>
+<secondary>GnuTLS</secondary>
+</indexterm>
+If you have <emphasis>pkg-config</emphasis> available, then instead you can just use:
+</para>
+<literallayout class="monospaced">
+USE_GNUTLS=yes
+USE_GNUTLS_PC=gnutls
+</literallayout>
+<para>
+You do not need to set TLS_INCLUDE if the relevant directory is already
+specified in INCLUDE. Details of how to configure Exim to make use of TLS are
+given in chapter <xref linkend="CHAPTLS"/>.
+</para>
+</section>
+<section id="SECID27">
+<title>Use of tcpwrappers</title>
+<para>
+<indexterm role="concept">
+<primary>tcpwrappers, building Exim to support</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>USE_TCP_WRAPPERS</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP_WRAPPERS_DAEMON_NAME</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>tcp_wrappers_daemon_name</primary>
+</indexterm>
+Exim can be linked with the <emphasis>tcpwrappers</emphasis> library in order to check incoming
+SMTP calls using the <emphasis>tcpwrappers</emphasis> control files. This may be a convenient
+alternative to Exim’s own checking facilities for installations that are
+already making use of <emphasis>tcpwrappers</emphasis> for other purposes. To do this, you
+should set USE_TCP_WRAPPERS in <filename>Local/Makefile</filename>, arrange for the file
+<filename>tcpd.h</filename> to be available at compile time, and also ensure that the library
+<filename>libwrap.a</filename> is available at link time, typically by including <option>-lwrap</option> in
+EXTRALIBS_EXIM. For example, if <emphasis>tcpwrappers</emphasis> is installed in <filename>/usr/local</filename>,
+you might have
+</para>
+<literallayout class="monospaced">
+USE_TCP_WRAPPERS=yes
+CFLAGS=-O -I/usr/local/include
+EXTRALIBS_EXIM=-L/usr/local/lib -lwrap
+</literallayout>
+<para>
+in <filename>Local/Makefile</filename>. The daemon name to use in the <emphasis>tcpwrappers</emphasis> control
+files is <quote>exim</quote>. For example, the line
+</para>
+<literallayout class="monospaced">
+exim : LOCAL 192.168.1. .friendly.domain.example
+</literallayout>
+<para>
+in your <filename>/etc/hosts.allow</filename> file allows connections from the local host, from
+the subnet 192.168.1.0/24, and from all hosts in <emphasis>friendly.domain.example</emphasis>.
+All other connections are denied. The daemon name used by <emphasis>tcpwrappers</emphasis>
+can be changed at build time by setting TCP_WRAPPERS_DAEMON_NAME in
+<filename>Local/Makefile</filename>, or by setting tcp_wrappers_daemon_name in the
+configure file. Consult the <emphasis>tcpwrappers</emphasis> documentation for
+further details.
+</para>
+</section>
+<section id="SECID28">
+<title>Including support for IPv6</title>
+<para>
+<indexterm role="concept">
+<primary>IPv6</primary>
+<secondary>including support for</secondary>
+</indexterm>
+Exim contains code for use on systems that have IPv6 support. Setting
+<literal>HAVE_IPV6=YES</literal> in <filename>Local/Makefile</filename> causes the IPv6 code to be included;
+it may also be necessary to set IPV6_INCLUDE and IPV6_LIBS on systems
+where the IPv6 support is not fully integrated into the normal include and
+library files.
+</para>
+<para>
+Two different types of DNS record for handling IPv6 addresses have been
+defined. AAAA records (analogous to A records for IPv4) are in use, and are
+currently seen as the mainstream. Another record type called A6 was proposed
+as better than AAAA because it had more flexibility. However, it was felt to be
+over-complex, and its status was reduced to <quote>experimental</quote>.
+Exim used to
+have a compile option for including A6 record support but this has now been
+withdrawn.
+</para>
+</section>
+<section id="SECTdynamicmodules">
+<title>Dynamically loaded lookup module support</title>
+<para>
+<indexterm role="concept">
+<primary>lookup modules</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>dynamic modules</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>.so building</primary>
+</indexterm>
+On some platforms, Exim supports not compiling all lookup types directly into
+the main binary, instead putting some into external modules which can be loaded
+on demand.
+This permits packagers to build Exim with support for lookups with extensive
+library dependencies without requiring all users to install all of those
+dependencies.
+Most, but not all, lookup types can be built this way.
+</para>
+<para>
+Set <literal>LOOKUP_MODULE_DIR</literal> to the directory into which the modules will be
+installed; Exim will only load modules from that directory, as a security
+measure. You will need to set <literal>CFLAGS_DYNAMIC</literal> if not already defined
+for your OS; see <filename>OS/Makefile-Linux</filename> for an example.
+Some other requirements for adjusting <literal>EXTRALIBS</literal> may also be necessary,
+see <filename>src/EDITME</filename> for details.
+</para>
+<para>
+Then, for each module to be loaded dynamically, define the relevant
+<literal>LOOKUP_</literal><<emphasis>lookup_type</emphasis>> flags to have the value "2" instead of "yes".
+For example, this will build in lsearch but load sqlite and mysql support
+on demand:
+</para>
+<literallayout class="monospaced">
+LOOKUP_LSEARCH=yes
+LOOKUP_SQLITE=2
+LOOKUP_MYSQL=2
+</literallayout>
+</section>
+<section id="SECID29">
+<title>The building process</title>
+<para>
+<indexterm role="concept">
+<primary>build directory</primary>
+</indexterm>
+Once <filename>Local/Makefile</filename> (and <filename>Local/eximon.conf</filename>, if required) have been
+created, run <emphasis>make</emphasis> at the top level. It determines the architecture and
+operating system types, and creates a build directory if one does not exist.
+For example, on a Sun system running Solaris 8, the directory
+<filename>build-SunOS5-5.8-sparc</filename> is created.
+<indexterm role="concept">
+<primary>symbolic link</primary>
+<secondary>to source files</secondary>
+</indexterm>
+Symbolic links to relevant source files are installed in the build directory.
+</para>
+<para>
+If this is the first time <emphasis>make</emphasis> has been run, it calls a script that builds
+a make file inside the build directory, using the configuration files from the
+<filename>Local</filename> directory. The new make file is then passed to another instance of
+<emphasis>make</emphasis>. This does the real work, building a number of utility scripts, and
+then compiling and linking the binaries for the Exim monitor (if configured), a
+number of utility programs, and finally Exim itself. The command <literal>make
+makefile</literal> can be used to force a rebuild of the make file in the build
+directory, should this ever be necessary.
+</para>
+<para>
+If you have problems building Exim, check for any comments there may be in the
+<filename>README</filename> file concerning your operating system, and also take a look at the
+FAQ, where some common problems are covered.
+</para>
+</section>
+<section id="SECID283">
+<title>Output from <quote>make</quote></title>
+<para>
+The output produced by the <emphasis>make</emphasis> process for compile lines is often very
+unreadable, because these lines can be very long. For this reason, the normal
+output is suppressed by default, and instead output similar to that which
+appears when compiling the 2.6 Linux kernel is generated: just a short line for
+each module that is being compiled or linked. However, it is still possible to
+get the full output, by calling <emphasis>make</emphasis> like this:
+</para>
+<literallayout class="monospaced">
+FULLECHO='' make -e
+</literallayout>
+<para>
+The value of FULLECHO defaults to <quote>@</quote>, the flag character that suppresses
+command reflection in <emphasis>make</emphasis>. When you ask for the full output, it is
+given in addition to the short output.
+</para>
+</section>
+<section id="SECToverride">
+<title>Overriding build-time options for Exim</title>
+<para>
+<indexterm role="concept">
+<primary>build-time options, overriding</primary>
+</indexterm>
+The main make file that is created at the beginning of the building process
+consists of the concatenation of a number of files which set configuration
+values, followed by a fixed set of <emphasis>make</emphasis> instructions. If a value is set
+more than once, the last setting overrides any previous ones. This provides a
+convenient way of overriding defaults. The files that are concatenated are, in
+order:
+</para>
+<literallayout>
+<filename>OS/Makefile-Default</filename>
+<filename>OS/Makefile-</filename><<emphasis>ostype</emphasis>>
+<filename>Local/Makefile</filename>
+<filename>Local/Makefile-</filename><<emphasis>ostype</emphasis>>
+<filename>Local/Makefile-</filename><<emphasis>archtype</emphasis>>
+<filename>Local/Makefile-</filename><<emphasis>ostype</emphasis>>-<<emphasis>archtype</emphasis>>
+<filename>OS/Makefile-Base</filename>
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary><filename>Local/Makefile</filename></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>building Exim</primary>
+<secondary>operating system type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>building Exim</primary>
+<secondary>architecture type</secondary>
+</indexterm>
+where <<emphasis>ostype</emphasis>> is the operating system type and <<emphasis>archtype</emphasis>> is the
+architecture type. <filename>Local/Makefile</filename> is required to exist, and the building
+process fails if it is absent. The other three <filename>Local</filename> files are optional,
+and are often not needed.
+</para>
+<para>
+The values used for <<emphasis>ostype</emphasis>> and <<emphasis>archtype</emphasis>> are obtained from scripts
+called <filename>scripts/os-type</filename> and <filename>scripts/arch-type</filename> respectively. If either of
+the environment variables EXIM_OSTYPE or EXIM_ARCHTYPE is set, their
+values are used, thereby providing a means of forcing particular settings.
+Otherwise, the scripts try to get values from the <option>uname</option> command. If this
+fails, the shell variables OSTYPE and ARCHTYPE are inspected. A number
+of <emphasis>ad hoc</emphasis> transformations are then applied, to produce the standard names
+that Exim expects. You can run these scripts directly from the shell in order
+to find out what values are being used on your system.
+</para>
+<para>
+<filename>OS/Makefile-Default</filename> contains comments about the variables that are set
+therein. Some (but not all) are mentioned below. If there is something that
+needs changing, review the contents of this file and the contents of the make
+file for your operating system (<filename>OS/Makefile-<ostype></filename>) to see what the
+default values are.
+</para>
+<para>
+<indexterm role="concept">
+<primary>building Exim</primary>
+<secondary>overriding default settings</secondary>
+</indexterm>
+If you need to change any of the values that are set in <filename>OS/Makefile-Default</filename>
+or in <filename>OS/Makefile-<ostype></filename>, or to add any new definitions, you do not
+need to change the original files. Instead, you should make the changes by
+putting the new values in an appropriate <filename>Local</filename> file. For example,
+<indexterm role="concept">
+<primary>Tru64-Unix build-time settings</primary>
+</indexterm>
+when building Exim in many releases of the Tru64-Unix (formerly Digital UNIX,
+formerly DEC-OSF1) operating system, it is necessary to specify that the C
+compiler is called <emphasis>cc</emphasis> rather than <emphasis>gcc</emphasis>. Also, the compiler must be
+called with the option <option>-std1</option>, to make it recognize some of the features of
+Standard C that Exim uses. (Most other compilers recognize Standard C by
+default.) To do this, you should create a file called <filename>Local/Makefile-OSF1</filename>
+containing the lines
+</para>
+<literallayout class="monospaced">
+CC=cc
+CFLAGS=-std1
+</literallayout>
+<para>
+If you are compiling for just one operating system, it may be easier to put
+these lines directly into <filename>Local/Makefile</filename>.
+</para>
+<para>
+Keeping all your local configuration settings separate from the distributed
+files makes it easy to transfer them to new versions of Exim simply by copying
+the contents of the <filename>Local</filename> directory.
+</para>
+<para>
+<indexterm role="concept">
+<primary>NIS lookup type</primary>
+<secondary>including support for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>NIS+ lookup type</primary>
+<secondary>including support for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>including support for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>inclusion in binary</secondary>
+</indexterm>
+Exim contains support for doing LDAP, NIS, NIS+, and other kinds of file
+lookup, but not all systems have these components installed, so the default is
+not to include the relevant code in the binary. All the different kinds of file
+and database lookup that Exim supports are implemented as separate code modules
+which are included only if the relevant compile-time options are set. In the
+case of LDAP, NIS, and NIS+, the settings for <filename>Local/Makefile</filename> are:
+</para>
+<literallayout class="monospaced">
+LOOKUP_LDAP=yes
+LOOKUP_NIS=yes
+LOOKUP_NISPLUS=yes
+</literallayout>
+<para>
+and similar settings apply to the other lookup types. They are all listed in
+<filename>src/EDITME</filename>. In many cases the relevant include files and interface
+libraries need to be installed before compiling Exim.
+<indexterm role="concept">
+<primary>cdb</primary>
+<secondary>including support for</secondary>
+</indexterm>
+However, there are some optional lookup types (such as cdb) for which
+the code is entirely contained within Exim, and no external include
+files or libraries are required. When a lookup type is not included in the
+binary, attempts to configure Exim to use it cause runtime configuration
+errors.
+</para>
+<para>
+<indexterm role="concept">
+<primary>pkg-config</primary>
+<secondary>lookups</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>pkg-config</primary>
+<secondary>authenticators</secondary>
+</indexterm>
+Many systems now use a tool called <emphasis>pkg-config</emphasis> to encapsulate information
+about how to compile against a library; Exim has some initial support for
+being able to use pkg-config for lookups and authenticators. For any given
+makefile variable which starts <literal>LOOKUP_</literal> or <literal>AUTH_</literal>, you can add a new
+variable with the <literal>_PC</literal> suffix in the name and assign as the value the
+name of the package to be queried. The results of querying via the
+<emphasis>pkg-config</emphasis> command will be added to the appropriate Makefile variables
+with <literal>+=</literal> directives, so your version of <emphasis>make</emphasis> will need to support that
+syntax. For instance:
+</para>
+<literallayout class="monospaced">
+LOOKUP_SQLITE=yes
+LOOKUP_SQLITE_PC=sqlite3
+AUTH_GSASL=yes
+AUTH_GSASL_PC=libgsasl
+AUTH_HEIMDAL_GSSAPI=yes
+AUTH_HEIMDAL_GSSAPI_PC=heimdal-gssapi
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>Perl</primary>
+<secondary>including support for</secondary>
+</indexterm>
+Exim can be linked with an embedded Perl interpreter, allowing Perl
+subroutines to be called during string expansion. To enable this facility,
+</para>
+<literallayout class="monospaced">
+EXIM_PERL=perl.o
+</literallayout>
+<para>
+must be defined in <filename>Local/Makefile</filename>. Details of this facility are given in
+chapter <xref linkend="CHAPperl"/>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>X11 libraries, location of</primary>
+</indexterm>
+The location of the X11 libraries is something that varies a lot between
+operating systems, and there may be different versions of X11 to cope
+with. Exim itself makes no use of X11, but if you are compiling the Exim
+monitor, the X11 libraries must be available.
+The following three variables are set in <filename>OS/Makefile-Default</filename>:
+</para>
+<literallayout class="monospaced">
+X11=/usr/X11R6
+XINCLUDE=-I$(X11)/include
+XLFLAGS=-L$(X11)/lib
+</literallayout>
+<para>
+These are overridden in some of the operating-system configuration files. For
+example, in <filename>OS/Makefile-SunOS5</filename> there is
+</para>
+<literallayout class="monospaced">
+X11=/usr/openwin
+XINCLUDE=-I$(X11)/include
+XLFLAGS=-L$(X11)/lib -R$(X11)/lib
+</literallayout>
+<para>
+If you need to override the default setting for your operating system, place a
+definition of all three of these variables into your
+<filename>Local/Makefile-<ostype></filename> file.
+</para>
+<para>
+<indexterm role="concept">
+<primary>EXTRALIBS</primary>
+</indexterm>
+If you need to add any extra libraries to the link steps, these can be put in a
+variable called EXTRALIBS, which appears in all the link commands, but by
+default is not defined. In contrast, EXTRALIBS_EXIM is used only on the
+command for linking the main Exim binary, and not for any associated utilities.
+</para>
+<para>
+<indexterm role="concept">
+<primary>DBM libraries</primary>
+<secondary>configuration for building</secondary>
+</indexterm>
+There is also DBMLIB, which appears in the link commands for binaries that
+use DBM functions (see also section <xref linkend="SECTdb"/>). Finally, there is
+EXTRALIBS_EXIMON, which appears only in the link step for the Exim monitor
+binary, and which can be used, for example, to include additional X11
+libraries.
+</para>
+<para>
+<indexterm role="concept">
+<primary>configuration file</primary>
+<secondary>editing</secondary>
+</indexterm>
+The make file copes with rebuilding Exim correctly if any of the configuration
+files are edited. However, if an optional configuration file is deleted, it is
+necessary to touch the associated non-optional file (that is,
+<filename>Local/Makefile</filename> or <filename>Local/eximon.conf</filename>) before rebuilding.
+</para>
+</section>
+<section id="SECID30">
+<title>OS-specific header files</title>
+<para>
+<indexterm role="concept">
+<primary><filename>os.h</filename></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>building Exim</primary>
+<secondary>OS-specific C header files</secondary>
+</indexterm>
+The <filename>OS</filename> directory contains a number of files with names of the form
+<filename>os.h-<ostype></filename>. These are system-specific C header files that should not
+normally need to be changed. There is a list of macro settings that are
+recognized in the file <filename>OS/os.configuring</filename>, which should be consulted if you
+are porting Exim to a new operating system.
+</para>
+</section>
+<section id="SECID31">
+<title>Overriding build-time options for the monitor</title>
+<para>
+<indexterm role="concept">
+<primary>building Eximon</primary>
+</indexterm>
+A similar process is used for overriding things when building the Exim monitor,
+where the files that are involved are
+</para>
+<literallayout>
+<filename>OS/eximon.conf-Default</filename>
+<filename>OS/eximon.conf-</filename><<emphasis>ostype</emphasis>>
+<filename>Local/eximon.conf</filename>
+<filename>Local/eximon.conf-</filename><<emphasis>ostype</emphasis>>
+<filename>Local/eximon.conf-</filename><<emphasis>archtype</emphasis>>
+<filename>Local/eximon.conf-</filename><<emphasis>ostype</emphasis>>-<<emphasis>archtype</emphasis>>
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary><filename>Local/eximon.conf</filename></primary>
+</indexterm>
+As with Exim itself, the final three files need not exist, and in this case the
+<filename>OS/eximon.conf-<ostype></filename> file is also optional. The default values in
+<filename>OS/eximon.conf-Default</filename> can be overridden dynamically by setting environment
+variables of the same name, preceded by EXIMON_. For example, setting
+EXIMON_LOG_DEPTH in the environment overrides the value of
+LOG_DEPTH at runtime.
+<indexterm role="concept" startref="IIDbuex" class="endofrange"/>
+</para>
+</section>
+<section id="SECID32">
+<title>Installing Exim binaries and scripts</title>
+<para>
+<indexterm role="concept">
+<primary>installing Exim</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>BIN_DIRECTORY</primary>
+</indexterm>
+The command <literal>make install</literal> runs the <command>exim_install</command> script with no
+arguments. The script copies binaries and utility scripts into the directory
+whose name is specified by the BIN_DIRECTORY setting in <filename>Local/Makefile</filename>.
+<indexterm role="concept">
+<primary>setuid</primary>
+<secondary>installing Exim with</secondary>
+</indexterm>
+The install script copies files only if they are newer than the files they are
+going to replace. The Exim binary is required to be owned by root and have the
+<emphasis>setuid</emphasis> bit set, for normal configurations. Therefore, you must run <literal>make
+install</literal> as root so that it can set up the Exim binary in this way. However, in
+some special situations (for example, if a host is doing no local deliveries)
+it may be possible to run Exim without making the binary setuid root (see
+chapter <xref linkend="CHAPsecurity"/> for details).
+</para>
+<para>
+<indexterm role="concept">
+<primary>CONFIGURE_FILE</primary>
+</indexterm>
+Exim’s runtime configuration file is named by the CONFIGURE_FILE setting
+in <filename>Local/Makefile</filename>. If this names a single file, and the file does not
+exist, the default configuration file <filename>src/configure.default</filename> is copied there
+by the installation script. If a runtime configuration file already exists, it
+is left alone. If CONFIGURE_FILE is a colon-separated list, naming several
+alternative files, no default is installed.
+</para>
+<para>
+<indexterm role="concept">
+<primary>system aliases file</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><filename>/etc/aliases</filename></primary>
+</indexterm>
+One change is made to the default configuration file when it is installed: the
+default configuration contains a router that references a system aliases file.
+The path to this file is set to the value specified by
+SYSTEM_ALIASES_FILE in <filename>Local/Makefile</filename> (<filename>/etc/aliases</filename> by default).
+If the system aliases file does not exist, the installation script creates it,
+and outputs a comment to the user.
+</para>
+<para>
+The created file contains no aliases, but it does contain comments about the
+aliases a site should normally have. Mail aliases have traditionally been
+kept in <filename>/etc/aliases</filename>. However, some operating systems are now using
+<filename>/etc/mail/aliases</filename>. You should check if yours is one of these, and change
+Exim’s configuration if necessary.
+</para>
+<para>
+The default configuration uses the local host’s name as the only local domain,
+and is set up to do local deliveries into the shared directory <filename>/var/mail</filename>,
+running as the local user. System aliases and <filename>.forward</filename> files in users’ home
+directories are supported, but no NIS or NIS+ support is configured. Domains
+other than the name of the local host are routed using the DNS, with delivery
+over SMTP.
+</para>
+<para>
+It is possible to install Exim for special purposes (such as building a binary
+distribution) in a private part of the file system. You can do this by a
+command such as
+</para>
+<literallayout class="monospaced">
+make DESTDIR=/some/directory/ install
+</literallayout>
+<para>
+This has the effect of pre-pending the specified directory to all the file
+paths, except the name of the system aliases file that appears in the default
+configuration. (If a default alias file is created, its name <emphasis>is</emphasis> modified.)
+For backwards compatibility, ROOT is used if DESTDIR is not set,
+but this usage is deprecated.
+</para>
+<para>
+<indexterm role="concept">
+<primary>installing Exim</primary>
+<secondary>what is not installed</secondary>
+</indexterm>
+Running <emphasis>make install</emphasis> does not copy the Exim 4 conversion script
+<emphasis>convert4r4</emphasis>. You will probably run this only once if you are
+upgrading from Exim 3. None of the documentation files in the <filename>doc</filename>
+directory are copied, except for the info files when you have set
+INFO_DIRECTORY, as described in section <xref linkend="SECTinsinfdoc"/> below.
+</para>
+<para>
+For the utility programs, old versions are renamed by adding the suffix <filename>.O</filename>
+to their names. The Exim binary itself, however, is handled differently. It is
+installed under a name that includes the version number and the compile number,
+for example, <filename>exim-4.94-1</filename>. The script then arranges for a symbolic link
+called <filename>exim</filename> to point to the binary. If you are updating a previous version
+of Exim, the script takes care to ensure that the name <filename>exim</filename> is never absent
+from the directory (as seen by other processes).
+</para>
+<para>
+<indexterm role="concept">
+<primary>installing Exim</primary>
+<secondary>testing the script</secondary>
+</indexterm>
+If you want to see what the <emphasis>make install</emphasis> will do before running it for
+real, you can pass the <option>-n</option> option to the installation script by this
+command:
+</para>
+<literallayout class="monospaced">
+make INSTALL_ARG=-n install
+</literallayout>
+<para>
+The contents of the variable INSTALL_ARG are passed to the installation
+script. You do not need to be root to run this test. Alternatively, you can run
+the installation script directly, but this must be from within the build
+directory. For example, from the top-level Exim directory you could use this
+command:
+</para>
+<literallayout class="monospaced">
+(cd build-SunOS5-5.5.1-sparc; ../scripts/exim_install -n)
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>installing Exim</primary>
+<secondary>install script options</secondary>
+</indexterm>
+There are two other options that can be supplied to the installation script.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<option>-no_chown</option> bypasses the call to change the owner of the installed binary
+to root, and the call to make it a setuid binary.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>-no_symlink</option> bypasses the setting up of the symbolic link <filename>exim</filename> to the
+installed binary.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+INSTALL_ARG can be used to pass these options to the script. For example:
+</para>
+<literallayout class="monospaced">
+make INSTALL_ARG=-no_symlink install
+</literallayout>
+<para>
+The installation script can also be given arguments specifying which files are
+to be copied. For example, to install just the Exim binary, and nothing else,
+without creating the symbolic link, you could use:
+</para>
+<literallayout class="monospaced">
+make INSTALL_ARG='-no_symlink exim' install
+</literallayout>
+</section>
+<section id="SECTinsinfdoc">
+<title>Installing info documentation</title>
+<para>
+<indexterm role="concept">
+<primary>installing Exim</primary>
+<secondary><emphasis>info</emphasis> documentation</secondary>
+</indexterm>
+Not all systems use the GNU <emphasis>info</emphasis> system for documentation, and for this
+reason, the Texinfo source of Exim’s documentation is not included in the main
+distribution. Instead it is available separately from the FTP site (see section
+<xref linkend="SECTavail"/>).
+</para>
+<para>
+If you have defined INFO_DIRECTORY in <filename>Local/Makefile</filename> and the Texinfo
+source of the documentation is found in the source tree, running <literal>make
+install</literal> automatically builds the info files and installs them.
+</para>
+</section>
+<section id="SECID33">
+<title>Setting up the spool directory</title>
+<para>
+<indexterm role="concept">
+<primary>spool directory</primary>
+<secondary>creating</secondary>
+</indexterm>
+When it starts up, Exim tries to create its spool directory if it does not
+exist. The Exim uid and gid are used for the owner and group of the spool
+directory. Sub-directories are automatically created in the spool directory as
+necessary.
+</para>
+</section>
+<section id="SECID34">
+<title>Testing</title>
+<para>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>installation</secondary>
+</indexterm>
+Having installed Exim, you can check that the runtime configuration file is
+syntactically valid by running the following command, which assumes that the
+Exim binary directory is within your PATH environment variable:
+</para>
+<literallayout class="monospaced">
+exim -bV
+</literallayout>
+<para>
+If there are any errors in the configuration file, Exim outputs error messages.
+Otherwise it outputs the version number and build date,
+the DBM library that is being used, and information about which drivers and
+other optional code modules are included in the binary.
+Some simple routing tests can be done by using the address testing option. For
+example,
+</para>
+<literallayout>
+<literal>exim -bt</literal> <<emphasis>local username</emphasis>>
+</literallayout>
+<para>
+should verify that it recognizes a local mailbox, and
+</para>
+<literallayout>
+<literal>exim -bt</literal> <<emphasis>remote address</emphasis>>
+</literallayout>
+<para>
+a remote one. Then try getting it to deliver mail, both locally and remotely.
+This can be done by passing messages directly to Exim, without going through a
+user agent. For example:
+</para>
+<literallayout class="monospaced">
+exim -v postmaster@your.domain.example
+From: user@your.domain.example
+To: postmaster@your.domain.example
+Subject: Testing Exim
+
+This is a test message.
+^D
+</literallayout>
+<para>
+The <option>-v</option> option causes Exim to output some verification of what it is doing.
+In this case you should see copies of three log lines, one for the message’s
+arrival, one for its delivery, and one containing <quote>Completed</quote>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>problems with</secondary>
+</indexterm>
+If you encounter problems, look at Exim’s log files (<emphasis>mainlog</emphasis> and
+<emphasis>paniclog</emphasis>) to see if there is any relevant information there. Another source
+of information is running Exim with debugging turned on, by specifying the
+<option>-d</option> option. If a message is stuck on Exim’s spool, you can force a delivery
+with debugging turned on by a command of the form
+</para>
+<literallayout>
+<literal>exim -d -M</literal> <<emphasis>exim-message-id</emphasis>>
+</literallayout>
+<para>
+You must be root or an <quote>admin user</quote> in order to do this. The <option>-d</option> option
+produces rather a lot of output, but you can cut this down to specific areas.
+For example, if you use <option>-d-all+route</option> only the debugging information
+relevant to routing is included. (See the <option>-d</option> option in chapter
+<xref linkend="CHAPcommandline"/> for more details.)
+</para>
+<para>
+<indexterm role="concept">
+<primary><quote>sticky</quote> bit</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lock files</primary>
+</indexterm>
+One specific problem that has shown up on some sites is the inability to do
+local deliveries into a shared mailbox directory, because it does not have the
+<quote>sticky bit</quote> set on it. By default, Exim tries to create a lock file before
+writing to a mailbox file, and if it cannot create the lock file, the delivery
+is deferred. You can get round this either by setting the <quote>sticky bit</quote> on the
+directory, or by setting a specific group for local deliveries and allowing
+that group to create files in the directory (see the comments above the
+<command>local_delivery</command> transport in the default configuration file). Another
+approach is to configure Exim not to use lock files, but just to rely on
+<function>fcntl()</function> locking instead. However, you should do this only if all user
+agents also use <function>fcntl()</function> locking. For further discussion of locking issues,
+see chapter <xref linkend="CHAPappendfile"/>.
+</para>
+<para>
+One thing that cannot be tested on a system that is already running an MTA is
+the receipt of incoming SMTP mail on the standard SMTP port. However, the
+<option>-oX</option> option can be used to run an Exim daemon that listens on some other
+port, or <emphasis>inetd</emphasis> can be used to do this. The <option>-bh</option> option and the
+<emphasis>exim_checkaccess</emphasis> utility can be used to check out policy controls on
+incoming SMTP mail.
+</para>
+<para>
+Testing a new version on a system that is already running Exim can most easily
+be done by building a binary with a different CONFIGURE_FILE setting. From
+within the runtime configuration, all other file and directory names
+that Exim uses can be altered, in order to keep it entirely clear of the
+production version.
+</para>
+</section>
+<section id="SECID35">
+<title>Replacing another MTA with Exim</title>
+<para>
+<indexterm role="concept">
+<primary>replacing another MTA</primary>
+</indexterm>
+Building and installing Exim for the first time does not of itself put it in
+general use. The name by which the system’s MTA is called by mail user agents
+is either <filename>/usr/sbin/sendmail</filename>, or <filename>/usr/lib/sendmail</filename> (depending on the
+operating system), and it is necessary to make this name point to the <emphasis>exim</emphasis>
+binary in order to get the user agents to pass messages to Exim. This is
+normally done by renaming any existing file and making <filename>/usr/sbin/sendmail</filename>
+or <filename>/usr/lib/sendmail</filename>
+<indexterm role="concept">
+<primary>symbolic link</primary>
+<secondary>to <emphasis>exim</emphasis> binary</secondary>
+</indexterm>
+a symbolic link to the <emphasis>exim</emphasis> binary. It is a good idea to remove any setuid
+privilege and executable status from the old MTA. It is then necessary to stop
+and restart the mailer daemon, if one is running.
+</para>
+<para>
+<indexterm role="concept">
+<primary>FreeBSD, MTA indirection</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><filename>/etc/mail/mailer.conf</filename></primary>
+</indexterm>
+Some operating systems have introduced alternative ways of switching MTAs. For
+example, if you are running FreeBSD, you need to edit the file
+<filename>/etc/mail/mailer.conf</filename> instead of setting up a symbolic link as just
+described. A typical example of the contents of this file for running Exim is
+as follows:
+</para>
+<literallayout class="monospaced">
+sendmail /usr/exim/bin/exim
+send-mail /usr/exim/bin/exim
+mailq /usr/exim/bin/exim -bp
+newaliases /usr/bin/true
+</literallayout>
+<para>
+Once you have set up the symbolic link, or edited <filename>/etc/mail/mailer.conf</filename>,
+your Exim installation is <quote>live</quote>. Check it by sending a message from your
+favourite user agent.
+</para>
+<para>
+You should consider what to tell your users about the change of MTA. Exim may
+have different capabilities to what was previously running, and there are
+various operational differences such as the text of messages produced by
+command line options and in bounce messages. If you allow your users to make
+use of Exim’s filtering capabilities, you should make the document entitled
+<emphasis>Exim’s interface to mail filtering</emphasis> available to them.
+</para>
+</section>
+<section id="SECID36">
+<title>Upgrading Exim</title>
+<para>
+<indexterm role="concept">
+<primary>upgrading Exim</primary>
+</indexterm>
+If you are already running Exim on your host, building and installing a new
+version automatically makes it available to MUAs, or any other programs that
+call the MTA directly. However, if you are running an Exim daemon, you do need
+<indexterm role="concept">
+<primary>restart</primary>
+<secondary>on HUP signal</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>signal</primary>
+<secondary>HUP, to restart</secondary>
+</indexterm>
+to send it a HUP signal, to make it re-execute itself, and thereby pick up the
+new binary. You do not need to stop processing mail in order to install a new
+version of Exim. The install script does not modify an existing runtime
+configuration file.
+</para>
+</section>
+<section id="SECID37">
+<title>Stopping the Exim daemon on Solaris</title>
+<para>
+<indexterm role="concept">
+<primary>Solaris</primary>
+<secondary>stopping Exim on</secondary>
+</indexterm>
+The standard command for stopping the mailer daemon on Solaris is
+</para>
+<literallayout class="monospaced">
+/etc/init.d/sendmail stop
+</literallayout>
+<para>
+If <filename>/usr/lib/sendmail</filename> has been turned into a symbolic link, this script
+fails to stop Exim because it uses the command <emphasis>ps -e</emphasis> and greps the output
+for the text <quote>sendmail</quote>; this is not present because the actual program name
+(that is, <quote>exim</quote>) is given by the <emphasis>ps</emphasis> command with these options. A
+solution is to replace the line that finds the process id with something like
+</para>
+<literallayout class="monospaced">
+pid=`cat /var/spool/exim/exim-daemon.pid`
+</literallayout>
+<para>
+to obtain the daemon’s pid directly from the file that Exim saves it in.
+</para>
+<para>
+Note, however, that stopping the daemon does not <quote>stop Exim</quote>. Messages can
+still be received from local processes, and if automatic delivery is configured
+(the normal case), deliveries will still occur.
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPcommandline">
+<title>The Exim command line</title>
+<para>
+<indexterm role="concept" id="IIDclo1" class="startofrange">
+<primary>command line</primary>
+<secondary>options</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDclo2" class="startofrange">
+<primary>options</primary>
+<secondary>command line</secondary>
+</indexterm>
+Exim’s command line takes the standard Unix form of a sequence of options,
+each starting with a hyphen character, followed by a number of arguments. The
+options are compatible with the main options of Sendmail, and there are also
+some additional options, some of which are compatible with Smail 3. Certain
+combinations of options do not make sense, and provoke an error if used.
+The form of the arguments depends on which options are set.
+</para>
+<section id="SECID38">
+<title>Setting options by program name</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>mailq</emphasis></primary>
+</indexterm>
+If Exim is called under the name <emphasis>mailq</emphasis>, it behaves as if the option <option>-bp</option>
+were present before any other options.
+The <option>-bp</option> option requests a listing of the contents of the mail queue on the
+standard output.
+This feature is for compatibility with some systems that contain a command of
+that name in one of the standard libraries, symbolically linked to
+<filename>/usr/sbin/sendmail</filename> or <filename>/usr/lib/sendmail</filename>.
+</para>
+<para>
+<indexterm role="concept">
+<primary><emphasis>rsmtp</emphasis></primary>
+</indexterm>
+If Exim is called under the name <emphasis>rsmtp</emphasis> it behaves as if the option <option>-bS</option>
+were present before any other options, for compatibility with Smail. The
+<option>-bS</option> option is used for reading in a number of messages in batched SMTP
+format.
+</para>
+<para>
+<indexterm role="concept">
+<primary><emphasis>rmail</emphasis></primary>
+</indexterm>
+If Exim is called under the name <emphasis>rmail</emphasis> it behaves as if the <option>-i</option> and
+<option>-oee</option> options were present before any other options, for compatibility with
+Smail. The name <emphasis>rmail</emphasis> is used as an interface by some UUCP systems.
+</para>
+<para>
+<indexterm role="concept">
+<primary><emphasis>runq</emphasis></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue runner</primary>
+</indexterm>
+If Exim is called under the name <emphasis>runq</emphasis> it behaves as if the option <option>-q</option>
+were present before any other options, for compatibility with Smail. The <option>-q</option>
+option causes a single queue runner process to be started.
+</para>
+<para>
+<indexterm role="concept">
+<primary><emphasis>newaliases</emphasis></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>alias file</primary>
+<secondary>building</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary>calling Exim as <emphasis>newaliases</emphasis></secondary>
+</indexterm>
+If Exim is called under the name <emphasis>newaliases</emphasis> it behaves as if the option
+<option>-bi</option> were present before any other options, for compatibility with Sendmail.
+This option is used for rebuilding Sendmail’s alias file. Exim does not have
+the concept of a single alias file, but can be configured to run a given
+command if called with the <option>-bi</option> option.
+</para>
+</section>
+<section id="SECTtrustedadmin">
+<title>Trusted and admin users</title>
+<para>
+Some Exim options are available only to <emphasis>trusted users</emphasis> and others are
+available only to <emphasis>admin users</emphasis>. In the description below, the phrases <quote>Exim
+user</quote> and <quote>Exim group</quote> mean the user and group defined by EXIM_USER and
+EXIM_GROUP in <filename>Local/Makefile</filename> or set by the <option>exim_user</option> and
+<option>exim_group</option> options. These do not necessarily have to use the name <quote>exim</quote>.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>trusted users</primary>
+<secondary>definition of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>user</primary>
+<secondary>trusted definition of</secondary>
+</indexterm>
+The trusted users are root, the Exim user, any user listed in the
+<option>trusted_users</option> configuration option, and any user whose current group or any
+supplementary group is one of those listed in the <option>trusted_groups</option>
+configuration option. Note that the Exim group is not automatically trusted.
+</para>
+<para>
+<indexterm role="concept">
+<primary><quote>From</quote> line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope from</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope sender</primary>
+</indexterm>
+Trusted users are always permitted to use the <option>-f</option> option or a leading
+<quote>From </quote> line to specify the envelope sender of a message that is passed to
+Exim through the local interface (see the <option>-bm</option> and <option>-f</option> options below).
+See the <option>untrusted_set_sender</option> option for a way of permitting non-trusted
+users to set envelope senders.
+</para>
+<para>
+<indexterm role="concept">
+<primary><emphasis>From:</emphasis> header line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>Sender:</emphasis> header line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>From:</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>Sender:</secondary>
+</indexterm>
+For a trusted user, there is never any check on the contents of the <emphasis>From:</emphasis>
+header line, and a <emphasis>Sender:</emphasis> line is never added. Furthermore, any existing
+<emphasis>Sender:</emphasis> line in incoming local (non-TCP/IP) messages is not removed.
+</para>
+<para>
+Trusted users may also specify a host name, host address, interface address,
+protocol name, ident value, and authentication data when submitting a message
+locally. Thus, they are able to insert messages into Exim’s queue locally that
+have the characteristics of messages received from a remote host. Untrusted
+users may in some circumstances use <option>-f</option>, but can never set the other values
+that are available to trusted users.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>user</primary>
+<secondary>admin definition of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>admin user</primary>
+<secondary>definition of</secondary>
+</indexterm>
+The admin users are root, the Exim user, and any user that is a member of the
+Exim group or of any group listed in the <option>admin_groups</option> configuration option.
+The current group does not have to be one of these groups.
+</para>
+<para>
+Admin users are permitted to list the queue, and to carry out certain
+operations on messages, for example, to force delivery failures. It is also
+necessary to be an admin user in order to see the full information provided by
+the Exim monitor, and full debugging output.
+</para>
+<para>
+By default, the use of the <option>-M</option>, <option>-q</option>, <option>-R</option>, and <option>-S</option> options to cause
+Exim to attempt delivery of messages on its queue is restricted to admin users.
+However, this restriction can be relaxed by setting the <option>prod_requires_admin</option>
+option false (that is, specifying <option>no_prod_requires_admin</option>).
+</para>
+<para>
+Similarly, the use of the <option>-bp</option> option to list all the messages in the queue
+is restricted to admin users unless <option>queue_list_requires_admin</option> is set
+false.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+<emphasis role="bold">Warning</emphasis>: If you configure your system so that admin users are able to
+edit Exim’s configuration file, you are giving those users an easy way of
+getting root. There is further discussion of this issue at the start of chapter
+<xref linkend="CHAPconf"/>.
+</para>
+</section>
+<section id="SECID39">
+<title>Command line options</title>
+<para>
+Exim’s command line options are described in alphabetical order below. If none
+of the options that specifies a specific action (such as starting the daemon or
+a queue runner, or testing an address, or receiving a message in a specific
+format, or listing the queue) are present, and there is at least one argument
+on the command line, <option>-bm</option> (accept a local message on the standard input,
+with the arguments specifying the recipients) is assumed. Otherwise, Exim
+outputs a brief message about itself and exits.
+</para>
+<!-- === Start of command line options === -->
+<variablelist>
+<varlistentry>
+<term><option>--</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary>--</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary>command line; terminating</secondary>
+</indexterm>
+This is a pseudo-option whose only purpose is to terminate the options and
+therefore to cause subsequent command line items to be treated as arguments
+rather than options, even if they begin with hyphens.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>--help</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>--help</option></primary>
+</indexterm>
+This option causes Exim to output a few sentences stating what it is.
+The same output is generated if the Exim binary is called with no options and
+no arguments.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>--version</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>--version</option></primary>
+</indexterm>
+This option is an alias for <option>-bV</option> and causes version information to be
+displayed.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Ac</option></term>
+<term><option>-Am</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Ac</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-Am</option></primary>
+</indexterm>
+These options are used by Sendmail for selecting configuration files and are
+ignored by Exim.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-B</option><<emphasis>type</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-B</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>8-bit characters</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary>8-bit characters</secondary>
+</indexterm>
+This is a Sendmail option for selecting 7 or 8 bit processing. Exim is 8-bit
+clean; it ignores this option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bd</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bd</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>daemon</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>listener</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue runner</primary>
+</indexterm>
+This option runs Exim as a daemon, awaiting incoming SMTP connections. Usually
+the <option>-bd</option> option is combined with the <option>-q</option><<emphasis>time</emphasis>> option, to specify
+that the daemon should also initiate periodic queue runs.
+</para>
+<para>
+The <option>-bd</option> option can be used only by an admin user. If either of the <option>-d</option>
+(debugging) or <option>-v</option> (verifying) options are set, the daemon does not
+disconnect from the controlling terminal. When running this way, it can be
+stopped by pressing ctrl-C.
+</para>
+<para>
+By default, Exim listens for incoming connections to the standard SMTP port on
+all the host’s running interfaces. However, it is possible to listen on other
+ports, on multiple ports, and only on specific interfaces. Chapter
+<xref linkend="CHAPinterfaces"/> contains a description of the options that control this.
+</para>
+<para>
+When a listening daemon
+<indexterm role="concept">
+<primary>daemon</primary>
+<secondary>process id (pid)</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>pid (process id)</primary>
+<secondary>of daemon</secondary>
+</indexterm>
+is started without the use of <option>-oX</option> (that is, without overriding the normal
+configuration), it writes its process id to a file called <filename>exim-daemon.pid</filename>
+in Exim’s spool directory. This location can be overridden by setting
+PID_FILE_PATH in <filename>Local/Makefile</filename>. The file is written while Exim is still
+running as root.
+</para>
+<para>
+When <option>-oX</option> is used on the command line to start a listening daemon, the
+process id is not written to the normal pid file path. However, <option>-oP</option> can be
+used to specify a path on the command line if a pid file is required.
+</para>
+<para>
+The SIGHUP signal
+<indexterm role="concept">
+<primary>SIGHUP</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>restart</primary>
+<secondary>on HUP signal</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>signal</primary>
+<secondary>HUP, to restart</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>daemon</primary>
+<secondary>restarting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>signal</primary>
+<secondary>to reload configuration</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>daemon</primary>
+<secondary>reload configuration</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>reload</primary>
+<secondary>configuration</secondary>
+</indexterm>
+can be used to cause the daemon to re-execute itself. This should be done
+whenever Exim’s configuration file, or any file that is incorporated into it by
+means of the <option>.include</option> facility, is changed, and also whenever a new version
+of Exim is installed. It is not necessary to do this when other files that are
+referenced from the configuration (for example, alias files) are changed,
+because these are reread each time they are used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bdf</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bdf</option></primary>
+</indexterm>
+This option has the same effect as <option>-bd</option> except that it never disconnects
+from the controlling terminal, even when no debugging is specified.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-be</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-be</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>string expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>testing</secondary>
+</indexterm>
+Run Exim in expansion testing mode. Exim discards its root privilege, to
+prevent ordinary users from using this mode to read otherwise inaccessible
+files. If no arguments are given, Exim runs interactively, prompting for lines
+of data. Otherwise, it processes each argument in turn.
+</para>
+<para>
+If Exim was built with USE_READLINE=yes in <filename>Local/Makefile</filename>, it tries
+to load the <option>libreadline</option> library dynamically whenever the <option>-be</option> option is
+used without command line arguments. If successful, it uses the <function>readline()</function>
+function, which provides extensive line-editing facilities, for reading the
+test data. A line history is supported.
+</para>
+<para>
+Long expansion expressions can be split over several lines by using backslash
+continuations. As in Exim’s runtime configuration, white space at the start of
+continuation lines is ignored. Each argument or data line is passed through the
+string expansion mechanism, and the result is output. Variable values from the
+configuration file (for example, <varname>$qualify_domain</varname>) are available, but no
+message-specific values (such as <varname>$message_exim_id</varname>) are set, because no message
+is being processed (but see <option>-bem</option> and <option>-Mset</option>).
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: If you use this mechanism to test lookups, and you change the data
+files or databases you are using, you must exit and restart Exim before trying
+the same lookup again. Otherwise, because each Exim process caches the results
+of lookups, you will just get the same result as before.
+</para>
+<para>
+Macro processing is done on lines before string-expansion: new macros can be
+defined and macros will be expanded.
+Because macros in the config file are often used for secrets, those are only
+available to admin users.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bem</option> <<emphasis>filename</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bem</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>string expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>testing</secondary>
+</indexterm>
+This option operates like <option>-be</option> except that it must be followed by the name
+of a file. For example:
+</para>
+<literallayout class="monospaced">
+exim -bem /tmp/testmessage
+</literallayout>
+<para>
+The file is read as a message (as if receiving a locally-submitted non-SMTP
+message) before any of the test expansions are done. Thus, message-specific
+variables such as <varname>$message_size</varname> and <varname>$header_from:</varname> are available. However,
+no <emphasis>Received:</emphasis> header is added to the message. If the <option>-t</option> option is set,
+recipients are read from the headers in the normal way, and are shown in the
+<varname>$recipients</varname> variable. Note that recipients cannot be given on the command
+line, because further arguments are taken as strings to expand (just like
+<option>-be</option>).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bF</option> <<emphasis>filename</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bF</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>system filter</primary>
+<secondary>testing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>system filter</secondary>
+</indexterm>
+This option is the same as <option>-bf</option> except that it assumes that the filter being
+tested is a system filter. The additional commands that are available only in
+system filters are recognized.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bf</option> <<emphasis>filename</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bf</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>testing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>filter file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>forward file</primary>
+<secondary>testing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>forward file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary>testing</secondary>
+</indexterm>
+This option runs Exim in user filter testing mode; the file is the filter file
+to be tested, and a test message must be supplied on the standard input. If
+there are no message-dependent tests in the filter, an empty file can be
+supplied.
+</para>
+<para>
+If you want to test a system filter file, use <option>-bF</option> instead of <option>-bf</option>. You
+can use both <option>-bF</option> and <option>-bf</option> on the same command, in order to test a system
+filter and a user filter in the same run. For example:
+</para>
+<literallayout class="monospaced">
+exim -bF /system/filter -bf /user/filter </test/message
+</literallayout>
+<para>
+This is helpful when the system filter adds header lines or sets filter
+variables that are used by the user filter.
+</para>
+<para>
+If the test filter file does not begin with one of the special lines
+</para>
+<literallayout class="monospaced">
+# Exim filter
+# Sieve filter
+</literallayout>
+<para>
+it is taken to be a normal <filename>.forward</filename> file, and is tested for validity under
+that interpretation. See sections <xref linkend="SECTitenonfilred"/> to
+<xref linkend="SECTspecitredli"/> for a description of the possible contents of non-filter
+redirection lists.
+</para>
+<para>
+The result of an Exim command that uses <option>-bf</option>, provided no errors are
+detected, is a list of the actions that Exim would try to take if presented
+with the message for real. More details of filter testing are given in the
+separate document entitled <emphasis>Exim’s interfaces to mail filtering</emphasis>.
+</para>
+<para>
+When testing a filter file,
+<indexterm role="concept">
+<primary><quote>From</quote> line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope from</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope sender</primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-f</option></primary>
+<secondary>for filter testing</secondary>
+</indexterm>
+the envelope sender can be set by the <option>-f</option> option,
+or by a <quote>From </quote> line at the start of the test message. Various parameters
+that would normally be taken from the envelope recipient address of the message
+can be set by means of additional command line options (see the next four
+options).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bfd</option> <<emphasis>domain</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bfd</option></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$qualify_domain</varname></primary>
+</indexterm>
+This sets the domain of the recipient address when a filter file is being
+tested by means of the <option>-bf</option> option. The default is the value of
+<varname>$qualify_domain</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bfl</option> <<emphasis>local part</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bfl</option></primary>
+</indexterm>
+This sets the local part of the recipient address when a filter file is being
+tested by means of the <option>-bf</option> option. The default is the username of the
+process that calls Exim. A local part should be specified with any prefix or
+suffix stripped, because that is how it appears to the filter when a message is
+actually being delivered.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bfp</option> <<emphasis>prefix</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bfp</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>affix</primary>
+<secondary>filter testing</secondary>
+</indexterm>
+This sets the prefix of the local part of the recipient address when a filter
+file is being tested by means of the <option>-bf</option> option. The default is an empty
+prefix.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bfs</option> <<emphasis>suffix</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bfs</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>affix</primary>
+<secondary>filter testing</secondary>
+</indexterm>
+This sets the suffix of the local part of the recipient address when a filter
+file is being tested by means of the <option>-bf</option> option. The default is an empty
+suffix.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bh</option> <<emphasis>IP address</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bh</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>incoming SMTP</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>testing incoming</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>relay control</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>relaying</primary>
+<secondary>testing configuration</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>policy control</primary>
+<secondary>testing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>debugging</primary>
+<secondary><option>-bh</option> option</secondary>
+</indexterm>
+This option runs a fake SMTP session as if from the given IP address, using the
+standard input and output. The IP address may include a port number at the end,
+after a full stop. For example:
+</para>
+<literallayout class="monospaced">
+exim -bh 10.9.8.7.1234
+exim -bh fe80::a00:20ff:fe86:a061.5678
+</literallayout>
+<para>
+When an IPv6 address is given, it is converted into canonical form. In the case
+of the second example above, the value of <varname>$sender_host_address</varname> after
+conversion to the canonical form is
+<literal>fe80:0000:0000:0a00:20ff:fe86:a061.5678</literal>.
+</para>
+<para>
+Comments as to what is going on are written to the standard error file. These
+include lines beginning with <quote>LOG</quote> for anything that would have been logged.
+This facility is provided for testing configuration options for incoming
+messages, to make sure they implement the required policy. For example, you can
+test your relay controls using <option>-bh</option>.
+</para>
+<para>
+<emphasis role="bold">Warning 1</emphasis>:
+<indexterm role="concept">
+<primary>RFC 1413</primary>
+</indexterm>
+You can test features of the configuration that rely on ident (RFC 1413)
+information by using the <option>-oMt</option> option. However, Exim cannot actually perform
+an ident callout when testing using <option>-bh</option> because there is no incoming SMTP
+connection.
+</para>
+<para>
+<emphasis role="bold">Warning 2</emphasis>: Address verification callouts (see section <xref linkend="SECTcallver"/>)
+are also skipped when testing using <option>-bh</option>. If you want these callouts to
+occur, use <option>-bhc</option> instead.
+</para>
+<para>
+Messages supplied during the testing session are discarded, and nothing is
+written to any of the real log files. There may be pauses when DNS (and other)
+lookups are taking place, and of course these may time out. The <option>-oMi</option> option
+can be used to specify a specific IP interface and port if this is important,
+and <option>-oMaa</option> and <option>-oMai</option> can be used to set parameters as if the SMTP
+session were authenticated.
+</para>
+<para>
+The <emphasis>exim_checkaccess</emphasis> utility is a <quote>packaged</quote> version of <option>-bh</option> whose
+output just states whether a given recipient address from a given host is
+acceptable or not. See section <xref linkend="SECTcheckaccess"/>.
+</para>
+<para>
+Features such as authentication and encryption, where the client input is not
+plain text, cannot easily be tested with <option>-bh</option>. Instead, you should use a
+specialized SMTP test program such as
+<emphasis role="bold"><ulink url="https://www.jetmore.org/john/code/swaks/">swaks</ulink></emphasis>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bhc</option> <<emphasis>IP address</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bhc</option></primary>
+</indexterm>
+This option operates in the same way as <option>-bh</option>, except that address
+verification callouts are performed if required. This includes consulting and
+updating the callout cache database.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bi</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bi</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>alias file</primary>
+<secondary>building</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>building alias file</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary><option>-bi</option> option</secondary>
+</indexterm>
+Sendmail interprets the <option>-bi</option> option as a request to rebuild its alias file.
+Exim does not have the concept of a single alias file, and so it cannot mimic
+this behaviour. However, calls to <filename>/usr/lib/sendmail</filename> with the <option>-bi</option> option
+tend to appear in various scripts such as NIS make files, so the option must be
+recognized.
+</para>
+<para>
+If <option>-bi</option> is encountered, the command specified by the <option>bi_command</option>
+configuration option is run, under the uid and gid of the caller of Exim. If
+the <option>-oA</option> option is used, its value is passed to the command as an argument.
+The command set by <option>bi_command</option> may not contain arguments. The command can
+use the <emphasis>exim_dbmbuild</emphasis> utility, or some other means, to rebuild alias files
+if this is required. If the <option>bi_command</option> option is not set, calling Exim with
+<option>-bi</option> is a no-op.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bI:help</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bI:help</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>querying exim information</primary>
+</indexterm>
+We shall provide various options starting <literal>-bI:</literal> for querying Exim for
+information. The output of many of these will be intended for machine
+consumption. This one is not. The <option>-bI:help</option> option asks Exim for a
+synopsis of supported options beginning <literal>-bI:</literal>. Use of any of these
+options shall cause Exim to exit after producing the requested output.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bI:dscp</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bI:dscp</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>DSCP</primary>
+<secondary>values</secondary>
+</indexterm>
+This option causes Exim to emit an alphabetically sorted list of all
+recognised DSCP names.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bI:sieve</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bI:sieve</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary>capabilities</secondary>
+</indexterm>
+This option causes Exim to emit an alphabetically sorted list of all supported
+Sieve protocol extensions on stdout, one per line. This is anticipated to be
+useful for ManageSieve (RFC 5804) implementations, in providing that protocol’s
+<literal>SIEVE</literal> capability response line. As the precise list may depend upon
+compile-time build options, which this option will adapt to, this is the only
+way to guarantee a correct response.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bm</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bm</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>local message reception</primary>
+</indexterm>
+This option runs an Exim receiving process that accepts an incoming,
+locally-generated message on the standard input. The recipients are given as the
+command arguments (except when <option>-t</option> is also present – see below). Each
+argument can be a comma-separated list of RFC 2822 addresses. This is the
+default option for selecting the overall action of an Exim call; it is assumed
+if no other conflicting option is present.
+</para>
+<para>
+If any addresses in the message are unqualified (have no domain), they are
+qualified by the values of the <option>qualify_domain</option> or <option>qualify_recipient</option>
+options, as appropriate. The <option>-bnq</option> option (see below) provides a way of
+suppressing this for special cases.
+</para>
+<para>
+Policy checks on the contents of local messages can be enforced by means of
+the non-SMTP ACL. See chapter <xref linkend="CHAPACL"/> for details.
+</para>
+<para>
+<indexterm role="concept">
+<primary>return code</primary>
+<secondary>for <option>-bm</option></secondary>
+</indexterm>
+The return code is zero if the message is successfully accepted. Otherwise, the
+action is controlled by the <option>-oe</option><emphasis>x</emphasis> option setting – see below.
+</para>
+<para>
+The format
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>format</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>format</primary>
+<secondary>message</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><quote>From</quote> line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>UUCP</primary>
+<secondary><quote>From</quote> line</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary><quote>From</quote> line</secondary>
+</indexterm>
+of the message must be as defined in RFC 2822, except that, for
+compatibility with Sendmail and Smail, a line in one of the forms
+</para>
+<literallayout class="monospaced">
+From sender Fri Jan 5 12:55 GMT 1997
+From sender Fri, 5 Jan 97 12:55:01
+</literallayout>
+<para>
+(with the weekday optional, and possibly with additional text after the date)
+is permitted to appear at the start of the message. There appears to be no
+authoritative specification of the format of this line. Exim recognizes it by
+matching against the regular expression defined by the <option>uucp_from_pattern</option>
+option, which can be changed if necessary.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>-f</option></primary>
+<secondary>overriding <quote>From</quote> line</secondary>
+</indexterm>
+The specified sender is treated as if it were given as the argument to the
+<option>-f</option> option, but if a <option>-f</option> option is also present, its argument is used in
+preference to the address taken from the message. The caller of Exim must be a
+trusted user for the sender of a message to be set in this way.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bmalware</option> <<emphasis>filename</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bmalware</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>,</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>malware scan test</primary>
+</indexterm>
+This debugging option causes Exim to scan the given file or directory
+(depending on the used scanner interface),
+using the malware scanning framework. The option of <option>av_scanner</option> influences
+this option, so if <option>av_scanner</option>’s value is dependent upon an expansion then
+the expansion should have defaults which apply to this invocation. ACLs are
+not invoked, so if <option>av_scanner</option> references an ACL variable then that variable
+will never be populated and <option>-bmalware</option> will fail.
+</para>
+<para>
+Exim will have changed working directory before resolving the filename, so
+using fully qualified pathnames is advisable. Exim will be running as the Exim
+user when it tries to open the file, rather than as the invoking user.
+This option requires admin privileges.
+</para>
+<para>
+The <option>-bmalware</option> option will not be extended to be more generally useful,
+there are better tools for file-scanning. This option exists to help
+administrators verify their Exim and AV scanner configuration.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bnq</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bnq</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>address qualification, suppressing</primary>
+</indexterm>
+By default, Exim automatically qualifies unqualified addresses (those
+without domains) that appear in messages that are submitted locally (that
+is, not over TCP/IP). This qualification applies both to addresses in
+envelopes, and addresses in header lines. Sender addresses are qualified using
+<option>qualify_domain</option>, and recipient addresses using <option>qualify_recipient</option> (which
+defaults to the value of <option>qualify_domain</option>).
+</para>
+<para>
+Sometimes, qualification is not wanted. For example, if <option>-bS</option> (batch SMTP) is
+being used to re-submit messages that originally came from remote hosts after
+content scanning, you probably do not want to qualify unqualified addresses in
+header lines. (Such lines will be present only if you have not enabled a header
+syntax check in the appropriate ACL.)
+</para>
+<para>
+The <option>-bnq</option> option suppresses all qualification of unqualified addresses in
+messages that originate on the local host. When this is used, unqualified
+addresses in the envelope provoke errors (causing message rejection) and
+unqualified addresses in header lines are left alone.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bP</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bP</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>configuration options</primary>
+<secondary>extracting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary>configuration – extracting</secondary>
+</indexterm>
+If this option is given with no arguments, it causes the values of all Exim’s
+main configuration options to be written to the standard output. The values
+of one or more specific options can be requested by giving their names as
+arguments, for example:
+</para>
+<literallayout class="monospaced">
+exim -bP qualify_domain hold_domains
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>hiding configuration option values</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>configuration options</primary>
+<secondary>hiding value of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary>hiding value of</secondary>
+</indexterm>
+However, any option setting that is preceded by the word <quote>hide</quote> in the
+configuration file is not shown in full, except to an admin user. For other
+users, the output is as in this example:
+</para>
+<literallayout class="monospaced">
+mysql_servers = <value not displayable>
+</literallayout>
+<para>
+If <option>config</option> is given as an argument, the config is
+output, as it was parsed, any include file resolved, any comment removed.
+</para>
+<para>
+If <option>config_file</option> is given as an argument, the name of the runtime
+configuration file is output. (<option>configure_file</option> works too, for
+backward compatibility.)
+If a list of configuration files was supplied, the value that is output here
+is the name of the file that was actually used.
+</para>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary>hiding name of</secondary>
+</indexterm>
+If the <option>-n</option> flag is given, then for most modes of <option>-bP</option> operation the
+name will not be output.
+</para>
+<para>
+<indexterm role="concept">
+<primary>daemon</primary>
+<secondary>process id (pid)</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>pid (process id)</primary>
+<secondary>of daemon</secondary>
+</indexterm>
+If <option>log_file_path</option> or <option>pid_file_path</option> are given, the names of the
+directories where log files and daemon pid files are written are output,
+respectively. If these values are unset, log files are written in a
+sub-directory of the spool directory called <option>log</option>, and the pid file is
+written directly into the spool directory.
+</para>
+<para>
+If <option>-bP</option> is followed by a name preceded by <literal>+</literal>, for example,
+</para>
+<literallayout class="monospaced">
+exim -bP +local_domains
+</literallayout>
+<para>
+it searches for a matching named list of any type (domain, host, address, or
+local part) and outputs what it finds.
+</para>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary>router – extracting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary>transport – extracting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary>authenticator – extracting</secondary>
+</indexterm>
+If one of the words <option>router</option>, <option>transport</option>, or <option>authenticator</option> is given,
+followed by the name of an appropriate driver instance, the option settings for
+that driver are output. For example:
+</para>
+<literallayout class="monospaced">
+exim -bP transport local_delivery
+</literallayout>
+<para>
+The generic driver options are output first, followed by the driver’s private
+options. A list of the names of drivers of a particular type can be obtained by
+using one of the words <option>router_list</option>, <option>transport_list</option>, or
+<option>authenticator_list</option>, and a complete list of all drivers with their option
+settings can be obtained by using <option>routers</option>, <option>transports</option>, or
+<option>authenticators</option>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>environment</primary>
+</indexterm>
+If <option>environment</option> is given as an argument, the set of environment
+variables is output, line by line. Using the <option>-n</option> flag suppresses the value of the
+variables.
+</para>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary>macro – extracting</secondary>
+</indexterm>
+If invoked by an admin user, then <option>macro</option>, <option>macro_list</option> and <option>macros</option>
+are available, similarly to the drivers. Because macros are sometimes used
+for storing passwords, this option is restricted.
+The output format is one item per line.
+For the "-bP macro <name>" form, if no such macro is found
+the exit status will be nonzero.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bp</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bp</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>listing messages in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>listing</primary>
+<secondary>messages in the queue</secondary>
+</indexterm>
+This option requests a listing of the contents of the mail queue on the
+standard output. If the <option>-bp</option> option is followed by a list of message ids,
+just those messages are listed. By default, this option can be used only by an
+admin user. However, the <option>queue_list_requires_admin</option> option can be set false
+to allow any user to see the queue.
+</para>
+<para>
+Each message in the queue is displayed as in the following example:
+</para>
+<literallayout class="monospaced">
+25m 2.9K 0t5C6f-0000c8-00 <alice@wonderland.fict.example>
+ red.king@looking-glass.fict.example
+ <other addresses>
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>size in queue listing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>size</primary>
+<secondary>of message</secondary>
+</indexterm>
+The first line contains the length of time the message has been in the queue
+(in this case 25 minutes), the size of the message (2.9K), the unique local
+identifier for the message, and the message sender, as contained in the
+envelope. For bounce messages, the sender address is empty, and appears as
+<quote><></quote>. If the message was submitted locally by an untrusted user who overrode
+the default sender address, the user’s login name is shown in parentheses
+before the sender address.
+</para>
+<para>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>in queue listing</secondary>
+</indexterm>
+If the message is frozen (attempts to deliver it are suspended) then the text
+<quote>*** frozen ***</quote> is displayed at the end of this line.
+</para>
+<para>
+The recipients of the message (taken from the envelope, not the headers) are
+displayed on subsequent lines. Those addresses to which the message has already
+been delivered are marked with the letter D. If an original address gets
+expanded into several addresses via an alias or forward file, the original is
+displayed with a D only when deliveries for all of its child addresses are
+complete.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bpa</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bpa</option></primary>
+</indexterm>
+This option operates like <option>-bp</option>, but in addition it shows delivered addresses
+that were generated from the original top level address(es) in each message by
+alias or forwarding operations. These addresses are flagged with <quote>+D</quote> instead
+of just <quote>D</quote>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bpc</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bpc</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>count of messages on</secondary>
+</indexterm>
+This option counts the number of messages in the queue, and writes the total
+to the standard output. It is restricted to admin users, unless
+<option>queue_list_requires_admin</option> is set false.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bpr</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bpr</option></primary>
+</indexterm>
+This option operates like <option>-bp</option>, but the output is not sorted into
+chronological order of message arrival. This can speed it up when there are
+lots of messages in the queue, and is particularly useful if the output is
+going to be post-processed in a way that doesn’t need the sorting.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bpra</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bpra</option></primary>
+</indexterm>
+This option is a combination of <option>-bpr</option> and <option>-bpa</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bpru</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bpru</option></primary>
+</indexterm>
+This option is a combination of <option>-bpr</option> and <option>-bpu</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bpu</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bpu</option></primary>
+</indexterm>
+This option operates like <option>-bp</option> but shows only undelivered top-level
+addresses for each message displayed. Addresses generated by aliasing or
+forwarding are not shown, unless the message was deferred after processing by a
+router with the <option>one_time</option> option set.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-brt</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-brt</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>retry configuration</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>configuration testing</secondary>
+</indexterm>
+This option is for testing retry rules, and it must be followed by up to three
+arguments. It causes Exim to look for a retry rule that matches the values
+and to write it to the standard output. For example:
+</para>
+<literallayout class="monospaced">
+exim -brt bach.comp.mus.example
+Retry rule: *.comp.mus.example F,2h,15m; F,4d,30m;
+</literallayout>
+<para>
+See chapter <xref linkend="CHAPretry"/> for a description of Exim’s retry rules. The first
+argument, which is required, can be a complete address in the form
+<emphasis>local_part@domain</emphasis>, or it can be just a domain name. If the second argument
+contains a dot, it is interpreted as an optional second domain name; if no
+retry rule is found for the first argument, the second is tried. This ties in
+with Exim’s behaviour when looking for retry rules for remote hosts – if no
+rule is found that matches the host, one that matches the mail domain is
+sought. Finally, an argument that is the name of a specific delivery error, as
+used in setting up retry rules, can be given. For example:
+</para>
+<literallayout class="monospaced">
+exim -brt haydn.comp.mus.example quota_3d
+Retry rule: *@haydn.comp.mus.example quota_3d F,1h,15m
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-brw</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-brw</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>rewriting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>testing</secondary>
+</indexterm>
+This option is for testing address rewriting rules, and it must be followed by
+a single argument, consisting of either a local part without a domain, or a
+complete address with a fully qualified domain. Exim outputs how this address
+would be rewritten for each possible place it might appear. See chapter
+<xref linkend="CHAPrewrite"/> for further details.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bS</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bS</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>batched incoming</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>batched SMTP input</primary>
+</indexterm>
+This option is used for batched SMTP input, which is an alternative interface
+for non-interactive local message submission. A number of messages can be
+submitted in a single run. However, despite its name, this is not really SMTP
+input. Exim reads each message’s envelope from SMTP commands on the standard
+input, but generates no responses. If the caller is trusted, or
+<option>untrusted_set_sender</option> is set, the senders in the SMTP MAIL commands are
+believed; otherwise the sender is always the caller of Exim.
+</para>
+<para>
+The message itself is read from the standard input, in SMTP format (leading
+dots doubled), terminated by a line containing just a single dot. An error is
+provoked if the terminating dot is missing. A further message may then follow.
+</para>
+<para>
+As for other local message submissions, the contents of incoming batch SMTP
+messages can be checked using the non-SMTP ACL (see chapter <xref linkend="CHAPACL"/>).
+Unqualified addresses are automatically qualified using <option>qualify_domain</option> and
+<option>qualify_recipient</option>, as appropriate, unless the <option>-bnq</option> option is used.
+</para>
+<para>
+Some other SMTP commands are recognized in the input. HELO and EHLO act
+as RSET; VRFY, EXPN, ETRN, and HELP act as NOOP;
+QUIT quits, ignoring the rest of the standard input.
+</para>
+<para>
+<indexterm role="concept">
+<primary>return code</primary>
+<secondary>for <option>-bS</option></secondary>
+</indexterm>
+If any error is encountered, reports are written to the standard output and
+error streams, and Exim gives up immediately. The return code is 0 if no error
+was detected; it is 1 if one or more messages were accepted before the error
+was detected; otherwise it is 2.
+</para>
+<para>
+More details of input using batched SMTP are given in section
+<xref linkend="SECTincomingbatchedSMTP"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bs</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bs</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>local input</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local SMTP input</primary>
+</indexterm>
+This option causes Exim to accept one or more messages by reading SMTP commands
+on the standard input, and producing SMTP replies on the standard output. SMTP
+policy controls, as defined in ACLs (see chapter <xref linkend="CHAPACL"/>) are applied.
+Some user agents use this interface as a way of passing locally-generated
+messages to the MTA.
+</para>
+<para>
+In
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>source of</secondary>
+</indexterm>
+this usage, if the caller of Exim is trusted, or <option>untrusted_set_sender</option> is
+set, the senders of messages are taken from the SMTP MAIL commands.
+Otherwise the content of these commands is ignored and the sender is set up as
+the calling user. Unqualified addresses are automatically qualified using
+<option>qualify_domain</option> and <option>qualify_recipient</option>, as appropriate, unless the
+<option>-bnq</option> option is used.
+</para>
+<para>
+<indexterm role="concept">
+<primary>inetd</primary>
+</indexterm>
+The
+<option>-bs</option> option is also used to run Exim from <emphasis>inetd</emphasis>, as an alternative to
+using a listening daemon. Exim can distinguish the two cases by checking
+whether the standard input is a TCP/IP socket. When Exim is called from
+<emphasis>inetd</emphasis>, the source of the mail is assumed to be remote, and the comments
+above concerning senders and qualification do not apply. In this situation,
+Exim behaves in exactly the same way as it does when receiving a message via
+the listening daemon.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bt</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bt</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>addresses</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address</primary>
+<secondary>testing</secondary>
+</indexterm>
+This option runs Exim in address testing mode, in which each argument is taken
+as a recipient address to be tested for deliverability. The results are
+written to the standard output. If a test fails, and the caller is not an admin
+user, no details of the failure are output, because these might contain
+sensitive information such as usernames and passwords for database lookups.
+</para>
+<para>
+If no arguments are given, Exim runs in an interactive manner, prompting with a
+right angle bracket for addresses to be tested.
+</para>
+<para>
+Unlike the <option>-be</option> test option, you cannot arrange for Exim to use the
+<function>readline()</function> function, because it is running as <emphasis>root</emphasis> and there are
+security issues.
+</para>
+<para>
+Each address is handled as if it were the recipient address of a message
+(compare the <option>-bv</option> option). It is passed to the routers and the result is
+written to the standard output. However, any router that has
+<option>no_address_test</option> set is bypassed. This can make <option>-bt</option> easier to use for
+genuine routing tests if your first router passes everything to a scanner
+program.
+</para>
+<para>
+<indexterm role="concept">
+<primary>return code</primary>
+<secondary>for <option>-bt</option></secondary>
+</indexterm>
+The return code is 2 if any address failed outright; it is 1 if no address
+failed outright but at least one could not be resolved for some reason. Return
+code 0 is given only when all addresses succeed.
+</para>
+<para>
+<indexterm role="concept">
+<primary>duplicate addresses</primary>
+</indexterm>
+<emphasis role="bold">Note</emphasis>: When actually delivering a message, Exim removes duplicate recipient
+addresses after routing is complete, so that only one delivery takes place.
+This does not happen when testing with <option>-bt</option>; the full results of routing are
+always shown.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: <option>-bt</option> can only do relatively simple testing. If any of the
+routers in the configuration makes any tests on the sender address of a
+message,
+<indexterm role="option">
+<primary><option>-f</option></primary>
+<secondary>for address testing</secondary>
+</indexterm>
+you can use the <option>-f</option> option to set an appropriate sender when running
+<option>-bt</option> tests. Without it, the sender is assumed to be the calling user at the
+default qualifying domain. However, if you have set up (for example) routers
+whose behaviour depends on the contents of an incoming message, you cannot test
+those conditions using <option>-bt</option>. The <option>-N</option> option provides a possible way of
+doing such tests.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bV</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bV</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>version number of Exim</primary>
+</indexterm>
+This option causes Exim to write the current version number, compilation
+number, and compilation date of the <emphasis>exim</emphasis> binary to the standard output.
+It also lists the DBM library that is being used, the optional modules (such as
+specific lookup types), the drivers that are included in the binary, and the
+name of the runtime configuration file that is in use.
+</para>
+<para>
+As part of its operation, <option>-bV</option> causes Exim to read and syntax check its
+configuration file. However, this is a static check only. It cannot check
+values that are to be expanded. For example, although a misspelt ACL verb is
+detected, an error in the verb’s arguments is not. You cannot rely on <option>-bV</option>
+alone to discover (for example) all the typos in the configuration; some
+realistic testing is needed. The <option>-bh</option> and <option>-N</option> options provide more
+dynamic testing facilities.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bv</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bv</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>verifying address</primary>
+<secondary>using <option>-bv</option></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address</primary>
+<secondary>verification</secondary>
+</indexterm>
+This option runs Exim in address verification mode, in which each argument is
+taken as a recipient address to be verified by the routers. (This does
+not involve any verification callouts). During normal operation, verification
+happens mostly as a consequence processing a <option>verify</option> condition in an ACL
+(see chapter <xref linkend="CHAPACL"/>). If you want to test an entire ACL, possibly
+including callouts, see the <option>-bh</option> and <option>-bhc</option> options.
+</para>
+<para>
+If verification fails, and the caller is not an admin user, no details of the
+failure are output, because these might contain sensitive information such as
+usernames and passwords for database lookups.
+</para>
+<para>
+If no arguments are given, Exim runs in an interactive manner, prompting with a
+right angle bracket for addresses to be verified.
+</para>
+<para>
+Unlike the <option>-be</option> test option, you cannot arrange for Exim to use the
+<function>readline()</function> function, because it is running as <emphasis>exim</emphasis> and there are
+security issues.
+</para>
+<para>
+Verification differs from address testing (the <option>-bt</option> option) in that routers
+that have <option>no_verify</option> set are skipped, and if the address is accepted by a
+router that has <option>fail_verify</option> set, verification fails. The address is
+verified as a recipient if <option>-bv</option> is used; to test verification for a sender
+address, <option>-bvs</option> should be used.
+</para>
+<para>
+If the <option>-v</option> option is not set, the output consists of a single line for each
+address, stating whether it was verified or not, and giving a reason in the
+latter case. Without <option>-v</option>, generating more than one address by redirection
+causes verification to end successfully, without considering the generated
+addresses. However, if just one address is generated, processing continues,
+and the generated address must verify successfully for the overall verification
+to succeed.
+</para>
+<para>
+When <option>-v</option> is set, more details are given of how the address has been handled,
+and in the case of address redirection, all the generated addresses are also
+considered. Verification may succeed for some and fail for others.
+</para>
+<para>
+The
+<indexterm role="concept">
+<primary>return code</primary>
+<secondary>for <option>-bv</option></secondary>
+</indexterm>
+return code is 2 if any address failed outright; it is 1 if no address
+failed outright but at least one could not be resolved for some reason. Return
+code 0 is given only when all addresses succeed.
+</para>
+<para>
+If any of the routers in the configuration makes any tests on the sender
+address of a message, you should use the <option>-f</option> option to set an appropriate
+sender when running <option>-bv</option> tests. Without it, the sender is assumed to be the
+calling user at the default qualifying domain.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bvs</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bvs</option></primary>
+</indexterm>
+This option acts like <option>-bv</option>, but verifies the address as a sender rather
+than a recipient address. This affects any rewriting and qualification that
+might happen.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-bw</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-bw</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>daemon</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>inetd</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>inetd</primary>
+<secondary>wait mode</secondary>
+</indexterm>
+This option runs Exim as a daemon, awaiting incoming SMTP connections,
+similarly to the <option>-bd</option> option. All port specifications on the command-line
+and in the configuration file are ignored. Queue-running may not be specified.
+</para>
+<para>
+In this mode, Exim expects to be passed a socket as fd 0 (stdin) which is
+listening for connections. This permits the system to start up and have
+inetd (or equivalent) listen on the SMTP ports, starting an Exim daemon for
+each port only when the first connection is received.
+</para>
+<para>
+If the option is given as <option>-bw</option><<emphasis>time</emphasis>> then the time is a timeout, after
+which the daemon will exit, which should cause inetd to listen once more.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-C</option> <<emphasis>filelist</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-C</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>configuration file</primary>
+<secondary>alternate</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>CONFIGURE_FILE</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>alternate configuration file</primary>
+</indexterm>
+This option causes Exim to find the runtime configuration file from the given
+list instead of from the list specified by the CONFIGURE_FILE
+compile-time setting. Usually, the list will consist of just a single filename,
+but it can be a colon-separated list of names. In this case, the first
+file that exists is used. Failure to open an existing file stops Exim from
+proceeding any further along the list, and an error is generated.
+</para>
+<para>
+When this option is used by a caller other than root, and the list is different
+from the compiled-in list, Exim gives up its root privilege immediately, and
+runs with the real and effective uid and gid set to those of the caller.
+However, if a TRUSTED_CONFIG_LIST file is defined in <filename>Local/Makefile</filename>, that
+file contains a list of full pathnames, one per line, for configuration files
+which are trusted. Root privilege is retained for any configuration file so
+listed, as long as the caller is the Exim user (or the user specified in the
+CONFIGURE_OWNER option, if any), and as long as the configuration file is
+not writeable by inappropriate users or groups.
+</para>
+<para>
+Leaving TRUSTED_CONFIG_LIST unset precludes the possibility of testing a
+configuration using <option>-C</option> right through message reception and delivery,
+even if the caller is root. The reception works, but by that time, Exim is
+running as the Exim user, so when it re-executes to regain privilege for the
+delivery, the use of <option>-C</option> causes privilege to be lost. However, root can
+test reception and delivery using two separate commands (one to put a message
+in the queue, using <option>-odq</option>, and another to do the delivery, using <option>-M</option>).
+</para>
+<para>
+If ALT_CONFIG_PREFIX is defined <filename>in Local/Makefile</filename>, it specifies a
+prefix string with which any file named in a <option>-C</option> command line option
+must start. In addition, the filename must not contain the sequence <literal>/../</literal>.
+However, if the value of the <option>-C</option> option is identical to the value of
+CONFIGURE_FILE in <filename>Local/Makefile</filename>, Exim ignores <option>-C</option> and proceeds as
+usual. There is no default setting for ALT_CONFIG_PREFIX; when it is
+unset, any filename can be used with <option>-C</option>.
+</para>
+<para>
+ALT_CONFIG_PREFIX can be used to confine alternative configuration files
+to a directory to which only root has access. This prevents someone who has
+broken into the Exim account from running a privileged Exim with an arbitrary
+configuration file.
+</para>
+<para>
+The <option>-C</option> facility is useful for ensuring that configuration files are
+syntactically correct, but cannot be used for test deliveries, unless the
+caller is privileged, or unless it is an exotic configuration that does not
+require privilege. No check is made on the owner or group of the files
+specified by this option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-D</option><<emphasis>macro</emphasis>>=<<emphasis>value</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-D</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>macro</primary>
+<secondary>setting on command line</secondary>
+</indexterm>
+This option can be used to override macro definitions in the configuration file
+(see section <xref linkend="SECTmacrodefs"/>). However, like <option>-C</option>, if it is used by an
+unprivileged caller, it causes Exim to give up its root privilege.
+If DISABLE_D_OPTION is defined in <filename>Local/Makefile</filename>, the use of <option>-D</option> is
+completely disabled, and its use causes an immediate error exit.
+</para>
+<para>
+If WHITELIST_D_MACROS is defined in <filename>Local/Makefile</filename> then it should be a
+colon-separated list of macros which are considered safe and, if <option>-D</option> only
+supplies macros from this list, and the values are acceptable, then Exim will
+not give up root privilege if the caller is root, the Exim run-time user, or
+the CONFIGURE_OWNER, if set. This is a transition mechanism and is expected
+to be removed in the future. Acceptable values for the macros satisfy the
+regexp: <literal>^[A-Za-z0-9_/.-]*$</literal>
+</para>
+<para>
+The entire option (including equals sign if present) must all be within one
+command line item. <option>-D</option> can be used to set the value of a macro to the empty
+string, in which case the equals sign is optional. These two commands are
+synonymous:
+</para>
+<literallayout class="monospaced">
+exim -DABC ...
+exim -DABC= ...
+</literallayout>
+<para>
+To include spaces in a macro definition item, quotes must be used. If you use
+quotes, spaces are permitted around the macro name and the equals sign. For
+example:
+</para>
+<literallayout class="monospaced">
+exim '-D ABC = something' ...
+</literallayout>
+<para>
+<option>-D</option> may be repeated up to 10 times on a command line.
+Only macro names up to 22 letters long can be set.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-d</option><<emphasis>debug options</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-d</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>debugging</primary>
+<secondary>list of selectors</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>debugging</primary>
+<secondary><option>-d</option> option</secondary>
+</indexterm>
+This option causes debugging information to be written to the standard
+error stream. It is restricted to admin users because debugging output may show
+database queries that contain password information. Also, the details of users’
+filter files should be protected. If a non-admin user uses <option>-d</option>, Exim
+writes an error message to the standard error stream and exits with a non-zero
+return code.
+</para>
+<para>
+When <option>-d</option> is used, <option>-v</option> is assumed. If <option>-d</option> is given on its own, a lot of
+standard debugging data is output. This can be reduced, or increased to include
+some more rarely needed information, by directly following <option>-d</option> with a string
+made up of names preceded by plus or minus characters. These add or remove sets
+of debugging data, respectively. For example, <option>-d+filter</option> adds filter
+debugging, whereas <option>-d-all+filter</option> selects only filter debugging. Note that
+no spaces are allowed in the debug setting. The available debugging categories
+are:
+</para>
+<literallayout>
+<literal>acl </literal> ACL interpretation
+<literal>auth </literal> authenticators
+<literal>deliver </literal> general delivery logic
+<literal>dns </literal> DNS lookups (see also resolver)
+<literal>dnsbl </literal> DNS black list (aka RBL) code
+<literal>exec </literal> arguments for <function>execv()</function> calls
+<literal>expand </literal> detailed debugging for string expansions
+<literal>filter </literal> filter handling
+<literal>hints_lookup </literal> hints data lookups
+<literal>host_lookup </literal> all types of name-to-IP address handling
+<literal>ident </literal> ident lookup
+<literal>interface </literal> lists of local interfaces
+<literal>lists </literal> matching things in lists
+<literal>load </literal> system load checks
+<literal>local_scan </literal> can be used by <function>local_scan()</function> (see chapter <xref linkend="CHAPlocalscan"/>)
+<literal>lookup </literal> general lookup code and all lookups
+<literal>memory </literal> memory handling
+<literal>noutf8 </literal> modifier: avoid UTF-8 line-drawing
+<literal>pid </literal> modifier: add pid to debug output lines
+<literal>process_info </literal> setting info for the process log
+<literal>queue_run </literal> queue runs
+<literal>receive </literal> general message reception logic
+<literal>resolver </literal> turn on the DNS resolver’s debugging output
+<literal>retry </literal> retry handling
+<literal>rewrite </literal> address rewriting
+<literal>route </literal> address routing
+<literal>timestamp </literal> modifier: add timestamp to debug output lines
+<literal>tls </literal> TLS logic
+<literal>transport </literal> transports
+<literal>uid </literal> changes of uid/gid and looking up uid/gid
+<literal>verify </literal> address verification logic
+<literal>all </literal> almost all of the above (see below), and also <option>-v</option>
+</literallayout>
+<para>
+The <literal>all</literal> option excludes <literal>memory</literal> when used as <literal>+all</literal>, but includes it
+for <literal>-all</literal>. The reason for this is that <literal>+all</literal> is something that people
+tend to use when generating debug output for Exim maintainers. If <literal>+memory</literal>
+is included, an awful lot of output that is very rarely of interest is
+generated, so it now has to be explicitly requested. However, <literal>-all</literal> does
+turn everything off.
+</para>
+<para>
+<indexterm role="concept">
+<primary>resolver, debugging output</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS resolver, debugging output</primary>
+</indexterm>
+The <literal>resolver</literal> option produces output only if the DNS resolver was compiled
+with DEBUG enabled. This is not the case in some operating systems. Also,
+unfortunately, debugging output from the DNS resolver is written to stdout
+rather than stderr.
+</para>
+<para>
+The default (<option>-d</option> with no argument) omits <literal>expand</literal>, <literal>filter</literal>,
+<literal>interface</literal>, <literal>load</literal>, <literal>memory</literal>, <literal>pid</literal>, <literal>resolver</literal>, and <literal>timestamp</literal>.
+However, the <literal>pid</literal> selector is forced when debugging is turned on for a
+daemon, which then passes it on to any re-executed Exims. Exim also
+automatically adds the pid to debug lines when several remote deliveries are
+run in parallel.
+</para>
+<para>
+The <literal>timestamp</literal> selector causes the current time to be inserted at the start
+of all debug output lines. This can be useful when trying to track down delays
+in processing.
+</para>
+<para>
+<indexterm role="concept">
+<primary>debugging</primary>
+<secondary>UTF-8 in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>UTF-8</primary>
+<secondary>in debug output</secondary>
+</indexterm>
+The <literal>noutf8</literal> selector disables the use of
+UTF-8 line-drawing characters to group related information.
+When disabled. ascii-art is used instead.
+Using the <literal>+all</literal> option does not set this modifier,
+</para>
+<para>
+If the <option>debug_print</option> option is set in any driver, it produces output whenever
+any debugging is selected, or if <option>-v</option> is used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-dd</option><<emphasis>debug options</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-dd</option></primary>
+</indexterm>
+This option behaves exactly like <option>-d</option> except when used on a command that
+starts a daemon process. In that case, debugging is turned off for the
+subprocesses that the daemon creates. Thus, it is useful for monitoring the
+behaviour of the daemon without creating as much output as full debugging does.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-dropcr</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-dropcr</option></primary>
+</indexterm>
+This is an obsolete option that is now a no-op. It used to affect the way Exim
+handled CR and LF characters in incoming messages. What happens now is
+described in section <xref linkend="SECTlineendings"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-E</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-E</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>generating</secondary>
+</indexterm>
+This option specifies that an incoming message is a locally-generated delivery
+failure report. It is used internally by Exim when handling delivery failures
+and is not intended for external use. Its only effect is to stop Exim
+generating certain messages to the postmaster, as otherwise message cascades
+could occur in some situations. As part of the same option, a message id may
+follow the characters <option>-E</option>. If it does, the log entry for the receipt of the
+new message contains the id, following <quote>R=</quote>, as a cross-reference.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-e</option><emphasis>x</emphasis></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-e</option><emphasis>x</emphasis></primary>
+</indexterm>
+There are a number of Sendmail options starting with <option>-oe</option> which seem to be
+called by various programs without the leading <option>o</option> in the option. For
+example, the <option>vacation</option> program uses <option>-eq</option>. Exim treats all options of the
+form <option>-e</option><emphasis>x</emphasis> as synonymous with the corresponding <option>-oe</option><emphasis>x</emphasis> options.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-F</option> <<emphasis>string</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-F</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>name</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>name</primary>
+<secondary>of sender</secondary>
+</indexterm>
+This option sets the sender’s full name for use when a locally-generated
+message is being accepted. In the absence of this option, the user’s <emphasis>gecos</emphasis>
+entry from the password data is used. As users are generally permitted to alter
+their <emphasis>gecos</emphasis> entries, no security considerations are involved. White space
+between <option>-F</option> and the <<emphasis>string</emphasis>> is optional.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-f</option> <<emphasis>address</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-f</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>address</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address</primary>
+<secondary>sender</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>trusted users</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope from</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope sender</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>user</primary>
+<secondary>trusted</secondary>
+</indexterm>
+This option sets the address of the envelope sender of a locally-generated
+message (also known as the return path). The option can normally be used only
+by a trusted user, but <option>untrusted_set_sender</option> can be set to allow untrusted
+users to use it.
+</para>
+<para>
+Processes running as root or the Exim user are always trusted. Other
+trusted users are defined by the <option>trusted_users</option> or <option>trusted_groups</option>
+options. In the absence of <option>-f</option>, or if the caller is not trusted, the sender
+of a local message is set to the caller’s login name at the default qualify
+domain.
+</para>
+<para>
+There is one exception to the restriction on the use of <option>-f</option>: an empty sender
+can be specified by any user, trusted or not, to create a message that can
+never provoke a bounce. An empty sender can be specified either as an empty
+string, or as a pair of angle brackets with nothing between them, as in these
+examples of shell commands:
+</para>
+<literallayout class="monospaced">
+exim -f '<>' user@domain
+exim -f "" user@domain
+</literallayout>
+<para>
+In addition, the use of <option>-f</option> is not restricted when testing a filter file
+with <option>-bf</option> or when testing or verifying addresses using the <option>-bt</option> or
+<option>-bv</option> options.
+</para>
+<para>
+Allowing untrusted users to change the sender address does not of itself make
+it possible to send anonymous mail. Exim still checks that the <emphasis>From:</emphasis> header
+refers to the local user, and if it does not, it adds a <emphasis>Sender:</emphasis> header,
+though this can be overridden by setting <option>no_local_from_check</option>.
+</para>
+<para>
+White
+<indexterm role="concept">
+<primary><quote>From</quote> line</primary>
+</indexterm>
+space between <option>-f</option> and the <<emphasis>address</emphasis>> is optional (that is, they can be
+given as two arguments or one combined argument). The sender of a
+locally-generated message can also be set (when permitted) by an initial
+<quote>From </quote> line in the message – see the description of <option>-bm</option> above – but
+if <option>-f</option> is also present, it overrides <quote>From </quote>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-G</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-G</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>submission fixups, suppressing (command-line)</primary>
+</indexterm>
+This option is equivalent to an ACL applying:
+</para>
+<literallayout class="monospaced">
+control = suppress_local_fixups
+</literallayout>
+<para>
+for every message received. Note that Sendmail will complain about such
+bad formatting, where Exim silently just does not fix it up. This may change
+in future.
+</para>
+<para>
+As this affects audit information, the caller must be a trusted user to use
+this option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-h</option> <<emphasis>number</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-h</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary><option>-h</option> option ignored</secondary>
+</indexterm>
+This option is accepted for compatibility with Sendmail, but has no effect. (In
+Sendmail it overrides the <quote>hop count</quote> obtained by counting <emphasis>Received:</emphasis>
+headers.)
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-i</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-i</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Solaris</primary>
+<secondary><emphasis>mail</emphasis> command</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>dot</primary>
+<secondary>in incoming non-SMTP message</secondary>
+</indexterm>
+This option, which has the same effect as <option>-oi</option>, specifies that a dot on a
+line by itself should not terminate an incoming, non-SMTP message. I can find
+no documentation for this option in Solaris 2.4 Sendmail, but the <emphasis>mailx</emphasis>
+command in Solaris 2.4 uses it. See also <option>-ti</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-L</option> <<emphasis>tag</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-L</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>syslog</primary>
+<secondary>process name; set with flag</secondary>
+</indexterm>
+This option is equivalent to setting <option>syslog_processname</option> in the config
+file and setting <option>log_file_path</option> to <literal>syslog</literal>.
+Its use is restricted to administrators. The configuration file has to be
+read and parsed, to determine access rights, before this is set and takes
+effect, so early configuration file errors will not honour this flag.
+</para>
+<para>
+The tag should not be longer than 32 characters.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-M</option> <<emphasis>message id</emphasis>> <<emphasis>message id</emphasis>> ...</term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-M</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>forcing delivery</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>forcing attempt</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>forcing delivery</secondary>
+</indexterm>
+This option requests Exim to run a delivery attempt on each message in turn. If
+any of the messages are frozen, they are automatically thawed before the
+delivery attempt. The settings of <option>queue_domains</option>, <option>queue_smtp_domains</option>,
+and <option>hold_domains</option> are ignored.
+</para>
+<para>
+Retry
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>overriding retry hints</secondary>
+</indexterm>
+hints for any of the addresses are overridden – Exim tries to deliver even if
+the normal retry time has not yet been reached. This option requires the caller
+to be an admin user. However, there is an option called <option>prod_requires_admin</option>
+which can be set false to relax this restriction (and also the same requirement
+for the <option>-q</option>, <option>-R</option>, and <option>-S</option> options).
+</para>
+<para>
+The deliveries happen synchronously, that is, the original Exim process does
+not terminate until all the delivery attempts have finished. No output is
+produced unless there is a serious error. If you want to see what is happening,
+use the <option>-v</option> option as well, or inspect Exim’s main log.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mar</option> <<emphasis>message id</emphasis>> <<emphasis>address</emphasis>> <<emphasis>address</emphasis>> ...</term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mar</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>adding recipients</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>recipient</primary>
+<secondary>adding</secondary>
+</indexterm>
+This option requests Exim to add the addresses to the list of recipients of the
+message (<quote>ar</quote> for <quote>add recipients</quote>). The first argument must be a message
+id, and the remaining ones must be email addresses. However, if the message is
+active (in the middle of a delivery attempt), it is not altered. This option
+can be used only by an admin user.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-MC</option> <<emphasis>transport</emphasis>> <<emphasis>hostname</emphasis>> <<emphasis>sequence number</emphasis>> <<emphasis>message id</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-MC</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>passed connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>multiple deliveries</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>multiple SMTP deliveries</primary>
+</indexterm>
+This option is not intended for use by external callers. It is used internally
+by Exim to invoke another instance of itself to deliver a waiting message using
+an existing SMTP connection, which is passed as the standard input. Details are
+given in chapter <xref linkend="CHAPSMTP"/>. This must be the final option, and the caller
+must be root or the Exim user in order to use it.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-MCA</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-MCA</option></primary>
+</indexterm>
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the <option>-MC</option> option. It signifies that the
+connection to the remote host has been authenticated.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-MCD</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-MCD</option></primary>
+</indexterm>
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the <option>-MC</option> option. It signifies that the
+remote host supports the ESMTP <filename>DSN</filename> extension.
+</para>
+</listitem></varlistentry>
+<varlistentry revisionflag="changed">
+<term><option>-MCd</option></term>
+<listitem>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>-MCd</option></primary>
+</indexterm>
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the <option>-d</option> option
+to pass on an information string on the purpose of the process.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-MCG</option> <<emphasis>queue name</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-MCG</option></primary>
+</indexterm>
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the <option>-MC</option> option. It signifies that an
+alternate queue is used, named by the following argument.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-MCK</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-MCK</option></primary>
+</indexterm>
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the <option>-MC</option> option. It signifies that a
+remote host supports the ESMTP <filename>CHUNKING</filename> extension.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-MCP</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-MCP</option></primary>
+</indexterm>
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the <option>-MC</option> option. It signifies that the server to
+which Exim is connected supports pipelining.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-MCQ</option> <<emphasis>process id</emphasis>> <<emphasis>pipe fd</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-MCQ</option></primary>
+</indexterm>
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the <option>-MC</option> option when the original delivery was
+started by a queue runner. It passes on the process id of the queue runner,
+together with the file descriptor number of an open pipe. Closure of the pipe
+signals the final completion of the sequence of processes that are passing
+messages through the same SMTP connection.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-MCS</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-MCS</option></primary>
+</indexterm>
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the <option>-MC</option> option, and passes on the fact that the
+ESMTP SIZE option should be used on messages delivered down the existing
+connection.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-MCT</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-MCT</option></primary>
+</indexterm>
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the <option>-MC</option> option, and passes on the fact that the
+host to which Exim is connected supports TLS encryption.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-MCt</option> <<emphasis>IP address</emphasis>> <<emphasis>port</emphasis>> <<emphasis>cipher</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-MCt</option></primary>
+</indexterm>
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the <option>-MC</option> option, and passes on the fact that the
+connection is being proxied by a parent process for handling TLS encryption.
+The arguments give the local address and port being proxied, and the TLS cipher.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mc</option> <<emphasis>message id</emphasis>> <<emphasis>message id</emphasis>> ...</term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mc</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>not overridden by <option>-Mc</option></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>manually started – not forced</secondary>
+</indexterm>
+This option requests Exim to run a delivery attempt on each message, in turn,
+but unlike the <option>-M</option> option, it does check for retry hints, and respects any
+that are found. This option is not very useful to external callers. It is
+provided mainly for internal use by Exim when it needs to re-invoke itself in
+order to regain root privilege for a delivery (see chapter <xref linkend="CHAPsecurity"/>).
+However, <option>-Mc</option> can be useful when testing, in order to run a delivery that
+respects retry times and other options such as <option>hold_domains</option> that are
+overridden when <option>-M</option> is used. Such a delivery does not count as a queue run.
+If you want to run a specific delivery as if in a queue run, you should use
+<option>-q</option> with a message id argument. A distinction between queue run deliveries
+and other deliveries is made in one or two places.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mes</option> <<emphasis>message id</emphasis>> <<emphasis>address</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mes</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>changing sender</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>changing</secondary>
+</indexterm>
+This option requests Exim to change the sender address in the message to the
+given address, which must be a fully qualified address or <quote><></quote> (<quote>es</quote> for
+<quote>edit sender</quote>). There must be exactly two arguments. The first argument must
+be a message id, and the second one an email address. However, if the message
+is active (in the middle of a delivery attempt), its status is not altered.
+This option can be used only by an admin user.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mf</option> <<emphasis>message id</emphasis>> <<emphasis>message id</emphasis>> ...</term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mf</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>freezing messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>manually freezing</secondary>
+</indexterm>
+This option requests Exim to mark each listed message as <quote>frozen</quote>. This
+prevents any delivery attempts taking place until the message is <quote>thawed</quote>,
+either manually or as a result of the <option>auto_thaw</option> configuration option.
+However, if any of the messages are active (in the middle of a delivery
+attempt), their status is not altered. This option can be used only by an admin
+user.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mg</option> <<emphasis>message id</emphasis>> <<emphasis>message id</emphasis>> ...</term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mg</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>giving up on messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>abandoning delivery attempts</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>abandoning further attempts</secondary>
+</indexterm>
+This option requests Exim to give up trying to deliver the listed messages,
+including any that are frozen. However, if any of the messages are active,
+their status is not altered. For non-bounce messages, a delivery error message
+is sent to the sender, containing the text <quote>cancelled by administrator</quote>.
+Bounce messages are just discarded. This option can be used only by an admin
+user.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-MG</option> <<emphasis>queue name</emphasis>> <<emphasis>message id</emphasis>> <<emphasis>message id</emphasis>> ...</term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-MG</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>named</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>named queues</primary>
+<secondary>moving messages</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>moving messages</secondary>
+</indexterm>
+This option requests that each listed message be moved from its current
+queue to the given named queue.
+The destination queue name argument is required, but can be an empty
+string to define the default queue.
+If the messages are not currently located in the default queue,
+a <option>-qG<name></option> option will be required to define the source queue.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mmad</option> <<emphasis>message id</emphasis>> <<emphasis>message id</emphasis>> ...</term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mmad</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>cancelling all</secondary>
+</indexterm>
+This option requests Exim to mark all the recipient addresses in the messages
+as already delivered (<quote>mad</quote> for <quote>mark all delivered</quote>). However, if any
+message is active (in the middle of a delivery attempt), its status is not
+altered. This option can be used only by an admin user.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mmd</option> <<emphasis>message id</emphasis>> <<emphasis>address</emphasis>> <<emphasis>address</emphasis>> ...</term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mmd</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>cancelling by address</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>recipient</primary>
+<secondary>removing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>removing recipients</primary>
+</indexterm>
+This option requests Exim to mark the given addresses as already delivered
+(<quote>md</quote> for <quote>mark delivered</quote>). The first argument must be a message id, and
+the remaining ones must be email addresses. These are matched to recipient
+addresses in the message in a case-sensitive manner. If the message is active
+(in the middle of a delivery attempt), its status is not altered. This option
+can be used only by an admin user.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mrm</option> <<emphasis>message id</emphasis>> <<emphasis>message id</emphasis>> ...</term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mrm</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>removing messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>abandoning mail</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>manually discarding</secondary>
+</indexterm>
+This option requests Exim to remove the given messages from the queue. No
+bounce messages are sent; each message is simply forgotten. However, if any of
+the messages are active, their status is not altered. This option can be used
+only by an admin user or by the user who originally caused the message to be
+placed in the queue.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mset</option> <<emphasis>message id</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mset</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>string expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>testing</secondary>
+</indexterm>
+This option is useful only in conjunction with <option>-be</option> (that is, when testing
+string expansions). Exim loads the given message from its spool before doing
+the test expansions, thus setting message-specific variables such as
+<varname>$message_size</varname> and the header variables. The <varname>$recipients</varname> variable is made
+available. This feature is provided to make it easier to test expansions that
+make use of these variables. However, this option can be used only by an admin
+user. See also <option>-bem</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mt</option> <<emphasis>message id</emphasis>> <<emphasis>message id</emphasis>> ...</term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mt</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>thawing messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>unfreezing messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>thawing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>thawing frozen</secondary>
+</indexterm>
+This option requests Exim to <quote>thaw</quote> any of the listed messages that are
+<quote>frozen</quote>, so that delivery attempts can resume. However, if any of the
+messages are active, their status is not altered. This option can be used only
+by an admin user.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mvb</option> <<emphasis>message id</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mvb</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>listing</primary>
+<secondary>message body</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>listing body of</secondary>
+</indexterm>
+This option causes the contents of the message body (-D) spool file to be
+written to the standard output. This option can be used only by an admin user.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mvc</option> <<emphasis>message id</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mvc</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>listing in RFC 2822 format</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>listing</primary>
+<secondary>message in RFC 2822 format</secondary>
+</indexterm>
+This option causes a copy of the complete message (header lines plus body) to
+be written to the standard output in RFC 2822 format. This option can be used
+only by an admin user.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mvh</option> <<emphasis>message id</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mvh</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>listing</primary>
+<secondary>message headers</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>listing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>listing header lines</secondary>
+</indexterm>
+This option causes the contents of the message headers (-H) spool file to be
+written to the standard output. This option can be used only by an admin user.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Mvl</option> <<emphasis>message id</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Mvl</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>listing</primary>
+<secondary>message log</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>listing message log</secondary>
+</indexterm>
+This option causes the contents of the message log spool file to be written to
+the standard output. This option can be used only by an admin user.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-m</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-m</option></primary>
+</indexterm>
+This is apparently a synonym for <option>-om</option> that is accepted by Sendmail, so Exim
+treats it that way too.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-N</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-N</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>debugging</primary>
+<secondary><option>-N</option> option</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>debugging</primary>
+<secondary>suppressing delivery</secondary>
+</indexterm>
+This is a debugging option that inhibits delivery of a message at the transport
+level. It implies <option>-v</option>. Exim goes through many of the motions of delivery –
+it just doesn’t actually transport the message, but instead behaves as if it
+had successfully done so. However, it does not make any updates to the retry
+database, and the log entries for deliveries are flagged with <quote>*></quote> rather
+than <quote>=></quote>.
+</para>
+<para>
+Because <option>-N</option> discards any message to which it applies, only root or the Exim
+user are allowed to use it with <option>-bd</option>, <option>-q</option>, <option>-R</option> or <option>-M</option>. In other
+words, an ordinary user can use it only when supplying an incoming message to
+which it will apply. Although transportation never fails when <option>-N</option> is set, an
+address may be deferred because of a configuration problem on a transport, or a
+routing problem. Once <option>-N</option> has been used for a delivery attempt, it sticks to
+the message, and applies to any subsequent delivery attempts that may happen
+for that message.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-n</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-n</option></primary>
+</indexterm>
+This option is interpreted by Sendmail to mean <quote>no aliasing</quote>.
+For normal modes of operation, it is ignored by Exim.
+When combined with <option>-bP</option> it makes the output more terse (suppresses
+option names, environment values and config pretty printing).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-O</option> <<emphasis>data</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-O</option></primary>
+</indexterm>
+This option is interpreted by Sendmail to mean <literal>set option</literal>. It is ignored by
+Exim.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oA</option> <<emphasis>file name</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oA</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary><option>-oA</option> option</secondary>
+</indexterm>
+This option is used by Sendmail in conjunction with <option>-bi</option> to specify an
+alternative alias filename. Exim handles <option>-bi</option> differently; see the
+description above.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oB</option> <<emphasis>n</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oB</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>passed connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>multiple deliveries</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>multiple SMTP deliveries</primary>
+</indexterm>
+This is a debugging option which limits the maximum number of messages that can
+be delivered down one SMTP connection, overriding the value set in any <command>smtp</command>
+transport. If <<emphasis>n</emphasis>> is omitted, the limit is set to 1.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-odb</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-odb</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>background delivery</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>in the background</secondary>
+</indexterm>
+This option applies to all modes in which Exim accepts incoming messages,
+including the listening daemon. It requests <quote>background</quote> delivery of such
+messages, which means that the accepting process automatically starts a
+delivery process for each message received, but does not wait for the delivery
+processes to finish.
+</para>
+<para>
+When all the messages have been received, the reception process exits,
+leaving the delivery processes to finish in their own time. The standard output
+and error streams are closed at the start of each delivery process.
+This is the default action if none of the <option>-od</option> options are present.
+</para>
+<para>
+If one of the queueing options in the configuration file
+(<option>queue_only</option> or <option>queue_only_file</option>, for example) is in effect, <option>-odb</option>
+overrides it if <option>queue_only_override</option> is set true, which is the default
+setting. If <option>queue_only_override</option> is set false, <option>-odb</option> has no effect.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-odf</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-odf</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>foreground delivery</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>in the foreground</secondary>
+</indexterm>
+This option requests <quote>foreground</quote> (synchronous) delivery when Exim has
+accepted a locally-generated message. (For the daemon it is exactly the same as
+<option>-odb</option>.) A delivery process is automatically started to deliver the message,
+and Exim waits for it to complete before proceeding.
+</para>
+<para>
+The original Exim reception process does not finish until the delivery
+process for the final message has ended. The standard error stream is left open
+during deliveries.
+</para>
+<para>
+However, like <option>-odb</option>, this option has no effect if <option>queue_only_override</option> is
+false and one of the queueing options in the configuration file is in effect.
+</para>
+<para>
+If there is a temporary delivery error during foreground delivery, the
+message is left in the queue for later delivery, and the original reception
+process exits. See chapter <xref linkend="CHAPnonqueueing"/> for a way of setting up a
+restricted configuration that never queues messages.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-odi</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-odi</option></primary>
+</indexterm>
+This option is synonymous with <option>-odf</option>. It is provided for compatibility with
+Sendmail.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-odq</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-odq</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>non-immediate delivery</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>suppressing immediate</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>queueing incoming messages</primary>
+</indexterm>
+This option applies to all modes in which Exim accepts incoming messages,
+including the listening daemon. It specifies that the accepting process should
+not automatically start a delivery process for each message received. Messages
+are placed in the queue, and remain there until a subsequent queue runner
+process encounters them. There are several configuration options (such as
+<option>queue_only</option>) that can be used to queue incoming messages under certain
+conditions. This option overrides all of them and also <option>-odqs</option>. It always
+forces queueing.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-odqs</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-odqs</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>delaying delivery</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>first pass routing</primary>
+</indexterm>
+This option is a hybrid between <option>-odb</option>/<option>-odi</option> and <option>-odq</option>.
+However, like <option>-odb</option> and <option>-odi</option>, this option has no effect if
+<option>queue_only_override</option> is false and one of the queueing options in the
+configuration file is in effect.
+</para>
+<para>
+When <option>-odqs</option> does operate, a delivery process is started for each incoming
+message, in the background by default, but in the foreground if <option>-odi</option> is
+also present. The recipient addresses are routed, and local deliveries are done
+in the normal way. However, if any SMTP deliveries are required, they are not
+done at this time, so the message remains in the queue until a subsequent queue
+runner process encounters it. Because routing was done, Exim knows which
+messages are waiting for which hosts, and so a number of messages for the same
+host can be sent in a single SMTP connection. The <option>queue_smtp_domains</option>
+configuration option has the same effect for specific domains. See also the
+<option>-qq</option> option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oee</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oee</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>error</primary>
+<secondary>reporting</secondary>
+</indexterm>
+If an error is detected while a non-SMTP message is being received (for
+example, a malformed address), the error is reported to the sender in a mail
+message.
+</para>
+<para>
+<indexterm role="concept">
+<primary>return code</primary>
+<secondary>for <option>-oee</option></secondary>
+</indexterm>
+Provided
+this error message is successfully sent, the Exim receiving process
+exits with a return code of zero. If not, the return code is 2 if the problem
+is that the original message has no recipients, or 1 for any other error.
+This is the default <option>-oe</option><emphasis>x</emphasis> option if Exim is called as <emphasis>rmail</emphasis>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oem</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oem</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>error</primary>
+<secondary>reporting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>return code</primary>
+<secondary>for <option>-oem</option></secondary>
+</indexterm>
+This is the same as <option>-oee</option>, except that Exim always exits with a non-zero
+return code, whether or not the error message was successfully sent.
+This is the default <option>-oe</option><emphasis>x</emphasis> option, unless Exim is called as <emphasis>rmail</emphasis>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oep</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oep</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>error</primary>
+<secondary>reporting</secondary>
+</indexterm>
+If an error is detected while a non-SMTP message is being received, the
+error is reported by writing a message to the standard error file (stderr).
+<indexterm role="concept">
+<primary>return code</primary>
+<secondary>for <option>-oep</option></secondary>
+</indexterm>
+The return code is 1 for all errors.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oeq</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oeq</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>error</primary>
+<secondary>reporting</secondary>
+</indexterm>
+This option is supported for compatibility with Sendmail, but has the same
+effect as <option>-oep</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oew</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oew</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>error</primary>
+<secondary>reporting</secondary>
+</indexterm>
+This option is supported for compatibility with Sendmail, but has the same
+effect as <option>-oem</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oi</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oi</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>dot</primary>
+<secondary>in incoming non-SMTP message</secondary>
+</indexterm>
+This option, which has the same effect as <option>-i</option>, specifies that a dot on a
+line by itself should not terminate an incoming, non-SMTP message. Otherwise, a
+single dot does terminate, though Exim does no special processing for other
+lines that start with a dot. This option is set by default if Exim is called as
+<emphasis>rmail</emphasis>. See also <option>-ti</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oitrue</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oitrue</option></primary>
+</indexterm>
+This option is treated as synonymous with <option>-oi</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oMa</option> <<emphasis>host address</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oMa</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>host address, specifying for local message</secondary>
+</indexterm>
+A number of options starting with <option>-oM</option> can be used to set values associated
+with remote hosts on locally-submitted messages (that is, messages not received
+over TCP/IP). These options can be used by any caller in conjunction with the
+<option>-bh</option>, <option>-be</option>, <option>-bf</option>, <option>-bF</option>, <option>-bt</option>, or <option>-bv</option> testing options. In
+other circumstances, they are ignored unless the caller is trusted.
+</para>
+<para>
+The <option>-oMa</option> option sets the sender host address. This may include a port
+number at the end, after a full stop (period). For example:
+</para>
+<literallayout class="monospaced">
+exim -bs -oMa 10.9.8.7.1234
+</literallayout>
+<para>
+An alternative syntax is to enclose the IP address in square brackets,
+followed by a colon and the port number:
+</para>
+<literallayout class="monospaced">
+exim -bs -oMa [10.9.8.7]:1234
+</literallayout>
+<para>
+The IP address is placed in the <varname>$sender_host_address</varname> variable, and the
+port, if present, in <varname>$sender_host_port</varname>. If both <option>-oMa</option> and <option>-bh</option>
+are present on the command line, the sender host IP address is taken from
+whichever one is last.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oMaa</option> <<emphasis>name</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oMaa</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>name, specifying for local message</secondary>
+</indexterm>
+See <option>-oMa</option> above for general remarks about the <option>-oM</option> options. The <option>-oMaa</option>
+option sets the value of <varname>$sender_host_authenticated</varname> (the authenticator
+name). See chapter <xref linkend="CHAPSMTPAUTH"/> for a discussion of SMTP authentication.
+This option can be used with <option>-bh</option> and <option>-bs</option> to set up an
+authenticated SMTP session without actually using the SMTP AUTH command.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oMai</option> <<emphasis>string</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oMai</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>id, specifying for local message</secondary>
+</indexterm>
+See <option>-oMa</option> above for general remarks about the <option>-oM</option> options. The <option>-oMai</option>
+option sets the value of <varname>$authenticated_id</varname> (the id that was authenticated).
+This overrides the default value (the caller’s login id, except with <option>-bh</option>,
+where there is no default) for messages from local sources. See chapter
+<xref linkend="CHAPSMTPAUTH"/> for a discussion of authenticated ids.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oMas</option> <<emphasis>address</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oMas</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>sender, specifying for local message</secondary>
+</indexterm>
+See <option>-oMa</option> above for general remarks about the <option>-oM</option> options. The <option>-oMas</option>
+option sets the authenticated sender value in <varname>$authenticated_sender</varname>. It
+overrides the sender address that is created from the caller’s login id for
+messages from local sources, except when <option>-bh</option> is used, when there is no
+default. For both <option>-bh</option> and <option>-bs</option>, an authenticated sender that is
+specified on a MAIL command overrides this value. See chapter
+<xref linkend="CHAPSMTPAUTH"/> for a discussion of authenticated senders.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oMi</option> <<emphasis>interface address</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oMi</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>interface</primary>
+<secondary>address, specifying for local message</secondary>
+</indexterm>
+See <option>-oMa</option> above for general remarks about the <option>-oM</option> options. The <option>-oMi</option>
+option sets the IP interface address value. A port number may be included,
+using the same syntax as for <option>-oMa</option>. The interface address is placed in
+<varname>$received_ip_address</varname> and the port number, if present, in <varname>$received_port</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oMm</option> <<emphasis>message reference</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oMm</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message reference</primary>
+<secondary>message reference, specifying for local message</secondary>
+</indexterm>
+See <option>-oMa</option> above for general remarks about the <option>-oM</option> options. The <option>-oMm</option>
+option sets the message reference, e.g. message-id, and is logged during
+delivery. This is useful when some kind of audit trail is required to tie
+messages together. The format of the message reference is checked and will
+abort if the format is invalid. The option will only be accepted if exim is
+running in trusted mode, not as any regular user.
+</para>
+<para>
+The best example of a message reference is when Exim sends a bounce message.
+The message reference is the message-id of the original message for which Exim
+is sending the bounce.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oMr</option> <<emphasis>protocol name</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oMr</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>protocol, specifying for local message</primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$received_protocol</varname></primary>
+</indexterm>
+See <option>-oMa</option> above for general remarks about the <option>-oM</option> options. The <option>-oMr</option>
+option sets the received protocol value that is stored in
+<varname>$received_protocol</varname>. However, it does not apply (and is ignored) when <option>-bh</option>
+or <option>-bs</option> is used. For <option>-bh</option>, the protocol is forced to one of the standard
+SMTP protocol names (see the description of <varname>$received_protocol</varname> in section
+<xref linkend="SECTexpvar"/>). For <option>-bs</option>, the protocol is always <quote>local-</quote> followed by
+one of those same names. For <option>-bS</option> (batched SMTP) however, the protocol can
+be set by <option>-oMr</option>. Repeated use of this option is not supported.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oMs</option> <<emphasis>host name</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oMs</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>host name, specifying for local message</secondary>
+</indexterm>
+See <option>-oMa</option> above for general remarks about the <option>-oM</option> options. The <option>-oMs</option>
+option sets the sender host name in <varname>$sender_host_name</varname>. When this option is
+present, Exim does not attempt to look up a host name from an IP address; it
+uses the name it is given.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oMt</option> <<emphasis>ident string</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oMt</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>ident string, specifying for local message</secondary>
+</indexterm>
+See <option>-oMa</option> above for general remarks about the <option>-oM</option> options. The <option>-oMt</option>
+option sets the sender ident value in <varname>$sender_ident</varname>. The default setting for
+local callers is the login id of the calling process, except when <option>-bh</option> is
+used, when there is no default.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-om</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-om</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary><option>-om</option> option ignored</secondary>
+</indexterm>
+In Sendmail, this option means <quote>me too</quote>, indicating that the sender of a
+message should receive a copy of the message if the sender appears in an alias
+expansion. Exim always does this, so the option does nothing.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oo</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oo</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary><option>-oo</option> option ignored</secondary>
+</indexterm>
+This option is ignored. In Sendmail it specifies <quote>old style headers</quote>,
+whatever that means.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oP</option> <<emphasis>path</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oP</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>pid (process id)</primary>
+<secondary>of daemon</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>daemon</primary>
+<secondary>process id (pid)</secondary>
+</indexterm>
+This option is useful only in conjunction with <option>-bd</option> or <option>-q</option> with a time
+value. The option specifies the file to which the process id of the daemon is
+written. When <option>-oX</option> is used with <option>-bd</option>, or when <option>-q</option> with a time is used
+without <option>-bd</option>, this is the only way of causing Exim to write a pid file,
+because in those cases, the normal pid file is not used.
+</para>
+</listitem></varlistentry>
+<varlistentry revisionflag="changed">
+<term><option>-oPX</option></term>
+<listitem>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>-oPX</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>pid (process id)</primary>
+<secondary>of daemon</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>daemon</primary>
+<secondary>process id (pid)</secondary>
+</indexterm>
+This option is not intended for general use.
+The daemon uses it when terminating due to a SIGTEM, possibly in
+combination with <option>-oP</option> <<emphasis>path</emphasis>>.
+It causes the pid file to be removed.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-or</option> <<emphasis>time</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-or</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>for non-SMTP input</secondary>
+</indexterm>
+This option sets a timeout value for incoming non-SMTP messages. If it is not
+set, Exim will wait forever for the standard input. The value can also be set
+by the <option>receive_timeout</option> option. The format used for specifying times is
+described in section <xref linkend="SECTtimeformat"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-os</option> <<emphasis>time</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-os</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>for SMTP input</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>input timeout</secondary>
+</indexterm>
+This option sets a timeout value for incoming SMTP messages. The timeout
+applies to each SMTP command and block of data. The value can also be set by
+the <option>smtp_receive_timeout</option> option; it defaults to 5 minutes. The format used
+for specifying times is described in section <xref linkend="SECTtimeformat"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-ov</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-ov</option></primary>
+</indexterm>
+This option has exactly the same effect as <option>-v</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-oX</option> <<emphasis>number or string</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-oX</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP/IP</primary>
+<secondary>setting listening ports</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP/IP</primary>
+<secondary>setting listening interfaces</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>port</primary>
+<secondary>receiving TCP/IP</secondary>
+</indexterm>
+This option is relevant only when the <option>-bd</option> (start listening daemon) option
+is also given. It controls which ports and interfaces the daemon uses. Details
+of the syntax, and how it interacts with configuration file options, are given
+in chapter <xref linkend="CHAPinterfaces"/>. When <option>-oX</option> is used to start a daemon, no pid
+file is written unless <option>-oP</option> is also present to specify a pid filename.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-pd</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-pd</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Perl</primary>
+<secondary>starting the interpreter</secondary>
+</indexterm>
+This option applies when an embedded Perl interpreter is linked with Exim (see
+chapter <xref linkend="CHAPperl"/>). It overrides the setting of the <option>perl_at_start</option>
+option, forcing the starting of the interpreter to be delayed until it is
+needed.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-ps</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-ps</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Perl</primary>
+<secondary>starting the interpreter</secondary>
+</indexterm>
+This option applies when an embedded Perl interpreter is linked with Exim (see
+chapter <xref linkend="CHAPperl"/>). It overrides the setting of the <option>perl_at_start</option>
+option, forcing the starting of the interpreter to occur as soon as Exim is
+started.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-p</option><<emphasis>rval</emphasis>>:<<emphasis>sval</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-p</option></primary>
+</indexterm>
+For compatibility with Sendmail, this option is equivalent to
+</para>
+<literallayout>
+<literal>-oMr</literal> <<emphasis>rval</emphasis>> <literal>-oMs</literal> <<emphasis>sval</emphasis>>
+</literallayout>
+<para>
+It sets the incoming protocol and host name (for trusted callers). The
+host name and its colon can be omitted when only the protocol is to be set.
+Note the Exim already has two private options, <option>-pd</option> and <option>-ps</option>, that refer
+to embedded Perl. It is therefore impossible to set a protocol value of <literal>d</literal>
+or <literal>s</literal> using this option (but that does not seem a real limitation).
+Repeated use of this option is not supported.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-q</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-q</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue runner</primary>
+<secondary>starting manually</secondary>
+</indexterm>
+This option is normally restricted to admin users. However, there is a
+configuration option called <option>prod_requires_admin</option> which can be set false to
+relax this restriction (and also the same requirement for the <option>-M</option>, <option>-R</option>,
+and <option>-S</option> options).
+</para>
+<para>
+<indexterm role="concept">
+<primary>queue runner</primary>
+<secondary>description of operation</secondary>
+</indexterm>
+If other commandline options do not specify an action,
+the <option>-q</option> option starts one queue runner process. This scans the queue of
+waiting messages, and runs a delivery process for each one in turn. It waits
+for each delivery process to finish before starting the next one. A delivery
+process may not actually do any deliveries if the retry times for the addresses
+have not been reached. Use <option>-qf</option> (see below) if you want to override this.
+</para>
+<para>
+If
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>passed connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>multiple deliveries</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>multiple SMTP deliveries</primary>
+</indexterm>
+the delivery process spawns other processes to deliver other messages down
+passed SMTP connections, the queue runner waits for these to finish before
+proceeding.
+</para>
+<para>
+When all the queued messages have been considered, the original queue runner
+process terminates. In other words, a single pass is made over the waiting
+mail, one message at a time. Use <option>-q</option> with a time (see below) if you want
+this to be repeated periodically.
+</para>
+<para>
+Exim processes the waiting messages in an unpredictable order. It isn’t very
+random, but it is likely to be different each time, which is all that matters.
+If one particular message screws up a remote MTA, other messages to the same
+MTA have a chance of getting through if they get tried first.
+</para>
+<para>
+It is possible to cause the messages to be processed in lexical message id
+order, which is essentially the order in which they arrived, by setting the
+<option>queue_run_in_order</option> option, but this is not recommended for normal use.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-q</option><<emphasis>qflags</emphasis>></term>
+<listitem>
+<para>
+The <option>-q</option> option may be followed by one or more flag letters that change its
+behaviour. They are all optional, but if more than one is present, they must
+appear in the correct order. Each flag is described in a separate item below.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-qq...</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-qq</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>double scanning</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>routing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>routing</primary>
+<secondary>whole queue before delivery</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>first pass routing</primary>
+</indexterm>
+An option starting with <option>-qq</option> requests a two-stage queue run. In the first
+stage, the queue is scanned as if the <option>queue_smtp_domains</option> option matched
+every domain. Addresses are routed, local deliveries happen, but no remote
+transports are run.
+</para>
+<para revisionflag="changed">
+Performance will be best if the <option>queue_run_in_order</option> option is false.
+</para>
+<para>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>remembering routing</secondary>
+</indexterm>
+The hints database that remembers which messages are waiting for specific hosts
+is updated, as if delivery to those hosts had been deferred. After this is
+complete, a second, normal queue scan happens, with routing and delivery taking
+place as normal. Messages that are routed to the same host should mostly be
+delivered down a single SMTP
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>passed connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>multiple deliveries</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>multiple SMTP deliveries</primary>
+</indexterm>
+connection because of the hints that were set up during the first queue scan.
+This option may be useful for hosts that are connected to the Internet
+intermittently.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-q[q]i...</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-qi</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>initial delivery</secondary>
+</indexterm>
+If the <emphasis>i</emphasis> flag is present, the queue runner runs delivery processes only for
+those messages that haven’t previously been tried. (<emphasis>i</emphasis> stands for <quote>initial
+delivery</quote>.) This can be helpful if you are putting messages in the queue using
+<option>-odq</option> and want a queue runner just to process the new messages.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-q[q][i]f...</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-qf</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>forcing delivery</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>forcing in queue run</secondary>
+</indexterm>
+If one <emphasis>f</emphasis> flag is present, a delivery attempt is forced for each non-frozen
+message, whereas without <emphasis>f</emphasis> only those non-frozen addresses that have passed
+their retry times are tried.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-q[q][i]ff...</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-qff</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>forcing delivery</secondary>
+</indexterm>
+If <emphasis>ff</emphasis> is present, a delivery attempt is forced for every message, whether
+frozen or not.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-q[q][i][f[f]]l</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-ql</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>local deliveries only</secondary>
+</indexterm>
+The <emphasis>l</emphasis> (the letter <quote>ell</quote>) flag specifies that only local deliveries are to
+be done. If a message requires any remote deliveries, it remains in the queue
+for later delivery.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-q[q][i][f[f]][l][G<name>[/<time>]]]</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-qG</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>named</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>named queues</primary>
+<secondary>deliver from</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>delivering specific messages</secondary>
+</indexterm>
+If the <emphasis>G</emphasis> flag and a name is present, the queue runner operates on the
+queue with the given name rather than the default queue.
+The name should not contain a <emphasis>/</emphasis> character.
+For a periodic queue run (see below)
+append to the name a slash and a time value.
+</para>
+<para>
+If other commandline options specify an action, a <emphasis>-qG<name></emphasis> option
+will specify a queue to operate on.
+For example:
+</para>
+<literallayout class="monospaced">
+exim -bp -qGquarantine
+mailq -qGquarantine
+exim -qGoffpeak -Rf @special.domain.example
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-q</option><<emphasis>qflags</emphasis>> <<emphasis>start id</emphasis>> <<emphasis>end id</emphasis>></term>
+<listitem>
+<para>
+When scanning the queue, Exim can be made to skip over messages whose ids are
+lexically less than a given value by following the <option>-q</option> option with a
+starting message id. For example:
+</para>
+<literallayout class="monospaced">
+exim -q 0t5C6f-0000c8-00
+</literallayout>
+<para>
+Messages that arrived earlier than <literal>0t5C6f-0000c8-00</literal> are not inspected. If a
+second message id is given, messages whose ids are lexically greater than it
+are also skipped. If the same id is given twice, for example,
+</para>
+<literallayout class="monospaced">
+exim -q 0t5C6f-0000c8-00 0t5C6f-0000c8-00
+</literallayout>
+<para>
+just one delivery process is started, for that message. This differs from
+<option>-M</option> in that retry data is respected, and it also differs from <option>-Mc</option> in
+that it counts as a delivery from a queue run. Note that the selection
+mechanism does not affect the order in which the messages are scanned. There
+are also other ways of selecting specific sets of messages for delivery in a
+queue run – see <option>-R</option> and <option>-S</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-q</option><<emphasis>qflags</emphasis>><<emphasis>time</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>queue runner</primary>
+<secondary>starting periodically</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>periodic queue running</primary>
+</indexterm>
+When a time value is present, the <option>-q</option> option causes Exim to run as a daemon,
+starting a queue runner process at intervals specified by the given time value
+(whose format is described in section <xref linkend="SECTtimeformat"/>). This form of the
+<option>-q</option> option is commonly combined with the <option>-bd</option> option, in which case a
+single daemon process handles both functions. A common way of starting up a
+combined daemon at system boot time is to use a command such as
+</para>
+<literallayout class="monospaced">
+/usr/exim/bin/exim -bd -q30m
+</literallayout>
+<para>
+Such a daemon listens for incoming SMTP calls, and also starts a queue runner
+process every 30 minutes.
+</para>
+<para>
+When a daemon is started by <option>-q</option> with a time value, but without <option>-bd</option>, no
+pid file is written unless one is explicitly requested by the <option>-oP</option> option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-qR</option><<emphasis>rsflags</emphasis>> <<emphasis>string</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-qR</option></primary>
+</indexterm>
+This option is synonymous with <option>-R</option>. It is provided for Sendmail
+compatibility.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-qS</option><<emphasis>rsflags</emphasis>> <<emphasis>string</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-qS</option></primary>
+</indexterm>
+This option is synonymous with <option>-S</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-R</option><<emphasis>rsflags</emphasis>> <<emphasis>string</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-R</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue runner</primary>
+<secondary>for specific recipients</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>to given domain</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain</primary>
+<secondary>delivery to</secondary>
+</indexterm>
+The <<emphasis>rsflags</emphasis>> may be empty, in which case the white space before the string
+is optional, unless the string is <emphasis>f</emphasis>, <emphasis>ff</emphasis>, <emphasis>r</emphasis>, <emphasis>rf</emphasis>, or <emphasis>rff</emphasis>,
+which are the possible values for <<emphasis>rsflags</emphasis>>. White space is required if
+<<emphasis>rsflags</emphasis>> is not empty.
+</para>
+<para>
+This option is similar to <option>-q</option> with no time value, that is, it causes Exim to
+perform a single queue run, except that, when scanning the messages on the
+queue, Exim processes only those that have at least one undelivered recipient
+address containing the given string, which is checked in a case-independent
+way. If the <<emphasis>rsflags</emphasis>> start with <emphasis>r</emphasis>, <<emphasis>string</emphasis>> is interpreted as a
+regular expression; otherwise it is a literal string.
+</para>
+<para>
+If you want to do periodic queue runs for messages with specific recipients,
+you can combine <option>-R</option> with <option>-q</option> and a time value. For example:
+</para>
+<literallayout class="monospaced">
+exim -q25m -R @special.domain.example
+</literallayout>
+<para>
+This example does a queue run for messages with recipients in the given domain
+every 25 minutes. Any additional flags that are specified with <option>-q</option> are
+applied to each queue run.
+</para>
+<para>
+Once a message is selected for delivery by this mechanism, all its addresses
+are processed. For the first selected message, Exim overrides any retry
+information and forces a delivery attempt for each undelivered address. This
+means that if delivery of any address in the first message is successful, any
+existing retry information is deleted, and so delivery attempts for that
+address in subsequently selected messages (which are processed without forcing)
+will run. However, if delivery of any address does not succeed, the retry
+information is updated, and in subsequently selected messages, the failing
+address will be skipped.
+</para>
+<para>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>forcing delivery</secondary>
+</indexterm>
+If the <<emphasis>rsflags</emphasis>> contain <emphasis>f</emphasis> or <emphasis>ff</emphasis>, the delivery forcing applies to
+all selected messages, not just the first; frozen messages are included when
+<emphasis>ff</emphasis> is present.
+</para>
+<para>
+The <option>-R</option> option makes it straightforward to initiate delivery of all messages
+to a given domain after a host has been down for some time. When the SMTP
+command ETRN is accepted by its ACL (see chapter <xref linkend="CHAPACL"/>), its default
+effect is to run Exim with the <option>-R</option> option, but it can be configured to run
+an arbitrary command instead.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-r</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-r</option></primary>
+</indexterm>
+This is a documented (for Sendmail) obsolete alternative name for <option>-f</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-S</option><<emphasis>rsflags</emphasis>> <<emphasis>string</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-S</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>from given sender</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue runner</primary>
+<secondary>for specific senders</secondary>
+</indexterm>
+This option acts like <option>-R</option> except that it checks the string against each
+message’s sender instead of against the recipients. If <option>-R</option> is also set, both
+conditions must be met for a message to be selected. If either of the options
+has <emphasis>f</emphasis> or <emphasis>ff</emphasis> in its flags, the associated action is taken.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-Tqt</option> <<emphasis>times</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-Tqt</option></primary>
+</indexterm>
+This is an option that is exclusively for use by the Exim testing suite. It is not
+recognized when Exim is run normally. It allows for the setting up of explicit
+<quote>queue times</quote> so that various warning/retry features can be tested.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-t</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-t</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>recipient</primary>
+<secondary>extracting from header lines</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>Bcc:</emphasis> header line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>Cc:</emphasis> header line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>To:</emphasis> header line</primary>
+</indexterm>
+When Exim is receiving a locally-generated, non-SMTP message on its standard
+input, the <option>-t</option> option causes the recipients of the message to be obtained
+from the <emphasis>To:</emphasis>, <emphasis>Cc:</emphasis>, and <emphasis>Bcc:</emphasis> header lines in the message instead of
+from the command arguments. The addresses are extracted before any rewriting
+takes place and the <emphasis>Bcc:</emphasis> header line, if present, is then removed.
+</para>
+<para>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary><option>-t</option> option</secondary>
+</indexterm>
+If the command has any arguments, they specify addresses to which the message
+is <emphasis>not</emphasis> to be delivered. That is, the argument addresses are removed from
+the recipients list obtained from the headers. This is compatible with Smail 3
+and in accordance with the documented behaviour of several versions of
+Sendmail, as described in man pages on a number of operating systems (e.g.
+Solaris 8, IRIX 6.5, HP-UX 11). However, some versions of Sendmail <emphasis>add</emphasis>
+argument addresses to those obtained from the headers, and the O’Reilly
+Sendmail book documents it that way. Exim can be made to add argument addresses
+instead of subtracting them by setting the option
+<option>extract_addresses_remove_arguments</option> false.
+</para>
+<para>
+<indexterm role="concept">
+<primary><option>Resent-</option> header lines</primary>
+<secondary>with <option>-t</option></secondary>
+</indexterm>
+If there are any <option>Resent-</option> header lines in the message, Exim extracts
+recipients from all <emphasis>Resent-To:</emphasis>, <emphasis>Resent-Cc:</emphasis>, and <emphasis>Resent-Bcc:</emphasis> header
+lines instead of from <emphasis>To:</emphasis>, <emphasis>Cc:</emphasis>, and <emphasis>Bcc:</emphasis>. This is for compatibility
+with Sendmail and other MTAs. (Prior to release 4.20, Exim gave an error if
+<option>-t</option> was used in conjunction with <option>Resent-</option> header lines.)
+</para>
+<para>
+RFC 2822 talks about different sets of <option>Resent-</option> header lines (for when a
+message is resent several times). The RFC also specifies that they should be
+added at the front of the message, and separated by <emphasis>Received:</emphasis> lines. It is
+not at all clear how <option>-t</option> should operate in the present of multiple sets,
+nor indeed exactly what constitutes a <quote>set</quote>.
+In practice, it seems that MUAs do not follow the RFC. The <option>Resent-</option> lines
+are often added at the end of the header, and if a message is resent more than
+once, it is common for the original set of <option>Resent-</option> headers to be renamed as
+<option>X-Resent-</option> when a new set is added. This removes any possible ambiguity.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-ti</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-ti</option></primary>
+</indexterm>
+This option is exactly equivalent to <option>-t</option> <option>-i</option>. It is provided for
+compatibility with Sendmail.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-tls-on-connect</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-tls-on-connect</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>use without STARTTLS</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>automatic start</secondary>
+</indexterm>
+This option is available when Exim is compiled with TLS support. It forces all
+incoming SMTP connections to behave as if the incoming port is listed in the
+<option>tls_on_connect_ports</option> option. See section <xref linkend="SECTsupobssmt"/> and chapter
+<xref linkend="CHAPTLS"/> for further details.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-U</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-U</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary><option>-U</option> option ignored</secondary>
+</indexterm>
+Sendmail uses this option for <quote>initial message submission</quote>, and its
+documentation states that in future releases, it may complain about
+syntactically invalid messages rather than fixing them when this flag is not
+set. Exim ignores this option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-v</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-v</option></primary>
+</indexterm>
+This option causes Exim to write information to the standard error stream,
+describing what it is doing. In particular, it shows the log lines for
+receiving and delivering a message, and if an SMTP connection is made, the SMTP
+dialogue is shown. Some of the log lines shown may not actually be written to
+the log if the setting of <option>log_selector</option> discards them. Any relevant
+selectors are shown with each log line. If none are shown, the logging is
+unconditional.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-x</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-x</option></primary>
+</indexterm>
+AIX uses <option>-x</option> for a private purpose (<quote>mail from a local mail program has
+National Language Support extended characters in the body of the mail item</quote>).
+It sets <option>-x</option> when calling the MTA from its <option>mail</option> command. Exim ignores
+this option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-X</option> <<emphasis>logfile</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-X</option></primary>
+</indexterm>
+This option is interpreted by Sendmail to cause debug information to be sent
+to the named file. It is ignored by Exim.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-z</option> <<emphasis>log-line</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-z</option></primary>
+</indexterm>
+This option writes its argument to Exim’s logfile.
+Use is restricted to administrators; the intent is for operational notes.
+Quotes should be used to maintain a multi-word item as a single argument,
+under most shells.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+<indexterm role="concept" startref="IIDclo1" class="endofrange"/>
+<indexterm role="concept" startref="IIDclo2" class="endofrange"/>
+</para>
+<!-- === End of command line options === -->
+</section>
+</chapter>
+
+<chapter id="CHAPconf">
+<title>The Exim runtime configuration file</title>
+<titleabbrev>The runtime configuration file</titleabbrev>
+<para>
+<indexterm role="concept">
+<primary>runtime configuration</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>configuration file</primary>
+<secondary>general description</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>CONFIGURE_FILE</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>configuration file</primary>
+<secondary>errors in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>error</primary>
+<secondary>in configuration file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>return code</primary>
+<secondary>for bad configuration</secondary>
+</indexterm>
+Exim uses a single runtime configuration file that is read whenever an Exim
+binary is executed. Note that in normal operation, this happens frequently,
+because Exim is designed to operate in a distributed manner, without central
+control.
+</para>
+<para>
+If a syntax error is detected while reading the configuration file, Exim
+writes a message on the standard error, and exits with a non-zero return code.
+The message is also written to the panic log. <emphasis role="bold">Note</emphasis>: Only simple syntax
+errors can be detected at this time. The values of any expanded options are
+not checked until the expansion happens, even when the expansion does not
+actually alter the string.
+</para>
+<para>
+The name of the configuration file is compiled into the binary for security
+reasons, and is specified by the CONFIGURE_FILE compilation option. In
+most configurations, this specifies a single file. However, it is permitted to
+give a colon-separated list of filenames, in which case Exim uses the first
+existing file in the list.
+</para>
+<para>
+<indexterm role="concept">
+<primary>EXIM_USER</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>EXIM_GROUP</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>CONFIGURE_OWNER</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>CONFIGURE_GROUP</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>configuration file</primary>
+<secondary>ownership</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ownership</primary>
+<secondary>configuration file</secondary>
+</indexterm>
+The runtime configuration file must be owned by root or by the user that is
+specified at compile time by the CONFIGURE_OWNER option (if set). The
+configuration file must not be world-writeable, or group-writeable unless its
+group is the root group or the one specified at compile time by the
+CONFIGURE_GROUP option.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: In a conventional configuration, where the Exim binary is setuid
+to root, anybody who is able to edit the runtime configuration file has an
+easy way to run commands as root. If you specify a user or group in the
+CONFIGURE_OWNER or CONFIGURE_GROUP options, then that user and/or any users
+who are members of that group will trivially be able to obtain root privileges.
+</para>
+<para>
+Up to Exim version 4.72, the runtime configuration file was also permitted to
+be writeable by the Exim user and/or group. That has been changed in Exim 4.73
+since it offered a simple privilege escalation for any attacker who managed to
+compromise the Exim user account.
+</para>
+<para>
+A default configuration file, which will work correctly in simple situations,
+is provided in the file <filename>src/configure.default</filename>. If CONFIGURE_FILE
+defines just one filename, the installation process copies the default
+configuration to a new file of that name if it did not previously exist. If
+CONFIGURE_FILE is a list, no default is automatically installed. Chapter
+<xref linkend="CHAPdefconfil"/> is a <quote>walk-through</quote> discussion of the default
+configuration.
+</para>
+<section id="SECID40">
+<title>Using a different configuration file</title>
+<para>
+<indexterm role="concept">
+<primary>configuration file</primary>
+<secondary>alternate</secondary>
+</indexterm>
+A one-off alternate configuration can be specified by the <option>-C</option> command line
+option, which may specify a single file or a list of files. However, when
+<option>-C</option> is used, Exim gives up its root privilege, unless called by root (or
+unless the argument for <option>-C</option> is identical to the built-in value from
+CONFIGURE_FILE), or is listed in the TRUSTED_CONFIG_LIST file and the caller
+is the Exim user or the user specified in the CONFIGURE_OWNER setting. <option>-C</option>
+is useful mainly for checking the syntax of configuration files before
+installing them. No owner or group checks are done on a configuration file
+specified by <option>-C</option>, if root privilege has been dropped.
+</para>
+<para>
+Even the Exim user is not trusted to specify an arbitrary configuration file
+with the <option>-C</option> option to be used with root privileges, unless that file is
+listed in the TRUSTED_CONFIG_LIST file. This locks out the possibility of
+testing a configuration using <option>-C</option> right through message reception and
+delivery, even if the caller is root. The reception works, but by that time,
+Exim is running as the Exim user, so when it re-execs to regain privilege for
+the delivery, the use of <option>-C</option> causes privilege to be lost. However, root
+can test reception and delivery using two separate commands (one to put a
+message in the queue, using <option>-odq</option>, and another to do the delivery, using
+<option>-M</option>).
+</para>
+<para>
+If ALT_CONFIG_PREFIX is defined <filename>in Local/Makefile</filename>, it specifies a
+prefix string with which any file named in a <option>-C</option> command line option must
+start. In addition, the filename must not contain the sequence <quote><literal>/../</literal></quote>.
+There is no default setting for ALT_CONFIG_PREFIX; when it is unset, any
+filename can be used with <option>-C</option>.
+</para>
+<para>
+One-off changes to a configuration can be specified by the <option>-D</option> command line
+option, which defines and overrides values for macros used inside the
+configuration file. However, like <option>-C</option>, the use of this option by a
+non-privileged user causes Exim to discard its root privilege.
+If DISABLE_D_OPTION is defined in <filename>Local/Makefile</filename>, the use of <option>-D</option> is
+completely disabled, and its use causes an immediate error exit.
+</para>
+<para>
+The WHITELIST_D_MACROS option in <filename>Local/Makefile</filename> permits the binary builder
+to declare certain macro names trusted, such that root privilege will not
+necessarily be discarded.
+WHITELIST_D_MACROS defines a colon-separated list of macros which are
+considered safe and, if <option>-D</option> only supplies macros from this list, and the
+values are acceptable, then Exim will not give up root privilege if the caller
+is root, the Exim run-time user, or the CONFIGURE_OWNER, if set. This is a
+transition mechanism and is expected to be removed in the future. Acceptable
+values for the macros satisfy the regexp: <literal>^[A-Za-z0-9_/.-]*$</literal>
+</para>
+<para>
+Some sites may wish to use the same Exim binary on different machines that
+share a file system, but to use different configuration files on each machine.
+If CONFIGURE_FILE_USE_NODE is defined in <filename>Local/Makefile</filename>, Exim first
+looks for a file whose name is the configuration filename followed by a dot
+and the machine’s node name, as obtained from the <function>uname()</function> function. If this
+file does not exist, the standard name is tried. This processing occurs for
+each filename in the list given by CONFIGURE_FILE or <option>-C</option>.
+</para>
+<para>
+In some esoteric situations different versions of Exim may be run under
+different effective uids and the CONFIGURE_FILE_USE_EUID is defined to
+help with this. See the comments in <filename>src/EDITME</filename> for details.
+</para>
+</section>
+<section id="SECTconffilfor">
+<title>Configuration file format</title>
+<para>
+<indexterm role="concept">
+<primary>configuration file</primary>
+<secondary>format of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>format</primary>
+<secondary>configuration file</secondary>
+</indexterm>
+Exim’s configuration file is divided into a number of different parts. General
+option settings must always appear at the start of the file. The other parts
+are all optional, and may appear in any order. Each part other than the first
+is introduced by the word <quote>begin</quote> followed by at least one literal
+space, and the name of the part. The optional parts are:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<emphasis>ACL</emphasis>: Access control lists for controlling incoming SMTP mail (see chapter
+<xref linkend="CHAPACL"/>).
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>configuration</secondary>
+</indexterm>
+<emphasis>authenticators</emphasis>: Configuration settings for the authenticator drivers. These
+are concerned with the SMTP AUTH command (see chapter <xref linkend="CHAPSMTPAUTH"/>).
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>routers</emphasis>: Configuration settings for the router drivers. Routers process
+addresses and determine how the message is to be delivered (see chapters
+<xref linkend="CHAProutergeneric"/>–<xref linkend="CHAPredirect"/>).
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>transports</emphasis>: Configuration settings for the transport drivers. Transports
+define mechanisms for copying messages to destinations (see chapters
+<xref linkend="CHAPtransportgeneric"/>–<xref linkend="CHAPsmtptrans"/>).
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>retry</emphasis>: Retry rules, for use when a message cannot be delivered immediately.
+If there is no retry section, or if it is empty (that is, no retry rules are
+defined), Exim will not retry deliveries. In this situation, temporary errors
+are treated the same as permanent errors. Retry rules are discussed in chapter
+<xref linkend="CHAPretry"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>rewrite</emphasis>: Global address rewriting rules, for use when a message arrives and
+when new addresses are generated during delivery. Rewriting is discussed in
+chapter <xref linkend="CHAPrewrite"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>local_scan</emphasis>: Private options for the <function>local_scan()</function> function. If you
+want to use this feature, you must set
+</para>
+<literallayout class="monospaced">
+LOCAL_SCAN_HAS_OPTIONS=yes
+</literallayout>
+<para>
+in <filename>Local/Makefile</filename> before building Exim. Details of the <function>local_scan()</function>
+facility are given in chapter <xref linkend="CHAPlocalscan"/>.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+<indexterm role="concept">
+<primary>configuration file</primary>
+<secondary>leading white space in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>configuration file</primary>
+<secondary>trailing white space in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>white space</primary>
+<secondary>in configuration file</secondary>
+</indexterm>
+Leading and trailing white space in configuration lines is always ignored.
+</para>
+<para>
+Blank lines in the file, and lines starting with a # character (ignoring
+leading white space) are treated as comments and are ignored. <emphasis role="bold">Note</emphasis>: A
+# character other than at the beginning of a line is not treated specially,
+and does not introduce a comment.
+</para>
+<para>
+Any non-comment line can be continued by ending it with a backslash. Note that
+the general rule for white space means that trailing white space after the
+backslash and leading white space at the start of continuation
+lines is ignored. Comment lines beginning with # (but not empty lines) may
+appear in the middle of a sequence of continuation lines.
+</para>
+<para>
+A convenient way to create a configuration file is to start from the
+default, which is supplied in <filename>src/configure.default</filename>, and add, delete, or
+change settings as required.
+</para>
+<para>
+The ACLs, retry rules, and rewriting rules have their own syntax which is
+described in chapters <xref linkend="CHAPACL"/>, <xref linkend="CHAPretry"/>, and <xref linkend="CHAPrewrite"/>,
+respectively. The other parts of the configuration file have some syntactic
+items in common, and these are described below, from section <xref linkend="SECTcos"/>
+onwards. Before that, the inclusion, macro, and conditional facilities are
+described.
+</para>
+</section>
+<section id="SECID41">
+<title>File inclusions in the configuration file</title>
+<para>
+<indexterm role="concept">
+<primary>inclusions in configuration file</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>configuration file</primary>
+<secondary>including other files</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><literal>.include</literal> in configuration file</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><literal>.include_if_exists</literal> in configuration file</primary>
+</indexterm>
+You can include other files inside Exim’s runtime configuration file by
+using this syntax:
+</para>
+<literallayout>
+<literal>.include</literal> <<emphasis>filename</emphasis>>
+<literal>.include_if_exists</literal> <<emphasis>filename</emphasis>>
+</literallayout>
+<para>
+on a line by itself. Double quotes round the filename are optional. If you use
+the first form, a configuration error occurs if the file does not exist; the
+second form does nothing for non-existent files.
+The first form allows a relative name. It is resolved relative to
+the directory of the including file. For the second form an absolute filename
+is required.
+</para>
+<para>
+Includes may be nested to any depth, but remember that Exim reads its
+configuration file often, so it is a good idea to keep them to a minimum.
+If you change the contents of an included file, you must HUP the daemon,
+because an included file is read only when the configuration itself is read.
+</para>
+<para>
+The processing of inclusions happens early, at a physical line level, so, like
+comment lines, an inclusion can be used in the middle of an option setting,
+for example:
+</para>
+<literallayout class="monospaced">
+hosts_lookup = a.b.c \
+ .include /some/file
+</literallayout>
+<para>
+Include processing happens after macro processing (see below). Its effect is to
+process the lines of the included file as if they occurred inline where the
+inclusion appears.
+</para>
+</section>
+<section id="SECTmacrodefs">
+<title>Macros in the configuration file</title>
+<para>
+<indexterm role="concept">
+<primary>macro</primary>
+<secondary>description of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>configuration file</primary>
+<secondary>macros</secondary>
+</indexterm>
+If a line in the main part of the configuration (that is, before the first
+<quote>begin</quote> line) begins with an upper case letter, it is taken as a macro
+definition, and must be of the form
+</para>
+<literallayout>
+<<emphasis>name</emphasis>> = <<emphasis>rest of line</emphasis>>
+</literallayout>
+<para>
+The name must consist of letters, digits, and underscores, and need not all be
+in upper case, though that is recommended. The rest of the line, including any
+continuations, is the replacement text, and has leading and trailing white
+space removed. Quotes are not removed. The replacement text can never end with
+a backslash character, but this doesn’t seem to be a serious limitation.
+</para>
+<para>
+Macros may also be defined between router, transport, authenticator, or ACL
+definitions. They may not, however, be defined within an individual driver or
+ACL, or in the <option>local_scan</option>, retry, or rewrite sections of the configuration.
+</para>
+</section>
+<section id="SECID42">
+<title>Macro substitution</title>
+<para>
+Once a macro is defined, all subsequent lines in the file (and any included
+files) are scanned for the macro name; if there are several macros, the line is
+scanned for each, in turn, in the order in which the macros are defined. The
+replacement text is not re-scanned for the current macro, though it is scanned
+for subsequently defined macros. For this reason, a macro name may not contain
+the name of a previously defined macro as a substring. You could, for example,
+define
+</para>
+<literallayout>
+<literal>ABCD_XYZ = </literal><<emphasis>something</emphasis>>
+<literal>ABCD = </literal><<emphasis>something else</emphasis>>
+</literallayout>
+<para>
+but putting the definitions in the opposite order would provoke a configuration
+error. Macro expansion is applied to individual physical lines from the file,
+before checking for line continuation or file inclusion (see above). If a line
+consists solely of a macro name, and the expansion of the macro is empty, the
+line is ignored. A macro at the start of a line may turn the line into a
+comment line or a <literal>.include</literal> line.
+</para>
+</section>
+<section id="SECID43">
+<title>Redefining macros</title>
+<para>
+Once defined, the value of a macro can be redefined later in the configuration
+(or in an included file). Redefinition is specified by using <emphasis>==</emphasis> instead of
+<emphasis>=</emphasis>. For example:
+</para>
+<literallayout class="monospaced">
+MAC = initial value
+...
+MAC == updated value
+</literallayout>
+<para>
+Redefinition does not alter the order in which the macros are applied to the
+subsequent lines of the configuration file. It is still the same order in which
+the macros were originally defined. All that changes is the macro’s value.
+Redefinition makes it possible to accumulate values. For example:
+</para>
+<literallayout class="monospaced">
+MAC = initial value
+...
+MAC == MAC and something added
+</literallayout>
+<para>
+This can be helpful in situations where the configuration file is built
+from a number of other files.
+</para>
+</section>
+<section id="SECID44">
+<title>Overriding macro values</title>
+<para>
+The values set for macros in the configuration file can be overridden by the
+<option>-D</option> command line option, but Exim gives up its root privilege when <option>-D</option> is
+used, unless called by root or the Exim user. A definition on the command line
+using the <option>-D</option> option causes all definitions and redefinitions within the
+file to be ignored.
+</para>
+</section>
+<section id="SECID45">
+<title>Example of macro usage</title>
+<para>
+As an example of macro usage, consider a configuration where aliases are looked
+up in a MySQL database. It helps to keep the file less cluttered if long
+strings such as SQL statements are defined separately as macros, for example:
+</para>
+<literallayout class="monospaced">
+ALIAS_QUERY = select mailbox from user where \
+ login='${quote_mysql:$local_part}';
+</literallayout>
+<para>
+This can then be used in a <command>redirect</command> router setting like this:
+</para>
+<literallayout class="monospaced">
+data = ${lookup mysql{ALIAS_QUERY}}
+</literallayout>
+<para>
+In earlier versions of Exim macros were sometimes used for domain, host, or
+address lists. In Exim 4 these are handled better by named lists – see
+section <xref linkend="SECTnamedlists"/>.
+</para>
+</section>
+<section id="SECTbuiltinmacros">
+<title>Builtin macros</title>
+<para>
+Exim defines some macros depending on facilities available, which may
+differ due to build-time definitions and from one release to another.
+All of these macros start with an underscore.
+They can be used to conditionally include parts of a configuration
+(see below).
+</para>
+<para>
+The following classes of macros are defined:
+</para>
+<literallayout>
+<literal> _HAVE_* </literal> build-time defines
+<literal> _DRIVER_ROUTER_* </literal> router drivers
+<literal> _DRIVER_TRANSPORT_* </literal> transport drivers
+<literal> _DRIVER_AUTHENTICATOR_* </literal> authenticator drivers
+<literal> _LOG_* </literal> log_selector values
+<literal> _OPT_MAIN_* </literal> main config options
+<literal> _OPT_ROUTERS_* </literal> generic router options
+<literal> _OPT_TRANSPORTS_* </literal> generic transport options
+<literal> _OPT_AUTHENTICATORS_* </literal> generic authenticator options
+<literal> _OPT_ROUTER_*_* </literal> private router options
+<literal> _OPT_TRANSPORT_*_* </literal> private transport options
+<literal> _OPT_AUTHENTICATOR_*_* </literal> private authenticator options
+</literallayout>
+<para>
+Use an <quote>exim -bP macros</quote> command to get the list of macros.
+</para>
+</section>
+<section id="SECID46">
+<title>Conditional skips in the configuration file</title>
+<para>
+<indexterm role="concept">
+<primary>configuration file</primary>
+<secondary>conditional skips</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><literal>.ifdef</literal></primary>
+</indexterm>
+You can use the directives <literal>.ifdef</literal>, <literal>.ifndef</literal>, <literal>.elifdef</literal>,
+<literal>.elifndef</literal>, <literal>.else</literal>, and <literal>.endif</literal> to dynamically include or exclude
+portions of the configuration file. The processing happens whenever the file is
+read (that is, when an Exim binary starts to run).
+</para>
+<para>
+The implementation is very simple. Instances of the first four directives must
+be followed by text that includes the names of one or macros. The condition
+that is tested is whether or not any macro substitution has taken place in the
+line. Thus:
+</para>
+<literallayout class="monospaced">
+.ifdef AAA
+message_size_limit = 50M
+.else
+message_size_limit = 100M
+.endif
+</literallayout>
+<para>
+sets a message size limit of 50M if the macro <literal>AAA</literal> is defined
+(or <literal>A</literal> or <literal>AA</literal>), and 100M
+otherwise. If there is more than one macro named on the line, the condition
+is true if any of them are defined. That is, it is an <quote>or</quote> condition. To
+obtain an <quote>and</quote> condition, you need to use nested <literal>.ifdef</literal>s.
+</para>
+<para>
+Although you can use a macro expansion to generate one of these directives,
+it is not very useful, because the condition <quote>there was a macro substitution
+in this line</quote> will always be true.
+</para>
+<para>
+Text following <literal>.else</literal> and <literal>.endif</literal> is ignored, and can be used as comment
+to clarify complicated nestings.
+</para>
+</section>
+<section id="SECTcos">
+<title>Common option syntax</title>
+<para>
+<indexterm role="concept">
+<primary>common option syntax</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>syntax of common options</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>configuration file</primary>
+<secondary>common option syntax</secondary>
+</indexterm>
+For the main set of options, driver options, and <function>local_scan()</function> options,
+each setting is on a line by itself, and starts with a name consisting of
+lower-case letters and underscores. Many options require a data value, and in
+these cases the name must be followed by an equals sign (with optional white
+space) and then the value. For example:
+</para>
+<literallayout class="monospaced">
+qualify_domain = mydomain.example.com
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>hiding configuration option values</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>configuration options</primary>
+<secondary>hiding value of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary>hiding value of</secondary>
+</indexterm>
+Some option settings may contain sensitive data, for example, passwords for
+accessing databases. To stop non-admin users from using the <option>-bP</option> command
+line option to read these values, you can precede the option settings with the
+word <quote>hide</quote>. For example:
+</para>
+<literallayout class="monospaced">
+hide mysql_servers = localhost/users/admin/secret-password
+</literallayout>
+<para>
+For non-admin users, such options are displayed like this:
+</para>
+<literallayout class="monospaced">
+mysql_servers = <value not displayable>
+</literallayout>
+<para>
+If <quote>hide</quote> is used on a driver option, it hides the value of that option on
+all instances of the same driver.
+</para>
+<para>
+The following sections describe the syntax used for the different data types
+that are found in option settings.
+</para>
+</section>
+<section id="SECID47">
+<title>Boolean options</title>
+<para>
+<indexterm role="concept">
+<primary>format</primary>
+<secondary>boolean</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>boolean configuration values</primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>no_</option><emphasis>xxx</emphasis></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>not_</option><emphasis>xxx</emphasis></primary>
+</indexterm>
+Options whose type is given as boolean are on/off switches. There are two
+different ways of specifying such options: with and without a data value. If
+the option name is specified on its own without data, the switch is turned on;
+if it is preceded by <quote>no_</quote> or <quote>not_</quote> the switch is turned off. However,
+boolean options may be followed by an equals sign and one of the words
+<quote>true</quote>, <quote>false</quote>, <quote>yes</quote>, or <quote>no</quote>, as an alternative syntax. For example,
+the following two settings have exactly the same effect:
+</para>
+<literallayout class="monospaced">
+queue_only
+queue_only = true
+</literallayout>
+<para>
+The following two lines also have the same (opposite) effect:
+</para>
+<literallayout class="monospaced">
+no_queue_only
+queue_only = false
+</literallayout>
+<para>
+You can use whichever syntax you prefer.
+</para>
+</section>
+<section id="SECID48">
+<title>Integer values</title>
+<para>
+<indexterm role="concept">
+<primary>integer configuration values</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>format</primary>
+<secondary>integer</secondary>
+</indexterm>
+If an option’s type is given as <quote>integer</quote>, the value can be given in decimal,
+hexadecimal, or octal. If it starts with a digit greater than zero, a decimal
+number is assumed. Otherwise, it is treated as an octal number unless it starts
+with the characters <quote>0x</quote>, in which case the remainder is interpreted as a
+hexadecimal number.
+</para>
+<para>
+If an integer value is followed by the letter K, it is multiplied by 1024; if
+it is followed by the letter M, it is multiplied by 1024x1024;
+if by the letter G, 1024x1024x1024.
+When the values
+of integer option settings are output, values which are an exact multiple of
+1024 or 1024x1024 are sometimes, but not always, printed using the letters K
+and M. The printing style is independent of the actual input format that was
+used.
+</para>
+</section>
+<section id="SECID49">
+<title>Octal integer values</title>
+<para>
+<indexterm role="concept">
+<primary>integer format</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>format</primary>
+<secondary>octal integer</secondary>
+</indexterm>
+If an option’s type is given as <quote>octal integer</quote>, its value is always
+interpreted as an octal number, whether or not it starts with the digit zero.
+Such options are always output in octal.
+</para>
+</section>
+<section id="SECID50">
+<title>Fixed point numbers</title>
+<para>
+<indexterm role="concept">
+<primary>fixed point configuration values</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>format</primary>
+<secondary>fixed point</secondary>
+</indexterm>
+If an option’s type is given as <quote>fixed-point</quote>, its value must be a decimal
+integer, optionally followed by a decimal point and up to three further digits.
+</para>
+</section>
+<section id="SECTtimeformat">
+<title>Time intervals</title>
+<para>
+<indexterm role="concept">
+<primary>time interval</primary>
+<secondary>specifying in configuration</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>format</primary>
+<secondary>time interval</secondary>
+</indexterm>
+A time interval is specified as a sequence of numbers, each followed by one of
+the following letters, with no intervening white space:
+</para>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="30pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry> <option>s</option></entry>
+<entry>seconds</entry>
+</row>
+<row>
+<entry> <option>m</option></entry>
+<entry>minutes</entry>
+</row>
+<row>
+<entry> <option>h</option></entry>
+<entry>hours</entry>
+</row>
+<row>
+<entry> <option>d</option></entry>
+<entry>days</entry>
+</row>
+<row>
+<entry> <option>w</option></entry>
+<entry>weeks</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+For example, <quote>3h50m</quote> specifies 3 hours and 50 minutes. The values of time
+intervals are output in the same format. Exim does not restrict the values; it
+is perfectly acceptable, for example, to specify <quote>90m</quote> instead of <quote>1h30m</quote>.
+</para>
+</section>
+<section id="SECTstrings">
+<title>String values</title>
+<para>
+<indexterm role="concept">
+<primary>string</primary>
+<secondary>format of configuration values</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>format</primary>
+<secondary>string</secondary>
+</indexterm>
+If an option’s type is specified as <quote>string</quote>, the value can be specified with
+or without double-quotes. If it does not start with a double-quote, the value
+consists of the remainder of the line plus any continuation lines, starting at
+the first character after any leading white space, with trailing white space
+removed, and with no interpretation of the characters in the string. Because
+Exim removes comment lines (those beginning with #) at an early stage, they can
+appear in the middle of a multi-line string. The following two settings are
+therefore equivalent:
+</para>
+<literallayout class="monospaced">
+trusted_users = uucp:mail
+trusted_users = uucp:\
+ # This comment line is ignored
+ mail
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>string</primary>
+<secondary>quoted</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>escape characters in quoted strings</primary>
+</indexterm>
+If a string does start with a double-quote, it must end with a closing
+double-quote, and any backslash characters other than those used for line
+continuation are interpreted as escape characters, as follows:
+</para>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="100pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry> <literal>\\</literal></entry>
+<entry>single backslash</entry>
+</row>
+<row>
+<entry> <literal>\n</literal></entry>
+<entry>newline</entry>
+</row>
+<row>
+<entry> <literal>\r</literal></entry>
+<entry>carriage return</entry>
+</row>
+<row>
+<entry> <literal>\t</literal></entry>
+<entry>tab</entry>
+</row>
+<row>
+<entry> <literal>\</literal><<emphasis>octal digits</emphasis>></entry>
+<entry>up to 3 octal digits specify one character</entry>
+</row>
+<row>
+<entry> <literal>\x</literal><<emphasis>hex digits</emphasis>></entry>
+<entry>up to 2 hexadecimal digits specify one character</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If a backslash is followed by some other character, including a double-quote
+character, that character replaces the pair.
+</para>
+<para>
+Quoting is necessary only if you want to make use of the backslash escapes to
+insert special characters, or if you need to specify a value with leading or
+trailing spaces. These cases are rare, so quoting is almost never needed in
+current versions of Exim. In versions of Exim before 3.14, quoting was required
+in order to continue lines, so you may come across older configuration files
+and examples that apparently quote unnecessarily.
+</para>
+</section>
+<section id="SECID51">
+<title>Expanded strings</title>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>definition of</secondary>
+</indexterm>
+Some strings in the configuration file are subjected to <emphasis>string expansion</emphasis>,
+by which means various parts of the string may be changed according to the
+circumstances (see chapter <xref linkend="CHAPexpand"/>). The input syntax for such strings
+is as just described; in particular, the handling of backslashes in quoted
+strings is done as part of the input process, before expansion takes place.
+However, backslash is also an escape character for the expander, so any
+backslashes that are required for that reason must be doubled if they are
+within a quoted configuration string.
+</para>
+</section>
+<section id="SECID52">
+<title>User and group names</title>
+<para>
+<indexterm role="concept">
+<primary>user name</primary>
+<secondary>format of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>format</primary>
+<secondary>user name</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>groups</primary>
+<secondary>name format</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>format</primary>
+<secondary>group name</secondary>
+</indexterm>
+User and group names are specified as strings, using the syntax described
+above, but the strings are interpreted specially. A user or group name must
+either consist entirely of digits, or be a name that can be looked up using the
+<function>getpwnam()</function> or <function>getgrnam()</function> function, as appropriate.
+</para>
+</section>
+<section id="SECTlistconstruct">
+<title>List construction</title>
+<para>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>syntax of in configuration</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>format</primary>
+<secondary>list item in configuration</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>string</primary>
+<secondary>list, definition of</secondary>
+</indexterm>
+The data for some configuration options is a list of items, with colon as the
+default separator. Many of these options are shown with type <quote>string list</quote> in
+the descriptions later in this document. Others are listed as <quote>domain list</quote>,
+<quote>host list</quote>, <quote>address list</quote>, or <quote>local part list</quote>. Syntactically, they
+are all the same; however, those other than <quote>string list</quote> are subject to
+particular kinds of interpretation, as described in chapter
+<xref linkend="CHAPdomhosaddlists"/>.
+</para>
+<para>
+In all these cases, the entire list is treated as a single string as far as the
+input syntax is concerned. The <option>trusted_users</option> setting in section
+<xref linkend="SECTstrings"/> above is an example. If a colon is actually needed in an item
+in a list, it must be entered as two colons. Leading and trailing white space
+on each item in a list is ignored. This makes it possible to include items that
+start with a colon, and in particular, certain forms of IPv6 address. For
+example, the list
+</para>
+<literallayout class="monospaced">
+local_interfaces = 127.0.0.1 : ::::1
+</literallayout>
+<para>
+contains two IP addresses, the IPv4 address 127.0.0.1 and the IPv6 address ::1.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: Although leading and trailing white space is ignored in individual
+list items, it is not ignored when parsing the list. The space after the first
+colon in the example above is necessary. If it were not there, the list would
+be interpreted as the two items 127.0.0.1:: and 1.
+</para>
+</section>
+<section id="SECTlistsepchange">
+<title>Changing list separators</title>
+<para>
+<indexterm role="concept">
+<primary>list separator</primary>
+<secondary>changing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>IPv6</primary>
+<secondary>addresses in lists</secondary>
+</indexterm>
+Doubling colons in IPv6 addresses is an unwelcome chore, so a mechanism was
+introduced to allow the separator character to be changed. If a list begins
+with a left angle bracket, followed by any punctuation character, that
+character is used instead of colon as the list separator. For example, the list
+above can be rewritten to use a semicolon separator like this:
+</para>
+<literallayout class="monospaced">
+local_interfaces = <; 127.0.0.1 ; ::1
+</literallayout>
+<para>
+This facility applies to all lists, with the exception of the list in
+<option>log_file_path</option>. It is recommended that the use of non-colon separators be
+confined to circumstances where they really are needed.
+</para>
+<para>
+<indexterm role="concept">
+<primary>list separator</primary>
+<secondary>newline as</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>newline</primary>
+<secondary>as list separator</secondary>
+</indexterm>
+It is also possible to use newline and other control characters (those with
+code values less than 32, plus DEL) as separators in lists. Such separators
+must be provided literally at the time the list is processed. For options that
+are string-expanded, you can write the separator using a normal escape
+sequence. This will be processed by the expander before the string is
+interpreted as a list. For example, if a newline-separated list of domains is
+generated by a lookup, you can process it directly by a line such as this:
+</para>
+<literallayout class="monospaced">
+domains = <\n ${lookup mysql{.....}}
+</literallayout>
+<para>
+This avoids having to change the list separator in such data. You are unlikely
+to want to use a control character as a separator in an option that is not
+expanded, because the value is literal text. However, it can be done by giving
+the value in quotes. For example:
+</para>
+<literallayout class="monospaced">
+local_interfaces = "<\n 127.0.0.1 \n ::1"
+</literallayout>
+<para>
+Unlike printing character separators, which can be included in list items by
+doubling, it is not possible to include a control character as data when it is
+set as the separator. Two such characters in succession are interpreted as
+enclosing an empty list item.
+</para>
+</section>
+<section id="SECTempitelis">
+<title>Empty items in lists</title>
+<para>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>empty item in</secondary>
+</indexterm>
+An empty item at the end of a list is always ignored. In other words, trailing
+separator characters are ignored. Thus, the list in
+</para>
+<literallayout class="monospaced">
+senders = user@domain :
+</literallayout>
+<para>
+contains only a single item. If you want to include an empty string as one item
+in a list, it must not be the last item. For example, this list contains three
+items, the second of which is empty:
+</para>
+<literallayout class="monospaced">
+senders = user1@domain : : user2@domain
+</literallayout>
+<para>
+<emphasis role="bold">Note</emphasis>: There must be white space between the two colons, as otherwise they
+are interpreted as representing a single colon data character (and the list
+would then contain just one item). If you want to specify a list that contains
+just one, empty item, you can do it as in this example:
+</para>
+<literallayout class="monospaced">
+senders = :
+</literallayout>
+<para>
+In this case, the first item is empty, and the second is discarded because it
+is at the end of the list.
+</para>
+</section>
+<section id="SECTfordricon">
+<title>Format of driver configurations</title>
+<para>
+<indexterm role="concept">
+<primary>drivers</primary>
+<secondary>configuration format</secondary>
+</indexterm>
+There are separate parts in the configuration for defining routers, transports,
+and authenticators. In each part, you are defining a number of driver
+instances, each with its own set of options. Each driver instance is defined by
+a sequence of lines like this:
+</para>
+<literallayout>
+<<emphasis>instance name</emphasis>>:
+ <<emphasis>option</emphasis>>
+ ...
+ <<emphasis>option</emphasis>>
+</literallayout>
+<para>
+In the following example, the instance name is <command>localuser</command>, and it is
+followed by three options settings:
+</para>
+<literallayout class="monospaced">
+localuser:
+ driver = accept
+ check_local_user
+ transport = local_delivery
+</literallayout>
+<para>
+For each driver instance, you specify which Exim code module it uses – by the
+setting of the <option>driver</option> option – and (optionally) some configuration
+settings. For example, in the case of transports, if you want a transport to
+deliver with SMTP you would use the <command>smtp</command> driver; if you want to deliver to
+a local file you would use the <command>appendfile</command> driver. Each of the drivers is
+described in detail in its own separate chapter later in this manual.
+</para>
+<para>
+You can have several routers, transports, or authenticators that are based on
+the same underlying driver (each must have a different instance name).
+</para>
+<para>
+The order in which routers are defined is important, because addresses are
+passed to individual routers one by one, in order. The order in which
+transports are defined does not matter at all. The order in which
+authenticators are defined is used only when Exim, as a client, is searching
+them to find one that matches an authentication mechanism offered by the
+server.
+</para>
+<para>
+<indexterm role="concept">
+<primary>generic options</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary>generic – definition of</secondary>
+</indexterm>
+Within a driver instance definition, there are two kinds of option: <emphasis>generic</emphasis>
+and <emphasis>private</emphasis>. The generic options are those that apply to all drivers of the
+same type (that is, all routers, all transports or all authenticators). The
+<option>driver</option> option is a generic option that must appear in every definition.
+<indexterm role="concept">
+<primary>private options</primary>
+</indexterm>
+The private options are special for each driver, and none need appear, because
+they all have default values.
+</para>
+<para>
+The options may appear in any order, except that the <option>driver</option> option must
+precede any private options, since these depend on the particular driver. For
+this reason, it is recommended that <option>driver</option> always be the first option.
+</para>
+<para>
+Driver instance names, which are used for reference in log entries and
+elsewhere, can be any sequence of letters, digits, and underscores (starting
+with a letter) and must be unique among drivers of the same type. A router and
+a transport (for example) can each have the same name, but no two router
+instances can have the same name. The name of a driver instance should not be
+confused with the name of the underlying driver module. For example, the
+configuration lines:
+</para>
+<literallayout class="monospaced">
+remote_smtp:
+ driver = smtp
+</literallayout>
+<para>
+create an instance of the <command>smtp</command> transport driver whose name is
+<command>remote_smtp</command>. The same driver code can be used more than once, with
+different instance names and different option settings each time. A second
+instance of the <command>smtp</command> transport, with different options, might be defined
+thus:
+</para>
+<literallayout class="monospaced">
+special_smtp:
+ driver = smtp
+ port = 1234
+ command_timeout = 10s
+</literallayout>
+<para>
+The names <command>remote_smtp</command> and <command>special_smtp</command> would be used to reference
+these transport instances from routers, and these names would appear in log
+lines.
+</para>
+<para>
+Comment lines may be present in the middle of driver specifications. The full
+list of option settings for any particular driver instance, including all the
+defaulted values, can be extracted by making use of the <option>-bP</option> command line
+option.
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPdefconfil">
+<title>The default configuration file</title>
+<para>
+<indexterm role="concept" id="IIDconfiwal" class="startofrange">
+<primary>configuration file</primary>
+<secondary>default <quote>walk through</quote></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>default</primary>
+<secondary>configuration file <quote>walk through</quote></secondary>
+</indexterm>
+The default configuration file supplied with Exim as <filename>src/configure.default</filename>
+is sufficient for a host with simple mail requirements. As an introduction to
+the way Exim is configured, this chapter <quote>walks through</quote> the default
+configuration, giving brief explanations of the settings. Detailed descriptions
+of the options are given in subsequent chapters. The default configuration file
+itself contains extensive comments about ways you might want to modify the
+initial settings. However, note that there are many options that are not
+mentioned at all in the default configuration.
+</para>
+<section id="SECTdefconfmacros">
+<title>Macros</title>
+<para>
+All macros should be defined before any options.
+</para>
+<para>
+One macro is specified, but commented out, in the default configuration:
+</para>
+<literallayout class="monospaced">
+# ROUTER_SMARTHOST=MAIL.HOSTNAME.FOR.CENTRAL.SERVER.EXAMPLE
+</literallayout>
+<para>
+If all off-site mail is expected to be delivered to a "smarthost", then set the
+hostname here and uncomment the macro. This will affect which router is used
+later on. If this is left commented out, then Exim will perform direct-to-MX
+deliveries using a <command>dnslookup</command> router.
+</para>
+<para>
+In addition to macros defined here, Exim includes a number of built-in macros
+to enable configuration to be guarded by a binary built with support for a
+given feature. See section <xref linkend="SECTbuiltinmacros"/> for more details.
+</para>
+</section>
+<section id="SECTdefconfmain">
+<title>Main configuration settings</title>
+<para>
+The main (global) configuration option settings section must always come first
+in the file, after the macros.
+The first thing you’ll see in the file, after some initial comments, is the line
+</para>
+<literallayout class="monospaced">
+# primary_hostname =
+</literallayout>
+<para>
+This is a commented-out setting of the <option>primary_hostname</option> option. Exim needs
+to know the official, fully qualified name of your host, and this is where you
+can specify it. However, in most cases you do not need to set this option. When
+it is unset, Exim uses the <function>uname()</function> system function to obtain the host name.
+</para>
+<para>
+The first three non-comment configuration lines are as follows:
+</para>
+<literallayout class="monospaced">
+domainlist local_domains = @
+domainlist relay_to_domains =
+hostlist relay_from_hosts = 127.0.0.1
+</literallayout>
+<para>
+These are not, in fact, option settings. They are definitions of two named
+domain lists and one named host list. Exim allows you to give names to lists of
+domains, hosts, and email addresses, in order to make it easier to manage the
+configuration file (see section <xref linkend="SECTnamedlists"/>).
+</para>
+<para>
+The first line defines a domain list called <emphasis>local_domains</emphasis>; this is used
+later in the configuration to identify domains that are to be delivered
+on the local host.
+</para>
+<para>
+<indexterm role="concept">
+<primary>@ in a domain list</primary>
+</indexterm>
+There is just one item in this list, the string <quote>@</quote>. This is a special form
+of entry which means <quote>the name of the local host</quote>. Thus, if the local host is
+called <emphasis>a.host.example</emphasis>, mail to <emphasis>any.user@a.host.example</emphasis> is expected to
+be delivered locally. Because the local host’s name is referenced indirectly,
+the same configuration file can be used on different hosts.
+</para>
+<para>
+The second line defines a domain list called <emphasis>relay_to_domains</emphasis>, but the
+list itself is empty. Later in the configuration we will come to the part that
+controls mail relaying through the local host; it allows relaying to any
+domains in this list. By default, therefore, no relaying on the basis of a mail
+domain is permitted.
+</para>
+<para>
+The third line defines a host list called <emphasis>relay_from_hosts</emphasis>. This list is
+used later in the configuration to permit relaying from any host or IP address
+that matches the list. The default contains just the IP address of the IPv4
+loopback interface, which means that processes on the local host are able to
+submit mail for relaying by sending it over TCP/IP to that interface. No other
+hosts are permitted to submit messages for relaying.
+</para>
+<para>
+Just to be sure there’s no misunderstanding: at this point in the configuration
+we aren’t actually setting up any controls. We are just defining some domains
+and hosts that will be used in the controls that are specified later.
+</para>
+<para>
+The next two configuration lines are genuine option settings:
+</para>
+<literallayout class="monospaced">
+acl_smtp_rcpt = acl_check_rcpt
+acl_smtp_data = acl_check_data
+</literallayout>
+<para>
+These options specify <emphasis>Access Control Lists</emphasis> (ACLs) that are to be used
+during an incoming SMTP session for every recipient of a message (every RCPT
+command), and after the contents of the message have been received,
+respectively. The names of the lists are <emphasis>acl_check_rcpt</emphasis> and
+<emphasis>acl_check_data</emphasis>, and we will come to their definitions below, in the ACL
+section of the configuration. The RCPT ACL controls which recipients are
+accepted for an incoming message – if a configuration does not provide an ACL
+to check recipients, no SMTP mail can be accepted. The DATA ACL allows the
+contents of a message to be checked.
+</para>
+<para>
+Two commented-out option settings are next:
+</para>
+<literallayout class="monospaced">
+# av_scanner = clamd:/tmp/clamd
+# spamd_address = 127.0.0.1 783
+</literallayout>
+<para>
+These are example settings that can be used when Exim is compiled with the
+content-scanning extension. The first specifies the interface to the virus
+scanner, and the second specifies the interface to SpamAssassin. Further
+details are given in chapter <xref linkend="CHAPexiscan"/>.
+</para>
+<para>
+Three more commented-out option settings follow:
+</para>
+<literallayout class="monospaced">
+# tls_advertise_hosts = *
+# tls_certificate = /etc/ssl/exim.crt
+# tls_privatekey = /etc/ssl/exim.pem
+</literallayout>
+<para>
+These are example settings that can be used when Exim is compiled with
+support for TLS (aka SSL) as described in section <xref linkend="SECTinctlsssl"/>. The
+first one specifies the list of clients that are allowed to use TLS when
+connecting to this server; in this case, the wildcard means all clients. The
+other options specify where Exim should find its TLS certificate and private
+key, which together prove the server’s identity to any clients that connect.
+More details are given in chapter <xref linkend="CHAPTLS"/>.
+</para>
+<para>
+Another two commented-out option settings follow:
+</para>
+<literallayout class="monospaced">
+# daemon_smtp_ports = 25 : 465 : 587
+# tls_on_connect_ports = 465
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>port</primary>
+<secondary>465 and 587</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>port</primary>
+<secondary>for message submission</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>submission, ports for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>submissions protocol</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>smtps protocol</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>ssmtp protocol</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>submissions protocol</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>ssmtp protocol</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>smtps protocol</secondary>
+</indexterm>
+These options provide better support for roaming users who wish to use this
+server for message submission. They are not much use unless you have turned on
+TLS (as described in the previous paragraph) and authentication (about which
+more in section <xref linkend="SECTdefconfauth"/>).
+Mail submission from mail clients (MUAs) should be separate from inbound mail
+to your domain (MX delivery) for various good reasons (eg, ability to impose
+much saner TLS protocol and ciphersuite requirements without unintended
+consequences).
+RFC 6409 (previously 4409) specifies use of port 587 for SMTP Submission,
+which uses STARTTLS, so this is the <quote>submission</quote> port.
+RFC 8314 specifies use of port 465 as the <quote>submissions</quote> protocol,
+which should be used in preference to 587.
+You should also consider deploying SRV records to help clients find
+these ports.
+Older names for <quote>submissions</quote> are <quote>smtps</quote> and <quote>ssmtp</quote>.
+</para>
+<para>
+Two more commented-out options settings follow:
+</para>
+<literallayout class="monospaced">
+# qualify_domain =
+# qualify_recipient =
+</literallayout>
+<para>
+The first of these specifies a domain that Exim uses when it constructs a
+complete email address from a local login name. This is often needed when Exim
+receives a message from a local process. If you do not set <option>qualify_domain</option>,
+the value of <option>primary_hostname</option> is used. If you set both of these options,
+you can have different qualification domains for sender and recipient
+addresses. If you set only the first one, its value is used in both cases.
+</para>
+<para>
+<indexterm role="concept">
+<primary>domain literal</primary>
+<secondary>recognizing format</secondary>
+</indexterm>
+The following line must be uncommented if you want Exim to recognize
+addresses of the form <emphasis>user@[10.11.12.13]</emphasis> that is, with a <quote>domain literal</quote>
+(an IP address within square brackets) instead of a named domain.
+</para>
+<literallayout class="monospaced">
+# allow_domain_literals
+</literallayout>
+<para>
+The RFCs still require this form, but many people think that in the modern
+Internet it makes little sense to permit mail to be sent to specific hosts by
+quoting their IP addresses. This ancient format has been used by people who
+try to abuse hosts by using them for unwanted relaying. However, some
+people believe there are circumstances (for example, messages addressed to
+<emphasis>postmaster</emphasis>) where domain literals are still useful.
+</para>
+<para>
+The next configuration line is a kind of trigger guard:
+</para>
+<literallayout class="monospaced">
+never_users = root
+</literallayout>
+<para>
+It specifies that no delivery must ever be run as the root user. The normal
+convention is to set up <emphasis>root</emphasis> as an alias for the system administrator. This
+setting is a guard against slips in the configuration.
+The list of users specified by <option>never_users</option> is not, however, the complete
+list; the build-time configuration in <filename>Local/Makefile</filename> has an option called
+FIXED_NEVER_USERS specifying a list that cannot be overridden. The
+contents of <option>never_users</option> are added to this list. By default
+FIXED_NEVER_USERS also specifies root.
+</para>
+<para>
+When a remote host connects to Exim in order to send mail, the only information
+Exim has about the host’s identity is its IP address. The next configuration
+line,
+</para>
+<literallayout class="monospaced">
+host_lookup = *
+</literallayout>
+<para>
+specifies that Exim should do a reverse DNS lookup on all incoming connections,
+in order to get a host name. This improves the quality of the logging
+information, but if you feel it is too expensive, you can remove it entirely,
+or restrict the lookup to hosts on <quote>nearby</quote> networks.
+Note that it is not always possible to find a host name from an IP address,
+because not all DNS reverse zones are maintained, and sometimes DNS servers are
+unreachable.
+</para>
+<para>
+The next two lines are concerned with <emphasis>ident</emphasis> callbacks, as defined by RFC
+1413 (hence their names):
+</para>
+<literallayout class="monospaced">
+rfc1413_hosts = *
+rfc1413_query_timeout = 0s
+</literallayout>
+<para>
+These settings cause Exim to avoid ident callbacks for all incoming SMTP calls.
+Few hosts offer RFC1413 service these days; calls have to be
+terminated by a timeout and this needlessly delays the startup
+of an incoming SMTP connection.
+If you have hosts for which you trust RFC1413 and need this
+information, you can change this.
+</para>
+<para>
+This line enables an efficiency SMTP option. It is negotiated by clients
+and not expected to cause problems but can be disabled if needed.
+</para>
+<literallayout class="monospaced">
+prdr_enable = true
+</literallayout>
+<para>
+When Exim receives messages over SMTP connections, it expects all addresses to
+be fully qualified with a domain, as required by the SMTP definition. However,
+if you are running a server to which simple clients submit messages, you may
+find that they send unqualified addresses. The two commented-out options:
+</para>
+<literallayout class="monospaced">
+# sender_unqualified_hosts =
+# recipient_unqualified_hosts =
+</literallayout>
+<para>
+show how you can specify hosts that are permitted to send unqualified sender
+and recipient addresses, respectively.
+</para>
+<para>
+The <option>log_selector</option> option is used to increase the detail of logging
+over the default:
+</para>
+<literallayout class="monospaced">
+log_selector = +smtp_protocol_error +smtp_syntax_error \
+ +tls_certificate_verified
+</literallayout>
+<para>
+The <option>percent_hack_domains</option> option is also commented out:
+</para>
+<literallayout class="monospaced">
+# percent_hack_domains =
+</literallayout>
+<para>
+It provides a list of domains for which the <quote>percent hack</quote> is to operate.
+This is an almost obsolete form of explicit email routing. If you do not know
+anything about it, you can safely ignore this topic.
+</para>
+<para>
+The next two settings in the main part of the default configuration are
+concerned with messages that have been <quote>frozen</quote> on Exim’s queue. When a
+message is frozen, Exim no longer continues to try to deliver it. Freezing
+occurs when a bounce message encounters a permanent failure because the sender
+address of the original message that caused the bounce is invalid, so the
+bounce cannot be delivered. This is probably the most common case, but there
+are also other conditions that cause freezing, and frozen messages are not
+always bounce messages.
+</para>
+<literallayout class="monospaced">
+ignore_bounce_errors_after = 2d
+timeout_frozen_after = 7d
+</literallayout>
+<para>
+The first of these options specifies that failing bounce messages are to be
+discarded after 2 days in the queue. The second specifies that any frozen
+message (whether a bounce message or not) is to be timed out (and discarded)
+after a week. In this configuration, the first setting ensures that no failing
+bounce message ever lasts a week.
+</para>
+<para>
+Exim queues it’s messages in a spool directory. If you expect to have
+large queues, you may consider using this option. It splits the spool
+directory into subdirectories to avoid file system degradation from
+many files in a single directory, resulting in better performance.
+Manual manipulation of queued messages becomes more complex (though fortunately
+not often needed).
+</para>
+<literallayout class="monospaced">
+# split_spool_directory = true
+</literallayout>
+<para>
+In an ideal world everybody follows the standards. For non-ASCII
+messages RFC 2047 is a standard, allowing a maximum line length of 76
+characters. Exim adheres that standard and won’t process messages which
+violate this standard. (Even ${rfc2047:...} expansions will fail.)
+In particular, the Exim maintainers have had multiple reports of
+problems from Russian administrators of issues until they disable this
+check, because of some popular, yet buggy, mail composition software.
+</para>
+<literallayout class="monospaced">
+# check_rfc2047_length = false
+</literallayout>
+<para>
+If you need to be strictly RFC compliant you may wish to disable the
+8BITMIME advertisement. Use this, if you exchange mails with systems
+that are not 8-bit clean.
+</para>
+<literallayout class="monospaced">
+# accept_8bitmime = false
+</literallayout>
+<para>
+Libraries you use may depend on specific environment settings. This
+imposes a security risk (e.g. PATH). There are two lists:
+<option>keep_environment</option> for the variables to import as they are, and
+<option>add_environment</option> for variables we want to set to a fixed value.
+Note that TZ is handled separately, by the $%timezone%$ runtime
+option and by the TIMEZONE_DEFAULT buildtime option.
+</para>
+<literallayout class="monospaced">
+# keep_environment = ^LDAP
+# add_environment = PATH=/usr/bin::/bin
+</literallayout>
+</section>
+<section id="SECID54">
+<title>ACL configuration</title>
+<para>
+<indexterm role="concept">
+<primary>default</primary>
+<secondary>ACLs</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>default configuration</secondary>
+</indexterm>
+In the default configuration, the ACL section follows the main configuration.
+It starts with the line
+</para>
+<literallayout class="monospaced">
+begin acl
+</literallayout>
+<para>
+and it contains the definitions of two ACLs, called <emphasis>acl_check_rcpt</emphasis> and
+<emphasis>acl_check_data</emphasis>, that were referenced in the settings of <option>acl_smtp_rcpt</option>
+and <option>acl_smtp_data</option> above.
+</para>
+<para>
+<indexterm role="concept">
+<primary>RCPT</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+The first ACL is used for every RCPT command in an incoming SMTP message. Each
+RCPT command specifies one of the message’s recipients. The ACL statements
+are considered in order, until the recipient address is either accepted or
+rejected. The RCPT command is then accepted or rejected, according to the
+result of the ACL processing.
+</para>
+<literallayout class="monospaced">
+acl_check_rcpt:
+</literallayout>
+<para>
+This line, consisting of a name terminated by a colon, marks the start of the
+ACL, and names it.
+</para>
+<literallayout class="monospaced">
+accept hosts = :
+</literallayout>
+<para>
+This ACL statement accepts the recipient if the sending host matches the list.
+But what does that strange list mean? It doesn’t actually contain any host
+names or IP addresses. The presence of the colon puts an empty item in the
+list; Exim matches this only if the incoming message did not come from a remote
+host, because in that case, the remote hostname is empty. The colon is
+important. Without it, the list itself is empty, and can never match anything.
+</para>
+<para>
+What this statement is doing is to accept unconditionally all recipients in
+messages that are submitted by SMTP from local processes using the standard
+input and output (that is, not using TCP/IP). A number of MUAs operate in this
+manner.
+</para>
+<literallayout class="monospaced">
+deny domains = +local_domains
+ local_parts = ^[.] : ^.*[@%!/|]
+ message = Restricted characters in address
+
+deny domains = !+local_domains
+ local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
+ message = Restricted characters in address
+</literallayout>
+<para>
+These statements are concerned with local parts that contain any of the
+characters <quote>@</quote>, <quote>%</quote>, <quote>!</quote>, <quote>/</quote>, <quote>|</quote>, or dots in unusual places.
+Although these characters are entirely legal in local parts (in the case of
+<quote>@</quote> and leading dots, only if correctly quoted), they do not commonly occur
+in Internet mail addresses.
+</para>
+<para>
+The first three have in the past been associated with explicitly routed
+addresses (percent is still sometimes used – see the <option>percent_hack_domains</option>
+option). Addresses containing these characters are regularly tried by spammers
+in an attempt to bypass relaying restrictions, and also by open relay testing
+programs. Unless you really need them it is safest to reject these characters
+at this early stage. This configuration is heavy-handed in rejecting these
+characters for all messages it accepts from remote hosts. This is a deliberate
+policy of being as safe as possible.
+</para>
+<para>
+The first rule above is stricter, and is applied to messages that are addressed
+to one of the local domains handled by this host. This is implemented by the
+first condition, which restricts it to domains that are listed in the
+<emphasis>local_domains</emphasis> domain list. The <quote>+</quote> character is used to indicate a
+reference to a named list. In this configuration, there is just one domain in
+<emphasis>local_domains</emphasis>, but in general there may be many.
+</para>
+<para>
+The second condition on the first statement uses two regular expressions to
+block local parts that begin with a dot or contain <quote>@</quote>, <quote>%</quote>, <quote>!</quote>, <quote>/</quote>,
+or <quote>|</quote>. If you have local accounts that include these characters, you will
+have to modify this rule.
+</para>
+<para>
+Empty components (two dots in a row) are not valid in RFC 2822, but Exim
+allows them because they have been encountered in practice. (Consider the
+common convention of local parts constructed as
+<quote><emphasis>first-initial.second-initial.family-name</emphasis></quote> when applied to someone like
+the author of Exim, who has no second initial.) However, a local part starting
+with a dot or containing <quote>/../</quote> can cause trouble if it is used as part of a
+filename (for example, for a mailing list). This is also true for local parts
+that contain slashes. A pipe symbol can also be troublesome if the local part
+is incorporated unthinkingly into a shell command line.
+</para>
+<para>
+The second rule above applies to all other domains, and is less strict. This
+allows your own users to send outgoing messages to sites that use slashes
+and vertical bars in their local parts. It blocks local parts that begin
+with a dot, slash, or vertical bar, but allows these characters within the
+local part. However, the sequence <quote>/../</quote> is barred. The use of <quote>@</quote>, <quote>%</quote>,
+and <quote>!</quote> is blocked, as before. The motivation here is to prevent your users
+(or your users’ viruses) from mounting certain kinds of attack on remote sites.
+</para>
+<literallayout class="monospaced">
+accept local_parts = postmaster
+ domains = +local_domains
+</literallayout>
+<para>
+This statement, which has two conditions, accepts an incoming address if the
+local part is <emphasis>postmaster</emphasis> and the domain is one of those listed in the
+<emphasis>local_domains</emphasis> domain list. The <quote>+</quote> character is used to indicate a
+reference to a named list. In this configuration, there is just one domain in
+<emphasis>local_domains</emphasis>, but in general there may be many.
+</para>
+<para>
+The presence of this statement means that mail to postmaster is never blocked
+by any of the subsequent tests. This can be helpful while sorting out problems
+in cases where the subsequent tests are incorrectly denying access.
+</para>
+<literallayout class="monospaced">
+require verify = sender
+</literallayout>
+<para>
+This statement requires the sender address to be verified before any subsequent
+ACL statement can be used. If verification fails, the incoming recipient
+address is refused. Verification consists of trying to route the address, to
+see if a bounce message could be delivered to it. In the case of remote
+addresses, basic verification checks only the domain, but <emphasis>callouts</emphasis> can be
+used for more verification if required. Section <xref linkend="SECTaddressverification"/>
+discusses the details of address verification.
+</para>
+<literallayout class="monospaced">
+accept hosts = +relay_from_hosts
+ control = submission
+</literallayout>
+<para>
+This statement accepts the address if the message is coming from one of the
+hosts that are defined as being allowed to relay through this host. Recipient
+verification is omitted here, because in many cases the clients are dumb MUAs
+that do not cope well with SMTP error responses. For the same reason, the
+second line specifies <quote>submission mode</quote> for messages that are accepted. This
+is described in detail in section <xref linkend="SECTsubmodnon"/>; it causes Exim to fix
+messages that are deficient in some way, for example, because they lack a
+<emphasis>Date:</emphasis> header line. If you are actually relaying out from MTAs, you should
+probably add recipient verification here, and disable submission mode.
+</para>
+<literallayout class="monospaced">
+accept authenticated = *
+ control = submission
+</literallayout>
+<para>
+This statement accepts the address if the client host has authenticated itself.
+Submission mode is again specified, on the grounds that such messages are most
+likely to come from MUAs. The default configuration does not define any
+authenticators, though it does include some nearly complete commented-out
+examples described in <xref linkend="SECTdefconfauth"/>. This means that no client can in
+fact authenticate until you complete the authenticator definitions.
+</para>
+<literallayout class="monospaced">
+require message = relay not permitted
+ domains = +local_domains : +relay_to_domains
+</literallayout>
+<para>
+This statement rejects the address if its domain is neither a local domain nor
+one of the domains for which this host is a relay.
+</para>
+<literallayout class="monospaced">
+require verify = recipient
+</literallayout>
+<para>
+This statement requires the recipient address to be verified; if verification
+fails, the address is rejected.
+</para>
+<literallayout class="monospaced">
+# deny dnslists = black.list.example
+# message = rejected because $sender_host_address \
+# is in a black list at $dnslist_domain\n\
+# $dnslist_text
+#
+# warn dnslists = black.list.example
+# add_header = X-Warning: $sender_host_address is in \
+# a black list at $dnslist_domain
+# log_message = found in $dnslist_domain
+</literallayout>
+<para>
+These commented-out lines are examples of how you could configure Exim to check
+sending hosts against a DNS black list. The first statement rejects messages
+from blacklisted hosts, whereas the second just inserts a warning header
+line.
+</para>
+<literallayout class="monospaced">
+# require verify = csa
+</literallayout>
+<para>
+This commented-out line is an example of how you could turn on client SMTP
+authorization (CSA) checking. Such checks do DNS lookups for special SRV
+records.
+</para>
+<literallayout class="monospaced">
+accept
+</literallayout>
+<para>
+The final statement in the first ACL unconditionally accepts any recipient
+address that has successfully passed all the previous tests.
+</para>
+<literallayout class="monospaced">
+acl_check_data:
+</literallayout>
+<para>
+This line marks the start of the second ACL, and names it. Most of the contents
+of this ACL are commented out:
+</para>
+<literallayout class="monospaced">
+# deny malware = *
+# message = This message contains a virus \
+# ($malware_name).
+</literallayout>
+<para>
+These lines are examples of how to arrange for messages to be scanned for
+viruses when Exim has been compiled with the content-scanning extension, and a
+suitable virus scanner is installed. If the message is found to contain a
+virus, it is rejected with the given custom error message.
+</para>
+<literallayout class="monospaced">
+# warn spam = nobody
+# message = X-Spam_score: $spam_score\n\
+# X-Spam_score_int: $spam_score_int\n\
+# X-Spam_bar: $spam_bar\n\
+# X-Spam_report: $spam_report
+</literallayout>
+<para>
+These lines are an example of how to arrange for messages to be scanned by
+SpamAssassin when Exim has been compiled with the content-scanning extension,
+and SpamAssassin has been installed. The SpamAssassin check is run with
+<literal>nobody</literal> as its user parameter, and the results are added to the message as a
+series of extra header line. In this case, the message is not rejected,
+whatever the spam score.
+</para>
+<literallayout class="monospaced">
+accept
+</literallayout>
+<para>
+This final line in the DATA ACL accepts the message unconditionally.
+</para>
+</section>
+<section id="SECID55">
+<title>Router configuration</title>
+<para>
+<indexterm role="concept">
+<primary>default</primary>
+<secondary>routers</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>routers</primary>
+<secondary>default</secondary>
+</indexterm>
+The router configuration comes next in the default configuration, introduced
+by the line
+</para>
+<literallayout class="monospaced">
+begin routers
+</literallayout>
+<para>
+Routers are the modules in Exim that make decisions about where to send
+messages. An address is passed to each router, in turn, until it is either
+accepted, or failed. This means that the order in which you define the routers
+matters. Each router is fully described in its own chapter later in this
+manual. Here we give only brief overviews.
+</para>
+<literallayout class="monospaced">
+# domain_literal:
+# driver = ipliteral
+# domains = !+local_domains
+# transport = remote_smtp
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>domain literal</primary>
+<secondary>default router</secondary>
+</indexterm>
+This router is commented out because the majority of sites do not want to
+support domain literal addresses (those of the form <emphasis>user@[10.9.8.7]</emphasis>). If
+you uncomment this router, you also need to uncomment the setting of
+<option>allow_domain_literals</option> in the main part of the configuration.
+</para>
+<para>
+Which router is used next depends upon whether or not the ROUTER_SMARTHOST
+macro has been defined, per
+</para>
+<literallayout class="monospaced">
+.ifdef ROUTER_SMARTHOST
+smarthost:
+#...
+.else
+dnslookup:
+#...
+.endif
+</literallayout>
+<para>
+If ROUTER_SMARTHOST has been defined, either at the top of the file or on the
+command-line, then we route all non-local mail to that smarthost; otherwise, we’ll
+perform DNS lookups for direct-to-MX lookup. Any mail which is to a local domain will
+skip these routers because of the <option>domains</option> option.
+</para>
+<literallayout class="monospaced">
+smarthost:
+ driver = manualroute
+ domains = ! +local_domains
+ transport = smarthost_smtp
+ route_data = ROUTER_SMARTHOST
+ ignore_target_hosts = <; 0.0.0.0 ; 127.0.0.0/8 ; ::1
+ no_more
+</literallayout>
+<para>
+This router only handles mail which is not to any local domains; this is
+specified by the line
+</para>
+<literallayout class="monospaced">
+domains = ! +local_domains
+</literallayout>
+<para>
+The <option>domains</option> option lists the domains to which this router applies, but the
+exclamation mark is a negation sign, so the router is used only for domains
+that are not in the domain list called <emphasis>local_domains</emphasis> (which was defined at
+the start of the configuration). The plus sign before <emphasis>local_domains</emphasis>
+indicates that it is referring to a named list. Addresses in other domains are
+passed on to the following routers.
+</para>
+<para>
+The name of the router driver is <command>manualroute</command> because we are manually
+specifying how mail should be routed onwards, instead of using DNS MX.
+While the name of this router instance is arbitrary, the <option>driver</option> option must
+be one of the driver modules that is in the Exim binary.
+</para>
+<para>
+With no pre-conditions other than <option>domains</option>, all mail for non-local domains
+will be handled by this router, and the <option>no_more</option> setting will ensure that no
+other routers will be used for messages matching the pre-conditions. See
+<xref linkend="SECTrouprecon"/> for more on how the pre-conditions apply. For messages which
+are handled by this router, we provide a hostname to deliver to in <option>route_data</option>
+and the macro supplies the value; the address is then queued for the
+<command>smarthost_smtp</command> transport.
+</para>
+<literallayout class="monospaced">
+dnslookup:
+ driver = dnslookup
+ domains = ! +local_domains
+ transport = remote_smtp
+ ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
+ no_more
+</literallayout>
+<para>
+The <option>domains</option> option behaves as per smarthost, above.
+</para>
+<para>
+The name of the router driver is <command>dnslookup</command>,
+and is specified by the <option>driver</option> option. Do not be confused by the fact that
+the name of this router instance is the same as the name of the driver. The
+instance name is arbitrary, but the name set in the <option>driver</option> option must be
+one of the driver modules that is in the Exim binary.
+</para>
+<para>
+The <command>dnslookup</command> router routes addresses by looking up their domains in the
+DNS in order to obtain a list of hosts to which the address is routed. If the
+router succeeds, the address is queued for the <command>remote_smtp</command> transport, as
+specified by the <option>transport</option> option. If the router does not find the domain
+in the DNS, no further routers are tried because of the <option>no_more</option> setting, so
+the address fails and is bounced.
+</para>
+<para>
+The <option>ignore_target_hosts</option> option specifies a list of IP addresses that are to
+be entirely ignored. This option is present because a number of cases have been
+encountered where MX records in the DNS point to host names
+whose IP addresses are 0.0.0.0 or are in the 127 subnet (typically 127.0.0.1).
+Completely ignoring these IP addresses causes Exim to fail to route the
+email address, so it bounces. Otherwise, Exim would log a routing problem, and
+continue to try to deliver the message periodically until the address timed
+out.
+</para>
+<literallayout class="monospaced">
+system_aliases:
+ driver = redirect
+ allow_fail
+ allow_defer
+ data = ${lookup{$local_part}lsearch{/etc/aliases}}
+# user = exim
+ file_transport = address_file
+ pipe_transport = address_pipe
+</literallayout>
+<para>
+Control reaches this and subsequent routers only for addresses in the local
+domains. This router checks to see whether the local part is defined as an
+alias in the <filename>/etc/aliases</filename> file, and if so, redirects it according to the
+data that it looks up from that file. If no data is found for the local part,
+the value of the <option>data</option> option is empty, causing the address to be passed to
+the next router.
+</para>
+<para>
+<filename>/etc/aliases</filename> is a conventional name for the system aliases file that is
+often used. That is why it is referenced by from the default configuration
+file. However, you can change this by setting SYSTEM_ALIASES_FILE in
+<filename>Local/Makefile</filename> before building Exim.
+</para>
+<literallayout class="monospaced">
+userforward:
+ driver = redirect
+ check_local_user
+# local_part_suffix = +* : -*
+# local_part_suffix_optional
+ file = $home/.forward
+# allow_filter
+ no_verify
+ no_expn
+ check_ancestor
+ file_transport = address_file
+ pipe_transport = address_pipe
+ reply_transport = address_reply
+</literallayout>
+<para>
+This is the most complicated router in the default configuration. It is another
+redirection router, but this time it is looking for forwarding data set up by
+individual users. The <option>check_local_user</option> setting specifies a check that the
+local part of the address is the login name of a local user. If it is not, the
+router is skipped. The two commented options that follow <option>check_local_user</option>,
+namely:
+</para>
+<literallayout class="monospaced">
+# local_part_suffix = +* : -*
+# local_part_suffix_optional
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part_suffix</varname></primary>
+</indexterm>
+show how you can specify the recognition of local part suffixes. If the first
+is uncommented, a suffix beginning with either a plus or a minus sign, followed
+by any sequence of characters, is removed from the local part and placed in the
+variable <varname>$local_part_suffix</varname>. The second suffix option specifies that the
+presence of a suffix in the local part is optional. When a suffix is present,
+the check for a local login uses the local part with the suffix removed.
+</para>
+<para>
+When a local user account is found, the file called <filename>.forward</filename> in the user’s
+home directory is consulted. If it does not exist, or is empty, the router
+declines. Otherwise, the contents of <filename>.forward</filename> are interpreted as
+redirection data (see chapter <xref linkend="CHAPredirect"/> for more details).
+</para>
+<para>
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary>enabling in default router</secondary>
+</indexterm>
+Traditional <filename>.forward</filename> files contain just a list of addresses, pipes, or
+files. Exim supports this by default. However, if <option>allow_filter</option> is set (it
+is commented out by default), the contents of the file are interpreted as a set
+of Exim or Sieve filtering instructions, provided the file begins with <quote>#Exim
+filter</quote> or <quote>#Sieve filter</quote>, respectively. User filtering is discussed in the
+separate document entitled <emphasis>Exim’s interfaces to mail filtering</emphasis>.
+</para>
+<para>
+The <option>no_verify</option> and <option>no_expn</option> options mean that this router is skipped when
+verifying addresses, or when running as a consequence of an SMTP EXPN command.
+There are two reasons for doing this:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+Whether or not a local user has a <filename>.forward</filename> file is not really relevant when
+checking an address for validity; it makes sense not to waste resources doing
+unnecessary work.
+</para>
+</listitem>
+<listitem>
+<para>
+More importantly, when Exim is verifying addresses or handling an EXPN
+command during an SMTP session, it is running as the Exim user, not as root.
+The group is the Exim group, and no additional groups are set up.
+It may therefore not be possible for Exim to read users’ <filename>.forward</filename> files at
+this time.
+</para>
+</listitem>
+</orderedlist>
+<para>
+The setting of <option>check_ancestor</option> prevents the router from generating a new
+address that is the same as any previous address that was redirected. (This
+works round a problem concerning a bad interaction between aliasing and
+forwarding – see section <xref linkend="SECTredlocmai"/>).
+</para>
+<para>
+The final three option settings specify the transports that are to be used when
+forwarding generates a direct delivery to a file, or to a pipe, or sets up an
+auto-reply, respectively. For example, if a <filename>.forward</filename> file contains
+</para>
+<literallayout class="monospaced">
+a.nother@elsewhere.example, /home/spqr/archive
+</literallayout>
+<para>
+the delivery to <filename>/home/spqr/archive</filename> is done by running the <option>address_file</option>
+transport.
+</para>
+<literallayout class="monospaced">
+localuser:
+ driver = accept
+ check_local_user
+# local_part_suffix = +* : -*
+# local_part_suffix_optional
+ transport = local_delivery
+</literallayout>
+<para>
+The final router sets up delivery into local mailboxes, provided that the local
+part is the name of a local login, by accepting the address and assigning it to
+the <command>local_delivery</command> transport. Otherwise, we have reached the end of the
+routers, so the address is bounced. The commented suffix settings fulfil the
+same purpose as they do for the <command>userforward</command> router.
+</para>
+</section>
+<section id="SECID56">
+<title>Transport configuration</title>
+<para>
+<indexterm role="concept">
+<primary>default</primary>
+<secondary>transports</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transports</primary>
+<secondary>default</secondary>
+</indexterm>
+Transports define mechanisms for actually delivering messages. They operate
+only when referenced from routers, so the order in which they are defined does
+not matter. The transports section of the configuration starts with
+</para>
+<literallayout class="monospaced">
+begin transports
+</literallayout>
+<para>
+Two remote transports and four local transports are defined.
+</para>
+<literallayout class="monospaced">
+remote_smtp:
+ driver = smtp
+ message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
+.ifdef _HAVE_PRDR
+ hosts_try_prdr = *
+.endif
+</literallayout>
+<para>
+This transport is used for delivering messages over SMTP connections.
+The list of remote hosts comes from the router.
+The <option>message_size_limit</option> usage is a hack to avoid sending on messages
+with over-long lines.
+</para>
+<para>
+The <option>hosts_try_prdr</option> option enables an efficiency SMTP option. It is
+negotiated between client and server and not expected to cause problems
+but can be disabled if needed. The built-in macro _HAVE_PRDR guards the
+use of the <option>hosts_try_prdr</option> configuration option.
+</para>
+<para>
+The other remote transport is used when delivering to a specific smarthost
+with whom there must be some kind of existing relationship, instead of the
+usual federated system.
+</para>
+<literallayout class="monospaced">
+smarthost_smtp:
+ driver = smtp
+ message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
+ multi_domain
+ #
+.ifdef _HAVE_TLS
+ # Comment out any of these which you have to, then file a Support
+ # request with your smarthost provider to get things fixed:
+ hosts_require_tls = *
+ tls_verify_hosts = *
+ # As long as tls_verify_hosts is enabled, this won't matter, but if you
+ # have to comment it out then this will at least log whether you succeed
+ # or not:
+ tls_try_verify_hosts = *
+ #
+ # The SNI name should match the name which we'll expect to verify;
+ # many mail systems don't use SNI and this doesn't matter, but if it does,
+ # we need to send a name which the remote site will recognize.
+ # This _should_ be the name which the smarthost operators specified as
+ # the hostname for sending your mail to.
+ tls_sni = ROUTER_SMARTHOST
+ #
+.ifdef _HAVE_OPENSSL
+ tls_require_ciphers = HIGH:!aNULL:@STRENGTH
+.endif
+.ifdef _HAVE_GNUTLS
+ tls_require_ciphers = SECURE192:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1
+.endif
+.endif
+.ifdef _HAVE_PRDR
+ hosts_try_prdr = *
+.endif
+</literallayout>
+<para>
+After the same <option>message_size_limit</option> hack, we then specify that this Transport
+can handle messages to multiple domains in one run. The assumption here is
+that you’re routing all non-local mail to the same place and that place is
+happy to take all messages from you as quickly as possible.
+All other options depend upon built-in macros; if Exim was built without TLS support
+then no other options are defined.
+If TLS is available, then we configure "stronger than default" TLS ciphersuites
+and versions using the <option>tls_require_ciphers</option> option, where the value to be
+used depends upon the library providing TLS.
+Beyond that, the options adopt the stance that you should have TLS support available
+from your smarthost on today’s Internet, so we turn on requiring TLS for the
+mail to be delivered, and requiring that the certificate be valid, and match
+the expected hostname. The <option>tls_sni</option> option can be used by service providers
+to select an appropriate certificate to present to you and here we re-use the
+ROUTER_SMARTHOST macro, because that is unaffected by CNAMEs present in DNS.
+You want to specify the hostname which you’ll expect to validate for, and that
+should not be subject to insecure tampering via DNS results.
+</para>
+<para>
+For the <option>hosts_try_prdr</option> option see the previous transport.
+</para>
+<para>
+All other options are defaulted.
+</para>
+<literallayout class="monospaced">
+local_delivery:
+ driver = appendfile
+ file = /var/mail/$local_part_data
+ delivery_date_add
+ envelope_to_add
+ return_path_add
+# group = mail
+# mode = 0660
+</literallayout>
+<para>
+This <command>appendfile</command> transport is used for local delivery to user mailboxes in
+traditional BSD mailbox format.
+</para>
+<para revisionflag="changed">
+We prefer to avoid using <varname>$local_part</varname> directly to define the mailbox filename,
+as it is provided by a potential bad actor.
+Instead we use <varname>$local_part_data</varname>,
+the result of looking up <varname>$local_part</varname> in the user database
+(done by using <option>check_local_user</option> in the the router).
+</para>
+<para>
+By default <command>appendfile</command> runs under the uid and gid of the
+local user, which requires the sticky bit to be set on the <filename>/var/mail</filename>
+directory. Some systems use the alternative approach of running mail deliveries
+under a particular group instead of using the sticky bit. The commented options
+show how this can be done.
+</para>
+<para>
+Exim adds three headers to the message as it delivers it: <emphasis>Delivery-date:</emphasis>,
+<emphasis>Envelope-to:</emphasis> and <emphasis>Return-path:</emphasis>. This action is requested by the three
+similarly-named options above.
+</para>
+<literallayout class="monospaced">
+address_pipe:
+ driver = pipe
+ return_output
+</literallayout>
+<para>
+This transport is used for handling deliveries to pipes that are generated by
+redirection (aliasing or users’ <filename>.forward</filename> files). The <option>return_output</option>
+option specifies that any output on stdout or stderr generated by the pipe is to
+be returned to the sender.
+</para>
+<literallayout class="monospaced">
+address_file:
+ driver = appendfile
+ delivery_date_add
+ envelope_to_add
+ return_path_add
+</literallayout>
+<para>
+This transport is used for handling deliveries to files that are generated by
+redirection. The name of the file is not specified in this instance of
+<command>appendfile</command>, because it comes from the <command>redirect</command> router.
+</para>
+<literallayout class="monospaced">
+address_reply:
+ driver = autoreply
+</literallayout>
+<para>
+This transport is used for handling automatic replies generated by users’
+filter files.
+</para>
+</section>
+<section id="SECID57">
+<title>Default retry rule</title>
+<para>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>default rule</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>default</primary>
+<secondary>retry rule</secondary>
+</indexterm>
+The retry section of the configuration file contains rules which affect the way
+Exim retries deliveries that cannot be completed at the first attempt. It is
+introduced by the line
+</para>
+<literallayout class="monospaced">
+begin retry
+</literallayout>
+<para>
+In the default configuration, there is just one rule, which applies to all
+errors:
+</para>
+<literallayout class="monospaced">
+* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
+</literallayout>
+<para>
+This causes any temporarily failing address to be retried every 15 minutes for
+2 hours, then at intervals starting at one hour and increasing by a factor of
+1.5 until 16 hours have passed, then every 6 hours up to 4 days. If an address
+is not delivered after 4 days of temporary failure, it is bounced. The time is
+measured from first failure, not from the time the message was received.
+</para>
+<para>
+If the retry section is removed from the configuration, or is empty (that is,
+if no retry rules are defined), Exim will not retry deliveries. This turns
+temporary errors into permanent errors.
+</para>
+</section>
+<section id="SECID58">
+<title>Rewriting configuration</title>
+<para>
+The rewriting section of the configuration, introduced by
+</para>
+<literallayout class="monospaced">
+begin rewrite
+</literallayout>
+<para>
+contains rules for rewriting addresses in messages as they arrive. There are no
+rewriting rules in the default configuration file.
+</para>
+</section>
+<section id="SECTdefconfauth">
+<title>Authenticators configuration</title>
+<para>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>configuration</secondary>
+</indexterm>
+The authenticators section of the configuration, introduced by
+</para>
+<literallayout class="monospaced">
+begin authenticators
+</literallayout>
+<para>
+defines mechanisms for the use of the SMTP AUTH command. The default
+configuration file contains two commented-out example authenticators
+which support plaintext username/password authentication using the
+standard PLAIN mechanism and the traditional but non-standard LOGIN
+mechanism, with Exim acting as the server. PLAIN and LOGIN are enough
+to support most MUA software.
+</para>
+<para>
+The example PLAIN authenticator looks like this:
+</para>
+<literallayout class="monospaced">
+#PLAIN:
+# driver = plaintext
+# server_set_id = $auth2
+# server_prompts = :
+# server_condition = Authentication is not yet configured
+# server_advertise_condition = ${if def:tls_in_cipher }
+</literallayout>
+<para>
+And the example LOGIN authenticator looks like this:
+</para>
+<literallayout class="monospaced">
+#LOGIN:
+# driver = plaintext
+# server_set_id = $auth1
+# server_prompts = <| Username: | Password:
+# server_condition = Authentication is not yet configured
+# server_advertise_condition = ${if def:tls_in_cipher }
+</literallayout>
+<para>
+The <option>server_set_id</option> option makes Exim remember the authenticated username
+in <varname>$authenticated_id</varname>, which can be used later in ACLs or routers. The
+<option>server_prompts</option> option configures the <command>plaintext</command> authenticator so
+that it implements the details of the specific authentication mechanism,
+i.e. PLAIN or LOGIN. The <option>server_advertise_condition</option> setting controls
+when Exim offers authentication to clients; in the examples, this is only
+when TLS or SSL has been started, so to enable the authenticators you also
+need to add support for TLS as described in section <xref linkend="SECTdefconfmain"/>.
+</para>
+<para>
+The <option>server_condition</option> setting defines how to verify that the username and
+password are correct. In the examples it just produces an error message.
+To make the authenticators work, you can use a string expansion
+expression like one of the examples in chapter <xref linkend="CHAPplaintext"/>.
+</para>
+<para>
+Beware that the sequence of the parameters to PLAIN and LOGIN differ; the
+usercode and password are in different positions.
+Chapter <xref linkend="CHAPplaintext"/> covers both.
+</para>
+<para>
+<indexterm role="concept" startref="IIDconfiwal" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPregexp">
+<title>Regular expressions</title>
+<para>
+<indexterm role="concept">
+<primary>regular expressions</primary>
+<secondary>library</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>PCRE</primary>
+</indexterm>
+Exim supports the use of regular expressions in many of its options. It
+uses the PCRE regular expression library; this provides regular expression
+matching that is compatible with Perl 5. The syntax and semantics of
+regular expressions is discussed in
+online Perl manpages, in
+many Perl reference books, and also in
+Jeffrey Friedl’s <emphasis>Mastering Regular Expressions</emphasis>, which is published by
+O’Reilly (see <emphasis role="bold"><ulink url="http://www.oreilly.com/catalog/regex2/">http://www.oreilly.com/catalog/regex2/</ulink></emphasis>).
+</para>
+<para>
+The documentation for the syntax and semantics of the regular expressions that
+are supported by PCRE is included in the PCRE distribution, and no further
+description is included here. The PCRE functions are called from Exim using
+the default option settings (that is, with no PCRE options set), except that
+the PCRE_CASELESS option is set when the matching is required to be
+case-insensitive.
+</para>
+<para>
+In most cases, when a regular expression is required in an Exim configuration,
+it has to start with a circumflex, in order to distinguish it from plain text
+or an <quote>ends with</quote> wildcard. In this example of a configuration setting, the
+second item in the colon-separated list is a regular expression.
+</para>
+<literallayout class="monospaced">
+domains = a.b.c : ^\\d{3} : *.y.z : ...
+</literallayout>
+<para>
+The doubling of the backslash is required because of string expansion that
+precedes interpretation – see section <xref linkend="SECTlittext"/> for more discussion
+of this issue, and a way of avoiding the need for doubling backslashes. The
+regular expression that is eventually used in this example contains just one
+backslash. The circumflex is included in the regular expression, and has the
+normal effect of <quote>anchoring</quote> it to the start of the string that is being
+matched.
+</para>
+<para>
+There are, however, two cases where a circumflex is not required for the
+recognition of a regular expression: these are the <option>match</option> condition in a
+string expansion, and the <option>matches</option> condition in an Exim filter file. In
+these cases, the relevant string is always treated as a regular expression; if
+it does not start with a circumflex, the expression is not anchored, and can
+match anywhere in the subject string.
+</para>
+<para>
+In all cases, if you want a regular expression to match at the end of a string,
+you must code the $ metacharacter to indicate this. For example:
+</para>
+<literallayout class="monospaced">
+domains = ^\\d{3}\\.example
+</literallayout>
+<para>
+matches the domain <emphasis>123.example</emphasis>, but it also matches <emphasis>123.example.com</emphasis>.
+You need to use:
+</para>
+<literallayout class="monospaced">
+domains = ^\\d{3}\\.example\$
+</literallayout>
+<para>
+if you want <emphasis>example</emphasis> to be the top-level domain. The backslash before the
+$ is needed because string expansion also interprets dollar characters.
+</para>
+</chapter>
+
+<chapter id="CHAPfdlookup">
+<title>File and database lookups</title>
+<para>
+<indexterm role="concept" id="IIDfidalo1" class="startofrange">
+<primary>file</primary>
+<secondary>lookups</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDfidalo2" class="startofrange">
+<primary>database</primary>
+<secondary>lookups</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>description of</secondary>
+</indexterm>
+Exim can be configured to look up data in files or databases as it processes
+messages. Two different kinds of syntax are used:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+A string that is to be expanded may contain explicit lookup requests. These
+cause parts of the string to be replaced by data that is obtained from the
+lookup. Lookups of this type are conditional expansion items. Different results
+can be defined for the cases of lookup success and failure. See chapter
+<xref linkend="CHAPexpand"/>, where string expansions are described in detail.
+The key for the lookup is specified as part of the string expansion.
+</para>
+</listitem>
+<listitem>
+<para>
+Lists of domains, hosts, and email addresses can contain lookup requests as a
+way of avoiding excessively long linear lists. In this case, the data that is
+returned by the lookup is often (but not always) discarded; whether the lookup
+succeeds or fails is what really counts. These kinds of list are described in
+chapter <xref linkend="CHAPdomhosaddlists"/>.
+The key for the lookup is given by the context in which the list is expanded.
+</para>
+</listitem>
+</orderedlist>
+<para>
+String expansions, lists, and lookups interact with each other in such a way
+that there is no order in which to describe any one of them that does not
+involve references to the others. Each of these three chapters makes more sense
+if you have read the other two first. If you are reading this for the first
+time, be aware that some of it will make a lot more sense after you have read
+chapters <xref linkend="CHAPdomhosaddlists"/> and <xref linkend="CHAPexpand"/>.
+</para>
+<section id="SECID60">
+<title>Examples of different lookup syntax</title>
+<para>
+It is easy to confuse the two different kinds of lookup, especially as the
+lists that may contain the second kind are always expanded before being
+processed as lists. Therefore, they may also contain lookups of the first kind.
+Be careful to distinguish between the following two examples:
+</para>
+<literallayout class="monospaced">
+domains = ${lookup{$sender_host_address}lsearch{/some/file}}
+domains = lsearch;/some/file
+</literallayout>
+<para>
+The first uses a string expansion, the result of which must be a domain list.
+No strings have been specified for a successful or a failing lookup; the
+defaults in this case are the looked-up data and an empty string, respectively.
+The expansion takes place before the string is processed as a list, and the
+file that is searched could contain lines like this:
+</para>
+<literallayout class="monospaced">
+192.168.3.4: domain1:domain2:...
+192.168.1.9: domain3:domain4:...
+</literallayout>
+<para>
+When the lookup succeeds, the result of the expansion is a list of domains (and
+possibly other types of item that are allowed in domain lists).
+<indexterm role="concept">
+<primary>tainted data</primary>
+<secondary>de-tainting</secondary>
+</indexterm>
+The result of the expansion is not tainted.
+</para>
+<para>
+In the second example, the lookup is a single item in a domain list. It causes
+Exim to use a lookup to see if the domain that is being processed can be found
+in the file. The file could contains lines like this:
+</para>
+<literallayout class="monospaced">
+domain1:
+domain2:
+</literallayout>
+<para>
+Any data that follows the keys is not relevant when checking that the domain
+matches the list item.
+</para>
+<para>
+It is possible, though no doubt confusing, to use both kinds of lookup at once.
+Consider a file containing lines like this:
+</para>
+<literallayout class="monospaced">
+192.168.5.6: lsearch;/another/file
+</literallayout>
+<para>
+If the value of <varname>$sender_host_address</varname> is 192.168.5.6, expansion of the
+first <option>domains</option> setting above generates the second setting, which therefore
+causes a second lookup to occur.
+</para>
+<para revisionflag="changed">
+The lookup type may optionally be followed by a comma
+and a comma-separated list of options.
+Each option is a <quote>name=value</quote> pair.
+Whether an option is meaningful depands on the lookup type.
+</para>
+<para>
+The rest of this chapter describes the different lookup types that are
+available. Any of them can be used in any part of the configuration where a
+lookup is permitted.
+</para>
+</section>
+<section id="SECID61">
+<title>Lookup types</title>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>types of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>single-key lookup</primary>
+<secondary>definition of</secondary>
+</indexterm>
+Two different types of data lookup are implemented:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The <emphasis>single-key</emphasis> type requires the specification of a file in which to look,
+and a single key to search for. The key must be a non-empty string for the
+lookup to succeed. The lookup type determines how the file is searched.
+</para>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>tainted data</primary>
+<secondary>single-key lookups</secondary>
+</indexterm>
+The file string may not be tainted
+</para>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>tainted data</primary>
+<secondary>de-tainting</secondary>
+</indexterm>
+All single-key lookups support the option <quote>ret=key</quote>.
+If this is given and the lookup
+(either underlying implementation or cached value)
+returns data, the result is replaced with a non-tainted
+version of the lookup key.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>query-style lookup</primary>
+<secondary>definition of</secondary>
+</indexterm>
+The <emphasis>query-style</emphasis> type accepts a generalized database query. No particular
+key value is assumed by Exim for query-style lookups. You can use whichever
+Exim variables you need to construct the database query.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The code for each lookup type is in a separate source file that is included in
+the binary of Exim only if the corresponding compile-time option is set. The
+default settings in <filename>src/EDITME</filename> are:
+</para>
+<literallayout class="monospaced">
+LOOKUP_DBM=yes
+LOOKUP_LSEARCH=yes
+</literallayout>
+<para>
+which means that only linear searching and DBM lookups are included by default.
+For some types of lookup (e.g. SQL databases), you need to install appropriate
+libraries and header files before building Exim.
+</para>
+</section>
+<section id="SECTsinglekeylookups">
+<title>Single-key lookup types</title>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>single-key types</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>single-key lookup</primary>
+<secondary>list of types</secondary>
+</indexterm>
+The following single-key lookup types are implemented:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>cdb</primary>
+<secondary>description of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>cdb</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>binary zero</primary>
+<secondary>in lookup key</secondary>
+</indexterm>
+<command>cdb</command>: The given file is searched as a Constant DataBase file, using the key
+string without a terminating binary zero. The cdb format is designed for
+indexed files that are read frequently and never updated, except by total
+re-creation. As such, it is particularly suitable for large files containing
+aliases or other indexed data referenced by an MTA. Information about cdb and
+tools for building the files can be found in several places:
+</para>
+<literallayout>
+<emphasis role="bold"><ulink url="https://cr.yp.to/cdb.html">https://cr.yp.to/cdb.html</ulink></emphasis>
+<emphasis role="bold"><ulink url="https://www.corpit.ru/mjt/tinycdb.html">https://www.corpit.ru/mjt/tinycdb.html</ulink></emphasis>
+<emphasis role="bold"><ulink url="https://packages.debian.org/stable/utils/freecdb">https://packages.debian.org/stable/utils/freecdb</ulink></emphasis>
+<emphasis role="bold"><ulink url="https://github.com/philpennock/cdbtools">https://github.com/philpennock/cdbtools</ulink></emphasis> (in Go)
+</literallayout>
+<para>
+A cdb distribution is not needed in order to build Exim with cdb support,
+because the code for reading cdb files is included directly in Exim itself.
+However, no means of building or testing cdb files is provided with Exim, so
+you need to obtain a cdb distribution in order to do this.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>DBM</primary>
+<secondary>lookup type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>dbm</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>binary zero</primary>
+<secondary>in lookup key</secondary>
+</indexterm>
+<command>dbm</command>: Calls to DBM library functions are used to extract data from the given
+DBM file by looking up the record with the given key. A terminating binary
+zero is included in the key that is passed to the DBM library. See section
+<xref linkend="SECTdb"/> for a discussion of DBM libraries.
+</para>
+<para>
+<indexterm role="concept">
+<primary>Berkeley DB library</primary>
+<secondary>file format</secondary>
+</indexterm>
+For all versions of Berkeley DB, Exim uses the DB_HASH style of database
+when building DBM files using the <option>exim_dbmbuild</option> utility. However, when
+using Berkeley DB versions 3 or 4, it opens existing databases for reading with
+the DB_UNKNOWN option. This enables it to handle any of the types of database
+that the library supports, and can be useful for accessing DBM files created by
+other applications. (For earlier DB versions, DB_HASH is always used.)
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>dbmjz</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>dbm – embedded NULs</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>sasldb2</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>dbmjz lookup type</primary>
+</indexterm>
+<command>dbmjz</command>: This is the same as <command>dbm</command>, except that the lookup key is
+interpreted as an Exim list; the elements of the list are joined together with
+ASCII NUL characters to form the lookup key. An example usage would be to
+authenticate incoming SMTP calls using the passwords from Cyrus SASL’s
+<filename>/etc/sasldb2</filename> file with the <command>gsasl</command> authenticator or Exim’s own
+<command>cram_md5</command> authenticator.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>dbmnz</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>dbm – terminating zero</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>binary zero</primary>
+<secondary>in lookup key</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Courier</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><filename>/etc/userdbshadow.dat</filename></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>dbmnz lookup type</primary>
+</indexterm>
+<command>dbmnz</command>: This is the same as <command>dbm</command>, except that a terminating binary zero
+is not included in the key that is passed to the DBM library. You may need this
+if you want to look up data in files that are created by or shared with some
+other application that does not use terminating zeros. For example, you need to
+use <command>dbmnz</command> rather than <command>dbm</command> if you want to authenticate incoming SMTP
+calls using the passwords from Courier’s <filename>/etc/userdbshadow.dat</filename> file. Exim’s
+utility program for creating DBM files (<emphasis>exim_dbmbuild</emphasis>) includes the zeros
+by default, but has an option to omit them (see section <xref linkend="SECTdbmbuild"/>).
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>dsearch</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>dsearch lookup type</primary>
+</indexterm>
+<command>dsearch</command>: The given file must be an
+</para>
+<para revisionflag="changed">
+absolute
+</para>
+<para>
+directory path; this is searched for an entry
+whose name is the key by calling the <function>lstat()</function> function.
+The key may not
+contain any forward slash characters.
+If <function>lstat()</function> succeeds then so does the lookup.
+</para>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>tainted data</primary>
+<secondary>dsearch result</secondary>
+</indexterm>
+The result is regarded as untainted.
+</para>
+<para revisionflag="changed">
+Options for the lookup can be given by appending them after the word "dsearch",
+separated by a comma. Options, if present, are a comma-separated list having
+each element starting with a tag name and an equals.
+</para>
+<para revisionflag="changed">
+Two options are supported, for the return value and for filtering match
+candidates.
+The "ret" option requests an alternate result value of
+the entire path for the entry. Example:
+</para>
+<literallayout class="monospaced" revisionflag="changed">
+${lookup {passwd} dsearch,ret=full {/etc}}
+</literallayout>
+<para revisionflag="changed">
+The default result is just the requested entry.
+The "filter" option requests that only directory entries of a given type
+are matched. The match value is one of "file", "dir" or "subdir" (the latter
+not matching "." or ".."). Example:
+</para>
+<literallayout class="monospaced" revisionflag="changed">
+${lookup {passwd} dsearch,filter=file {/etc}}
+</literallayout>
+<para revisionflag="changed">
+The default matching is for any entry type, including directories
+and symlinks.
+</para>
+<para>
+An example of how this
+lookup can be used to support virtual domains is given in section
+<xref linkend="SECTvirtualdomains"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>iplsearch</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>iplsearch lookup type</primary>
+</indexterm>
+<command>iplsearch</command>: The given file is a text file containing keys and data. A key is
+terminated by a colon or white space or the end of the line. The keys in the
+file must be IP addresses, or IP addresses with CIDR masks. Keys that involve
+IPv6 addresses must be enclosed in quotes to prevent the first internal colon
+being interpreted as a key terminator. For example:
+</para>
+<literallayout class="monospaced">
+1.2.3.4: data for 1.2.3.4
+192.168.0.0/16: data for 192.168.0.0/16
+"abcd::cdab": data for abcd::cdab
+"abcd:abcd::/32" data for abcd:abcd::/32
+</literallayout>
+<para>
+The key for an <command>iplsearch</command> lookup must be an IP address (without a mask). The
+file is searched linearly, using the CIDR masks where present, until a matching
+key is found. The first key that matches is used; there is no attempt to find a
+<quote>best</quote> match. Apart from the way the keys are matched, the processing for
+<command>iplsearch</command> is the same as for <command>lsearch</command>.
+</para>
+<para>
+<emphasis role="bold">Warning 1</emphasis>: Unlike most other single-key lookup types, a file of data for
+<command>iplsearch</command> can <emphasis>not</emphasis> be turned into a DBM or cdb file, because those
+lookup types support only literal keys.
+</para>
+<para>
+<emphasis role="bold">Warning 2</emphasis>: In a host list, you must always use <command>net-iplsearch</command> so that
+the implicit key is the host’s IP address rather than its name (see section
+<xref linkend="SECThoslispatsikey"/>).
+</para>
+<para>
+<emphasis role="bold">Warning 3</emphasis>: Do not use an IPv4-mapped IPv6 address for a key; use the
+IPv4, in dotted-quad form. (Exim converts IPv4-mapped IPv6 addresses to this
+notation before executing the lookup.)
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>json</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>json</primary>
+<secondary>lookup type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>JSON</primary>
+<secondary>expansions</secondary>
+</indexterm>
+<command>json</command>: The given file is a text file with a JSON structure.
+An element of the structure is extracted, defined by the search key.
+The key is a list of subelement selectors
+(colon-separated by default but changeable in the usual way)
+which are applied in turn to select smaller and smaller portions
+of the JSON structure.
+If a selector is numeric, it must apply to a JSON array; the (zero-based)
+nunbered array element is selected.
+Otherwise it must apply to a JSON object; the named element is selected.
+The final resulting element can be a simple JSON type or a JSON object
+or array; for the latter two a string-representation of the JSON
+is returned.
+For elements of type string, the returned value is de-quoted.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>linear search</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>lsearch</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lsearch lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>case sensitivity</primary>
+<secondary>in lsearch lookup</secondary>
+</indexterm>
+<command>lsearch</command>: The given file is a text file that is searched linearly for a
+line beginning with the search key, terminated by a colon or white space or the
+end of the line. The search is case-insensitive; that is, upper and lower case
+letters are treated as the same. The first occurrence of the key that is found
+in the file is used.
+</para>
+<para>
+White space between the key and the colon is permitted. The remainder of the
+line, with leading and trailing white space removed, is the data. This can be
+continued onto subsequent lines by starting them with any amount of white
+space, but only a single space character is included in the data at such a
+junction. If the data begins with a colon, the key must be terminated by a
+colon, for example:
+</para>
+<literallayout class="monospaced">
+baduser: :fail:
+</literallayout>
+<para>
+Empty lines and lines beginning with # are ignored, even if they occur in the
+middle of an item. This is the traditional textual format of alias files. Note
+that the keys in an <command>lsearch</command> file are literal strings. There is no
+wildcarding of any kind.
+</para>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>lsearch – colons in keys</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>white space</primary>
+<secondary>in lsearch key</secondary>
+</indexterm>
+In most <command>lsearch</command> files, keys are not required to contain colons or #
+characters, or white space. However, if you need this feature, it is available.
+If a key begins with a doublequote character, it is terminated only by a
+matching quote (or end of line), and the normal escaping rules apply to its
+contents (see section <xref linkend="SECTstrings"/>). An optional colon is permitted after
+quoted keys (exactly as for unquoted keys). There is no special handling of
+quotes for the data part of an <command>lsearch</command> line.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>NIS lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>NIS</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>binary zero</primary>
+<secondary>in lookup key</secondary>
+</indexterm>
+<command>nis</command>: The given file is the name of a NIS map, and a NIS lookup is done with
+the given key, without a terminating binary zero. There is a variant called
+<command>nis0</command> which does include the terminating binary zero in the key. This is
+reportedly needed for Sun-style alias files. Exim does not recognize NIS
+aliases; the full map names must be used.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>wildlsearch lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>wildlsearch</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>nwildlsearch lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>nwildlsearch</secondary>
+</indexterm>
+<command>wildlsearch</command> or <command>nwildlsearch</command>: These search a file linearly, like
+<command>lsearch</command>, but instead of being interpreted as a literal string, each key in
+the file may be wildcarded. The difference between these two lookup types is
+that for <command>wildlsearch</command>, each key in the file is string-expanded before being
+used, whereas for <command>nwildlsearch</command>, no expansion takes place.
+</para>
+<para>
+<indexterm role="concept">
+<primary>case sensitivity</primary>
+<secondary>in (n)wildlsearch lookup</secondary>
+</indexterm>
+Like <command>lsearch</command>, the testing is done case-insensitively. However, keys in the
+file that are regular expressions can be made case-sensitive by the use of
+<literal>(-i)</literal> within the pattern. The following forms of wildcard are recognized:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+The string may begin with an asterisk to mean <quote>ends with</quote>. For example:
+</para>
+<literallayout class="monospaced">
+ *.a.b.c data for anything.a.b.c
+ *fish data for anythingfish
+</literallayout>
+</listitem>
+<listitem>
+<para>
+The string may begin with a circumflex to indicate a regular expression. For
+example, for <command>wildlsearch</command>:
+</para>
+<literallayout class="monospaced">
+ ^\N\d+\.a\.b\N data for <digits>.a.b
+</literallayout>
+<para>
+Note the use of <literal>\N</literal> to disable expansion of the contents of the regular
+expression. If you are using <command>nwildlsearch</command>, where the keys are not
+string-expanded, the equivalent entry is:
+</para>
+<literallayout class="monospaced">
+ ^\d+\.a\.b data for <digits>.a.b
+</literallayout>
+<para>
+The case-insensitive flag is set at the start of compiling the regular
+expression, but it can be turned off by using <literal>(-i)</literal> at an appropriate point.
+For example, to make the entire pattern case-sensitive:
+</para>
+<literallayout class="monospaced">
+ ^(?-i)\d+\.a\.b data for <digits>.a.b
+</literallayout>
+<para>
+If the regular expression contains white space or colon characters, you must
+either quote it (see <command>lsearch</command> above), or represent these characters in other
+ways. For example, <literal>\s</literal> can be used for white space and <literal>\x3A</literal> for a
+colon. This may be easier than quoting, because if you quote, you have to
+escape all the backslashes inside the quotes.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: It is not possible to capture substrings in a regular expression
+match for later use, because the results of all lookups are cached. If a lookup
+is repeated, the result is taken from the cache, and no actual pattern matching
+takes place. The values of all the numeric variables are unset after a
+<command>(n)wildlsearch</command> match.
+</para>
+</listitem>
+<listitem>
+<para>
+Although I cannot see it being of much use, the general matching function that
+is used to implement <command>(n)wildlsearch</command> means that the string may begin with a
+lookup name terminated by a semicolon, and followed by lookup data. For
+example:
+</para>
+<literallayout class="monospaced">
+ cdb;/some/file data for keys that match the file
+</literallayout>
+<para>
+The data that is obtained from the nested lookup is discarded.
+</para>
+</listitem>
+</orderedlist>
+<para>
+Keys that do not match any of these patterns are interpreted literally. The
+continuation rules for the data are the same as for <command>lsearch</command>, and keys may
+be followed by optional colons.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: Unlike most other single-key lookup types, a file of data for
+<command>(n)wildlsearch</command> can <emphasis>not</emphasis> be turned into a DBM or cdb file, because those
+lookup types support only literal keys.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>spf lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>spf</secondary>
+</indexterm>
+<command>spf</command>: If Exim is built with SPF support, manual lookups can be done
+(as opposed to the standard ACL condition method).
+For details see section <xref linkend="SECSPF"/>.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECTquerystylelookups">
+<title>Query-style lookup types</title>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>query-style types</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>query-style lookup</primary>
+<secondary>list of types</secondary>
+</indexterm>
+The supported query-style lookup types are listed below. Further details about
+many of them are given in later sections.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>as a lookup type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>DNS</secondary>
+</indexterm>
+<command>dnsdb</command>: This does a DNS search for one or more records whose domain names
+are given in the supplied query. The resulting data is the contents of the
+records. See section <xref linkend="SECTdnsdb"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>InterBase lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>InterBase</secondary>
+</indexterm>
+<command>ibase</command>: This does a lookup in an InterBase database.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>lookup type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>LDAP</secondary>
+</indexterm>
+<command>ldap</command>: This does an LDAP lookup using a query in the form of a URL, and
+returns attributes from a single entry. There is a variant called <command>ldapm</command>
+that permits values from multiple entries to be returned. A third variant
+called <command>ldapdn</command> returns the Distinguished Name of a single entry instead of
+any attribute values. See section <xref linkend="SECTldap"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>MySQL</primary>
+<secondary>lookup type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>MySQL</secondary>
+</indexterm>
+<command>mysql</command>: The format of the query is an SQL statement that is passed to a
+MySQL database. See section <xref linkend="SECTsql"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>NIS+ lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>NIS+</secondary>
+</indexterm>
+<command>nisplus</command>: This does a NIS+ lookup using a query that can specify the name of
+the field to be returned. See section <xref linkend="SECTnisplus"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>Oracle</primary>
+<secondary>lookup type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>Oracle</secondary>
+</indexterm>
+<command>oracle</command>: The format of the query is an SQL statement that is passed to an
+Oracle database. See section <xref linkend="SECTsql"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>passwd</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>passwd lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><filename>/etc/passwd</filename></primary>
+</indexterm>
+<command>passwd</command> is a query-style lookup with queries that are just user names. The
+lookup calls <function>getpwnam()</function> to interrogate the system password data, and on
+success, the result string is the same as you would get from an <command>lsearch</command>
+lookup on a traditional <filename>/etc/passwd file</filename>, though with <literal>*</literal> for the
+password value. For example:
+</para>
+<literallayout class="monospaced">
+*:42:42:King Rat:/home/kr:/bin/bash
+</literallayout>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>PostgreSQL lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>PostgreSQL</secondary>
+</indexterm>
+<command>pgsql</command>: The format of the query is an SQL statement that is passed to a
+PostgreSQL database. See section <xref linkend="SECTsql"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>Redis lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>Redis</secondary>
+</indexterm>
+<command>redis</command>: The format of the query is either a simple get or simple set,
+passed to a Redis database. See section <xref linkend="SECTsql"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>sqlite lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>sqlite</secondary>
+</indexterm>
+<command>sqlite</command>: The format of the query is
+new
+an optional filename
+</para>
+<para>
+followed by an SQL statement
+that is passed to an SQLite database. See section <xref linkend="SECTsqlite"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+<command>testdb</command>: This is a lookup type that is used for testing Exim. It is
+not likely to be useful in normal operation.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>whoson lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>whoson</secondary>
+</indexterm>
+<command>whoson</command>: <emphasis>Whoson</emphasis> (<emphasis role="bold"><ulink url="http://whoson.sourceforge.net">http://whoson.sourceforge.net</ulink></emphasis>) is a protocol that
+allows a server to check whether a particular (dynamically allocated) IP
+address is currently allocated to a known (trusted) user and, optionally, to
+obtain the identity of the said user. For SMTP servers, <emphasis>Whoson</emphasis> was popular
+at one time for <quote>POP before SMTP</quote> authentication, but that approach has been
+superseded by SMTP authentication. In Exim, <emphasis>Whoson</emphasis> can be used to implement
+<quote>POP before SMTP</quote> checking using ACL statements such as
+</para>
+<literallayout class="monospaced">
+require condition = \
+ ${lookup whoson {$sender_host_address}{yes}{no}}
+</literallayout>
+<para>
+The query consists of a single IP address. The value returned is the name of
+the authenticated user, which is stored in the variable <varname>$value</varname>. However, in
+this example, the data in <varname>$value</varname> is not used; the result of the lookup is
+one of the fixed strings <quote>yes</quote> or <quote>no</quote>.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID63">
+<title>Temporary errors in lookups</title>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>temporary error in</secondary>
+</indexterm>
+Lookup functions can return temporary error codes if the lookup cannot be
+completed. For example, an SQL or LDAP database might be unavailable. For this
+reason, it is not advisable to use a lookup that might do this for critical
+options such as a list of local domains.
+</para>
+<para>
+When a lookup cannot be completed in a router or transport, delivery
+of the message (to the relevant address) is deferred, as for any other
+temporary error. In other circumstances Exim may assume the lookup has failed,
+or may give up altogether.
+</para>
+</section>
+<section id="SECTdefaultvaluelookups">
+<title>Default values in single-key lookups</title>
+<para>
+<indexterm role="concept">
+<primary>wildcard lookups</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>default values</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>wildcard</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>* added to type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>default</primary>
+<secondary>in single-key lookups</secondary>
+</indexterm>
+In this context, a <quote>default value</quote> is a value specified by the administrator
+that is to be used if a lookup fails.
+</para>
+<para>
+<emphasis role="bold">Note:</emphasis> This section applies only to single-key lookups. For query-style
+lookups, the facilities of the query language must be used. An attempt to
+specify a default for a query-style lookup provokes an error.
+</para>
+<para>
+If <quote>*</quote> is added to a single-key lookup type (for example, <option>lsearch*</option>)
+and the initial lookup fails, the key <quote>*</quote> is looked up in the file to
+provide a default value. See also the section on partial matching below.
+</para>
+<para>
+<indexterm role="concept">
+<primary>*@ with single-key lookup</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>*@ added to type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>alias file</primary>
+<secondary>per-domain default</secondary>
+</indexterm>
+Alternatively, if <quote>*@</quote> is added to a single-key lookup type (for example
+<option>dbm*@</option>) then, if the initial lookup fails and the key contains an @
+character, a second lookup is done with everything before the last @ replaced
+by *. This makes it possible to provide per-domain defaults in alias files
+that include the domains in the keys. If the second lookup fails (or doesn’t
+take place because there is no @ in the key), <quote>*</quote> is looked up.
+For example, a <command>redirect</command> router might contain:
+</para>
+<literallayout class="monospaced">
+data = ${lookup{$local_part@$domain}lsearch*@{/etc/mix-aliases}}
+</literallayout>
+<para>
+Suppose the address that is being processed is <emphasis>jane@eyre.example</emphasis>. Exim
+looks up these keys, in this order:
+</para>
+<literallayout class="monospaced">
+jane@eyre.example
+*@eyre.example
+*
+</literallayout>
+<para>
+The data is taken from whichever key it finds first. <emphasis role="bold">Note</emphasis>: In an
+<command>lsearch</command> file, this does not mean the first of these keys in the file. A
+complete scan is done for each key, and only if it is not found at all does
+Exim move on to try the next key.
+</para>
+</section>
+<section id="SECTpartiallookup">
+<title>Partial matching in single-key lookups</title>
+<para>
+<indexterm role="concept">
+<primary>partial matching</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>wildcard lookups</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>partial matching</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>wildcard</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>asterisk</primary>
+<secondary>in search type</secondary>
+</indexterm>
+The normal operation of a single-key lookup is to search the file for an exact
+match with the given key. However, in a number of situations where domains are
+being looked up, it is useful to be able to do partial matching. In this case,
+information in the file that has a key starting with <quote>*.</quote> is matched by any
+domain that ends with the components that follow the full stop. For example, if
+a key in a DBM file is
+</para>
+<literallayout class="monospaced">
+*.dates.fict.example
+</literallayout>
+<para>
+then when partial matching is enabled this is matched by (amongst others)
+<emphasis>2001.dates.fict.example</emphasis> and <emphasis>1984.dates.fict.example</emphasis>. It is also matched
+by <emphasis>dates.fict.example</emphasis>, if that does not appear as a separate key in the
+file.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: Partial matching is not available for query-style lookups. It is
+also not available for any lookup items in address lists (see section
+<xref linkend="SECTaddresslist"/>).
+</para>
+<para>
+Partial matching is implemented by doing a series of separate lookups using
+keys constructed by modifying the original subject key. This means that it can
+be used with any of the single-key lookup types, provided that
+partial matching keys
+beginning with a special prefix (default <quote>*.</quote>) are included in the data file.
+Keys in the file that do not begin with the prefix are matched only by
+unmodified subject keys when partial matching is in use.
+</para>
+<para>
+Partial matching is requested by adding the string <quote>partial-</quote> to the front of
+the name of a single-key lookup type, for example, <option>partial-dbm</option>. When this
+is done, the subject key is first looked up unmodified; if that fails, <quote>*.</quote>
+is added at the start of the subject key, and it is looked up again. If that
+fails, further lookups are tried with dot-separated components removed from the
+start of the subject key, one-by-one, and <quote>*.</quote> added on the front of what
+remains.
+</para>
+<para>
+A minimum number of two non-* components are required. This can be adjusted
+by including a number before the hyphen in the search type. For example,
+<option>partial3-lsearch</option> specifies a minimum of three non-* components in the
+modified keys. Omitting the number is equivalent to <quote>partial2-</quote>. If the
+subject key is <emphasis>2250.dates.fict.example</emphasis> then the following keys are looked
+up when the minimum number of non-* components is two:
+</para>
+<literallayout class="monospaced">
+2250.dates.fict.example
+*.2250.dates.fict.example
+*.dates.fict.example
+*.fict.example
+</literallayout>
+<para>
+As soon as one key in the sequence is successfully looked up, the lookup
+finishes.
+</para>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>partial matching – changing prefix</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>prefix</primary>
+<secondary>for partial matching</secondary>
+</indexterm>
+The use of <quote>*.</quote> as the partial matching prefix is a default that can be
+changed. The motivation for this feature is to allow Exim to operate with file
+formats that are used by other MTAs. A different prefix can be supplied in
+parentheses instead of the hyphen after <quote>partial</quote>. For example:
+</para>
+<literallayout class="monospaced">
+domains = partial(.)lsearch;/some/file
+</literallayout>
+<para>
+In this example, if the domain is <emphasis>a.b.c</emphasis>, the sequence of lookups is
+<literal>a.b.c</literal>, <literal>.a.b.c</literal>, and <literal>.b.c</literal> (the default minimum of 2 non-wild
+components is unchanged). The prefix may consist of any punctuation characters
+other than a closing parenthesis. It may be empty, for example:
+</para>
+<literallayout class="monospaced">
+domains = partial1()cdb;/some/file
+</literallayout>
+<para>
+For this example, if the domain is <emphasis>a.b.c</emphasis>, the sequence of lookups is
+<literal>a.b.c</literal>, <literal>b.c</literal>, and <literal>c</literal>.
+</para>
+<para>
+If <quote>partial0</quote> is specified, what happens at the end (when the lookup with
+just one non-wild component has failed, and the original key is shortened right
+down to the null string) depends on the prefix:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If the prefix has zero length, the whole lookup fails.
+</para>
+</listitem>
+<listitem>
+<para>
+If the prefix has length 1, a lookup for just the prefix is done. For
+example, the final lookup for <quote>partial0(.)</quote> is for <literal>.</literal> alone.
+</para>
+</listitem>
+<listitem>
+<para>
+Otherwise, if the prefix ends in a dot, the dot is removed, and the
+remainder is looked up. With the default prefix, therefore, the final lookup is
+for <quote>*</quote> on its own.
+</para>
+</listitem>
+<listitem>
+<para>
+Otherwise, the whole prefix is looked up.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+If the search type ends in <quote>*</quote> or <quote>*@</quote> (see section
+<xref linkend="SECTdefaultvaluelookups"/> above), the search for an ultimate default that
+this implies happens after all partial lookups have failed. If <quote>partial0</quote> is
+specified, adding <quote>*</quote> to the search type has no effect with the default
+prefix, because the <quote>*</quote> key is already included in the sequence of partial
+lookups. However, there might be a use for lookup types such as
+<quote>partial0(.)lsearch*</quote>.
+</para>
+<para>
+The use of <quote>*</quote> in lookup partial matching differs from its use as a wildcard
+in domain lists and the like. Partial matching works only in terms of
+dot-separated components; a key such as <literal>*fict.example</literal>
+in a database file is useless, because the asterisk in a partial matching
+subject key is always followed by a dot.
+</para>
+</section>
+<section id="SECID64">
+<title>Lookup caching</title>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>caching</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>caching</primary>
+<secondary>lookup data</secondary>
+</indexterm>
+Exim caches all lookup results in order to avoid needless repetition of
+lookups. However, because (apart from the daemon) Exim operates as a collection
+of independent, short-lived processes, this caching applies only within a
+single Exim process. There is no inter-process lookup caching facility.
+</para>
+<para>
+For single-key lookups, Exim keeps the relevant files open in case there is
+another lookup that needs them. In some types of configuration this can lead to
+many files being kept open for messages with many recipients. To avoid hitting
+the operating system limit on the number of simultaneously open files, Exim
+closes the least recently used file when it needs to open more files than its
+own internal limit, which can be changed via the <option>lookup_open_max</option> option.
+</para>
+<para>
+The single-key lookup files are closed and the lookup caches are flushed at
+strategic points during delivery – for example, after all routing is
+complete.
+</para>
+</section>
+<section id="SECID65">
+<title>Quoting lookup data</title>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>quoting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>quoting</primary>
+<secondary>in lookups</secondary>
+</indexterm>
+When data from an incoming message is included in a query-style lookup, there
+is the possibility of special characters in the data messing up the syntax of
+the query. For example, a NIS+ query that contains
+</para>
+<literallayout class="monospaced">
+[name=$local_part]
+</literallayout>
+<para>
+will be broken if the local part happens to contain a closing square bracket.
+For NIS+, data can be enclosed in double quotes like this:
+</para>
+<literallayout class="monospaced">
+[name="$local_part"]
+</literallayout>
+<para>
+but this still leaves the problem of a double quote in the data. The rule for
+NIS+ is that double quotes must be doubled. Other lookup types have different
+rules, and to cope with the differing requirements, an expansion operator
+of the following form is provided:
+</para>
+<literallayout class="monospaced">
+${quote_<lookup-type>:<string>}
+</literallayout>
+<para>
+For example, the safest way to write the NIS+ query is
+</para>
+<literallayout class="monospaced">
+[name="${quote_nisplus:$local_part}"]
+</literallayout>
+<para>
+See chapter <xref linkend="CHAPexpand"/> for full coverage of string expansions. The quote
+operator can be used for all lookup types, but has no effect for single-key
+lookups, since no quoting is ever needed in their key strings.
+</para>
+</section>
+<section id="SECTdnsdb">
+<title>More about dnsdb</title>
+<para>
+<indexterm role="concept">
+<primary>dnsdb lookup</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>dnsdb</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>as a lookup type</secondary>
+</indexterm>
+The <command>dnsdb</command> lookup type uses the DNS as its database. A simple query consists
+of a record type and a domain name, separated by an equals sign. For example,
+an expansion string could contain:
+</para>
+<literallayout class="monospaced">
+${lookup dnsdb{mx=a.b.example}{$value}fail}
+</literallayout>
+<para>
+If the lookup succeeds, the result is placed in <varname>$value</varname>, which in this case
+is used on its own as the result. If the lookup does not succeed, the
+<literal>fail</literal> keyword causes a <emphasis>forced expansion failure</emphasis> – see section
+<xref linkend="SECTforexpfai"/> for an explanation of what this means.
+</para>
+<para>
+The supported DNS record types are A, CNAME, MX, NS, PTR, SOA, SPF, SRV, TLSA
+and TXT, and, when Exim is compiled with IPv6 support, AAAA.
+If no type is given, TXT is assumed.
+</para>
+<para>
+For any record type, if multiple records are found, the data is returned as a
+concatenation, with newline as the default separator. The order, of course,
+depends on the DNS resolver. You can specify a different separator character
+between multiple records by putting a right angle-bracket followed immediately
+by the new separator at the start of the query. For example:
+</para>
+<literallayout class="monospaced">
+${lookup dnsdb{>: a=host1.example}}
+</literallayout>
+<para>
+It is permitted to specify a space as the separator character. Further
+white space is ignored.
+For lookup types that return multiple fields per record,
+an alternate field separator can be specified using a comma after the main
+separator character, followed immediately by the field separator.
+</para>
+<para>
+<indexterm role="concept">
+<primary>PTR record</primary>
+<secondary>in <command>dnsdb</command> lookup</secondary>
+</indexterm>
+When the type is PTR,
+the data can be an IP address, written as normal; inversion and the addition of
+<option>in-addr.arpa</option> or <option>ip6.arpa</option> happens automatically. For example:
+</para>
+<literallayout class="monospaced">
+${lookup dnsdb{ptr=192.168.4.5}{$value}fail}
+</literallayout>
+<para>
+If the data for a PTR record is not a syntactically valid IP address, it is not
+altered and nothing is added.
+</para>
+<para>
+<indexterm role="concept">
+<primary>MX record</primary>
+<secondary>in <command>dnsdb</command> lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SRV record</primary>
+<secondary>in <command>dnsdb</command> lookup</secondary>
+</indexterm>
+For an MX lookup, both the preference value and the host name are returned for
+each record, separated by a space. For an SRV lookup, the priority, weight,
+port, and host name are returned for each record, separated by spaces.
+The field separator can be modified as above.
+</para>
+<para>
+<indexterm role="concept">
+<primary>TXT record</primary>
+<secondary>in <command>dnsdb</command> lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SPF record</primary>
+<secondary>in <command>dnsdb</command> lookup</secondary>
+</indexterm>
+For TXT records with multiple items of data, only the first item is returned,
+unless a field separator is specified.
+To concatenate items without a separator, use a semicolon instead.
+For SPF records the
+default behaviour is to concatenate multiple items without using a separator.
+</para>
+<literallayout class="monospaced">
+${lookup dnsdb{>\n,: txt=a.b.example}}
+${lookup dnsdb{>\n; txt=a.b.example}}
+${lookup dnsdb{spf=example.org}}
+</literallayout>
+<para>
+It is permitted to specify a space as the separator character. Further
+white space is ignored.
+</para>
+<para>
+<indexterm role="concept">
+<primary>SOA record</primary>
+<secondary>in <command>dnsdb</command> lookup</secondary>
+</indexterm>
+For an SOA lookup, while no result is obtained the lookup is redone with
+successively more leading components dropped from the given domain.
+Only the primary-nameserver field is returned unless a field separator is
+specified.
+</para>
+<literallayout class="monospaced">
+${lookup dnsdb{>:,; soa=a.b.example.com}}
+</literallayout>
+</section>
+<section id="SECTdnsdb_mod">
+<title>Dnsdb lookup modifiers</title>
+<para>
+<indexterm role="concept">
+<primary>dnsdb modifiers</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>modifiers</primary>
+<secondary>dnsdb</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary>dnsdb</secondary>
+</indexterm>
+Modifiers for <command>dnsdb</command> lookups are given by optional keywords,
+each followed by a comma,
+that may appear before the record type.
+</para>
+<para>
+The <command>dnsdb</command> lookup fails only if all the DNS lookups fail. If there is a
+temporary DNS error for any of them, the behaviour is controlled by
+a defer-option modifier.
+The possible keywords are
+<quote>defer_strict</quote>, <quote>defer_never</quote>, and <quote>defer_lax</quote>.
+With <quote>strict</quote> behaviour, any temporary DNS error causes the
+whole lookup to defer. With <quote>never</quote> behaviour, a temporary DNS error is
+ignored, and the behaviour is as if the DNS lookup failed to find anything.
+With <quote>lax</quote> behaviour, all the queries are attempted, but a temporary DNS
+error causes the whole lookup to defer only if none of the other lookups
+succeed. The default is <quote>lax</quote>, so the following lookups are equivalent:
+</para>
+<literallayout class="monospaced">
+${lookup dnsdb{defer_lax,a=one.host.com:two.host.com}}
+${lookup dnsdb{a=one.host.com:two.host.com}}
+</literallayout>
+<para>
+Thus, in the default case, as long as at least one of the DNS lookups
+yields some data, the lookup succeeds.
+</para>
+<para>
+<indexterm role="concept">
+<primary>DNSSEC</primary>
+<secondary>dns lookup</secondary>
+</indexterm>
+Use of <command>DNSSEC</command> is controlled by a dnssec modifier.
+The possible keywords are
+<quote>dnssec_strict</quote>, <quote>dnssec_lax</quote>, and <quote>dnssec_never</quote>.
+With <quote>strict</quote> or <quote>lax</quote> DNSSEC information is requested
+with the lookup.
+With <quote>strict</quote> a response from the DNS resolver that
+is not labelled as authenticated data
+is treated as equivalent to a temporary DNS error.
+The default is <quote>lax</quote>.
+</para>
+<para>
+See also the <varname>$lookup_dnssec_authenticated</varname> variable.
+</para>
+<para>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>dns lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>timeout</secondary>
+</indexterm>
+Timeout for the dnsdb lookup can be controlled by a retrans modifier.
+The form is <quote>retrans_VAL</quote> where VAL is an Exim time specification
+(e.g. <quote>5s</quote>).
+The default value is set by the main configuration option <option>dns_retrans</option>.
+</para>
+<para>
+Retries for the dnsdb lookup can be controlled by a retry modifier.
+The form if <quote>retry_VAL</quote> where VAL is an integer.
+The default count is set by the main configuration option <option>dns_retry</option>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>caching</primary>
+<secondary>of dns lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TTL</primary>
+<secondary>of dns lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>TTL</secondary>
+</indexterm>
+Dnsdb lookup results are cached within a single process (and its children).
+The cache entry lifetime is limited to the smallest time-to-live (TTL)
+value of the set of returned DNS records.
+</para>
+</section>
+<section id="SECID66">
+<title>Pseudo dnsdb record types</title>
+<para>
+<indexterm role="concept">
+<primary>MX record</primary>
+<secondary>in <command>dnsdb</command> lookup</secondary>
+</indexterm>
+By default, both the preference value and the host name are returned for
+each MX record, separated by a space. If you want only host names, you can use
+the pseudo-type MXH:
+</para>
+<literallayout class="monospaced">
+${lookup dnsdb{mxh=a.b.example}}
+</literallayout>
+<para>
+In this case, the preference values are omitted, and just the host names are
+returned.
+</para>
+<para>
+<indexterm role="concept">
+<primary>name server for enclosing domain</primary>
+</indexterm>
+Another pseudo-type is ZNS (for <quote>zone NS</quote>). It performs a lookup for NS
+records on the given domain, but if none are found, it removes the first
+component of the domain name, and tries again. This process continues until NS
+records are found or there are no more components left (or there is a DNS
+error). In other words, it may return the name servers for a top-level domain,
+but it never returns the root name servers. If there are no NS records for the
+top-level domain, the lookup fails. Consider these examples:
+</para>
+<literallayout class="monospaced">
+${lookup dnsdb{zns=xxx.quercite.com}}
+${lookup dnsdb{zns=xxx.edu}}
+</literallayout>
+<para>
+Assuming that in each case there are no NS records for the full domain name,
+the first returns the name servers for <option>quercite.com</option>, and the second returns
+the name servers for <option>edu</option>.
+</para>
+<para>
+You should be careful about how you use this lookup because, unless the
+top-level domain does not exist, the lookup always returns some host names. The
+sort of use to which this might be put is for seeing if the name servers for a
+given domain are on a blacklist. You can probably assume that the name servers
+for the high-level domains such as <option>com</option> or <option>co.uk</option> are not going to be on
+such a list.
+</para>
+<para>
+<indexterm role="concept">
+<primary>CSA</primary>
+<secondary>in <command>dnsdb</command> lookup</secondary>
+</indexterm>
+A third pseudo-type is CSA (Client SMTP Authorization). This looks up SRV
+records according to the CSA rules, which are described in section
+<xref linkend="SECTverifyCSA"/>. Although <command>dnsdb</command> supports SRV lookups directly, this is
+not sufficient because of the extra parent domain search behaviour of CSA. The
+result of a successful lookup such as:
+</para>
+<literallayout class="monospaced">
+${lookup dnsdb {csa=$sender_helo_name}}
+</literallayout>
+<para>
+has two space-separated fields: an authorization code and a target host name.
+The authorization code can be <quote>Y</quote> for yes, <quote>N</quote> for no, <quote>X</quote> for explicit
+authorization required but absent, or <quote>?</quote> for unknown.
+</para>
+<para>
+<indexterm role="concept">
+<primary>A+</primary>
+<secondary>in <command>dnsdb</command> lookup</secondary>
+</indexterm>
+The pseudo-type A+ performs an AAAA
+and then an A lookup. All results are returned; defer processing
+(see below) is handled separately for each lookup. Example:
+</para>
+<literallayout class="monospaced">
+${lookup dnsdb {>; a+=$sender_helo_name}}
+</literallayout>
+</section>
+<section id="SECID67">
+<title>Multiple dnsdb lookups</title>
+<para>
+In the previous sections, <command>dnsdb</command> lookups for a single domain are described.
+However, you can specify a list of domains or IP addresses in a single
+<command>dnsdb</command> lookup. The list is specified in the normal Exim way, with colon as
+the default separator, but with the ability to change this. For example:
+</para>
+<literallayout class="monospaced">
+${lookup dnsdb{one.domain.com:two.domain.com}}
+${lookup dnsdb{a=one.host.com:two.host.com}}
+${lookup dnsdb{ptr = <; 1.2.3.4 ; 4.5.6.8}}
+</literallayout>
+<para>
+In order to retain backwards compatibility, there is one special case: if
+the lookup type is PTR and no change of separator is specified, Exim looks
+to see if the rest of the string is precisely one IPv6 address. In this
+case, it does not treat it as a list.
+</para>
+<para>
+The data from each lookup is concatenated, with newline separators by default,
+in the same way that multiple DNS records for a single item are handled. A
+different separator can be specified, as described above.
+</para>
+</section>
+<section id="SECTldap">
+<title>More about LDAP</title>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>lookup, more about</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>LDAP</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Solaris</primary>
+<secondary>LDAP</secondary>
+</indexterm>
+The original LDAP implementation came from the University of Michigan; this has
+become <quote>Open LDAP</quote>, and there are now two different releases. Another
+implementation comes from Netscape, and Solaris 7 and subsequent releases
+contain inbuilt LDAP support. Unfortunately, though these are all compatible at
+the lookup function level, their error handling is different. For this reason
+it is necessary to set a compile-time variable when building Exim with LDAP, to
+indicate which LDAP library is in use. One of the following should appear in
+your <filename>Local/Makefile</filename>:
+</para>
+<literallayout class="monospaced">
+LDAP_LIB_TYPE=UMICHIGAN
+LDAP_LIB_TYPE=OPENLDAP1
+LDAP_LIB_TYPE=OPENLDAP2
+LDAP_LIB_TYPE=NETSCAPE
+LDAP_LIB_TYPE=SOLARIS
+</literallayout>
+<para>
+If LDAP_LIB_TYPE is not set, Exim assumes <literal>OPENLDAP1</literal>, which has the
+same interface as the University of Michigan version.
+</para>
+<para>
+There are three LDAP lookup types in Exim. These behave slightly differently in
+the way they handle the results of a query:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<command>ldap</command> requires the result to contain just one entry; if there are more, it
+gives an error.
+</para>
+</listitem>
+<listitem>
+<para>
+<command>ldapdn</command> also requires the result to contain just one entry, but it is the
+Distinguished Name that is returned rather than any attribute values.
+</para>
+</listitem>
+<listitem>
+<para>
+<command>ldapm</command> permits the result to contain more than one entry; the attributes
+from all of them are returned.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+For <command>ldap</command> and <command>ldapm</command>, if a query finds only entries with no attributes,
+Exim behaves as if the entry did not exist, and the lookup fails. The format of
+the data returned by a successful lookup is described in the next section.
+First we explain how LDAP queries are coded.
+</para>
+</section>
+<section id="SECTforldaque">
+<title>Format of LDAP queries</title>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>query format</secondary>
+</indexterm>
+An LDAP query takes the form of a URL as defined in RFC 2255. For example, in
+the configuration of a <command>redirect</command> router one might have this setting:
+</para>
+<literallayout class="monospaced">
+data = ${lookup ldap \
+ {ldap:///cn=$local_part,o=University%20of%20Cambridge,\
+ c=UK?mailbox?base?}}
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>with TLS</secondary>
+</indexterm>
+The URL may begin with <literal>ldap</literal> or <literal>ldaps</literal> if your LDAP library supports
+secure (encrypted) LDAP connections. The second of these ensures that an
+encrypted TLS connection is used.
+</para>
+<para>
+With sufficiently modern LDAP libraries, Exim supports forcing TLS over regular
+LDAP connections, rather than the SSL-on-connect <literal>ldaps</literal>.
+See the <option>ldap_start_tls</option> option.
+</para>
+<para>
+Starting with Exim 4.83, the initialization of LDAP with TLS is more tightly
+controlled. Every part of the TLS configuration can be configured by settings in
+<filename>exim.conf</filename>. Depending on the version of the client libraries installed on
+your system, some of the initialization may have required setting options in
+<filename>/etc/ldap.conf</filename> or <filename>~/.ldaprc</filename> to get TLS working with self-signed
+certificates. This revealed a nuance where the current UID that exim was
+running as could affect which config files it read. With Exim 4.83, these
+methods become optional, only taking effect if not specifically set in
+<filename>exim.conf</filename>.
+</para>
+</section>
+<section id="SECID68">
+<title>LDAP quoting</title>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>quoting</secondary>
+</indexterm>
+Two levels of quoting are required in LDAP queries, the first for LDAP itself
+and the second because the LDAP query is represented as a URL. Furthermore,
+within an LDAP query, two different kinds of quoting are required. For this
+reason, there are two different LDAP-specific quoting operators.
+</para>
+<para>
+The <option>quote_ldap</option> operator is designed for use on strings that are part of
+filter specifications. Conceptually, it first does the following conversions on
+the string:
+</para>
+<literallayout class="monospaced">
+* => \2A
+( => \28
+) => \29
+\ => \5C
+</literallayout>
+<para>
+in accordance with RFC 2254. The resulting string is then quoted according
+to the rules for URLs, that is, all non-alphanumeric characters except
+</para>
+<literallayout class="monospaced">
+! $ ' - . _ ( ) * +
+</literallayout>
+<para>
+are converted to their hex values, preceded by a percent sign. For example:
+</para>
+<literallayout class="monospaced">
+${quote_ldap: a(bc)*, a<yz>; }
+</literallayout>
+<para>
+yields
+</para>
+<literallayout class="monospaced">
+%20a%5C28bc%5C29%5C2A%2C%20a%3Cyz%3E%3B%20
+</literallayout>
+<para>
+Removing the URL quoting, this is (with a leading and a trailing space):
+</para>
+<literallayout class="monospaced">
+a\28bc\29\2A, a<yz>;
+</literallayout>
+<para>
+The <option>quote_ldap_dn</option> operator is designed for use on strings that are part of
+base DN specifications in queries. Conceptually, it first converts the string
+by inserting a backslash in front of any of the following characters:
+</para>
+<literallayout class="monospaced">
+, + " \ < > ;
+</literallayout>
+<para>
+It also inserts a backslash before any leading spaces or # characters, and
+before any trailing spaces. (These rules are in RFC 2253.) The resulting string
+is then quoted according to the rules for URLs. For example:
+</para>
+<literallayout class="monospaced">
+${quote_ldap_dn: a(bc)*, a<yz>; }
+</literallayout>
+<para>
+yields
+</para>
+<literallayout class="monospaced">
+%5C%20a(bc)*%5C%2C%20a%5C%3Cyz%5C%3E%5C%3B%5C%20
+</literallayout>
+<para>
+Removing the URL quoting, this is (with a trailing space):
+</para>
+<literallayout class="monospaced">
+\ a(bc)*\, a\<yz\>\;\
+</literallayout>
+<para>
+There are some further comments about quoting in the section on LDAP
+authentication below.
+</para>
+</section>
+<section id="SECID69">
+<title>LDAP connections</title>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>connections</secondary>
+</indexterm>
+The connection to an LDAP server may either be over TCP/IP, or, when OpenLDAP
+is in use, via a Unix domain socket. The example given above does not specify
+an LDAP server. A server that is reached by TCP/IP can be specified in a query
+by starting it with
+</para>
+<literallayout class="monospaced">
+ldap://<hostname>:<port>/...
+</literallayout>
+<para>
+If the port (and preceding colon) are omitted, the standard LDAP port (389) is
+used. When no server is specified in a query, a list of default servers is
+taken from the <option>ldap_default_servers</option> configuration option. This supplies a
+colon-separated list of servers which are tried in turn until one successfully
+handles a query, or there is a serious error. Successful handling either
+returns the requested data, or indicates that it does not exist. Serious errors
+are syntactical, or multiple values when only a single value is expected.
+Errors which cause the next server to be tried are connection failures, bind
+failures, and timeouts.
+</para>
+<para>
+For each server name in the list, a port number can be given. The standard way
+of specifying a host and port is to use a colon separator (RFC 1738). Because
+<option>ldap_default_servers</option> is a colon-separated list, such colons have to be
+doubled. For example
+</para>
+<literallayout class="monospaced">
+ldap_default_servers = ldap1.example.com::145:ldap2.example.com
+</literallayout>
+<para>
+If <option>ldap_default_servers</option> is unset, a URL with no server name is passed
+to the LDAP library with no server name, and the library’s default (normally
+the local host) is used.
+</para>
+<para>
+If you are using the OpenLDAP library, you can connect to an LDAP server using
+a Unix domain socket instead of a TCP/IP connection. This is specified by using
+<literal>ldapi</literal> instead of <literal>ldap</literal> in LDAP queries. What follows here applies only
+to OpenLDAP. If Exim is compiled with a different LDAP library, this feature is
+not available.
+</para>
+<para>
+For this type of connection, instead of a host name for the server, a pathname
+for the socket is required, and the port number is not relevant. The pathname
+can be specified either as an item in <option>ldap_default_servers</option>, or inline in
+the query. In the former case, you can have settings such as
+</para>
+<literallayout class="monospaced">
+ldap_default_servers = /tmp/ldap.sock : backup.ldap.your.domain
+</literallayout>
+<para>
+When the pathname is given in the query, you have to escape the slashes as
+<literal>%2F</literal> to fit in with the LDAP URL syntax. For example:
+</para>
+<literallayout class="monospaced">
+${lookup ldap {ldapi://%2Ftmp%2Fldap.sock/o=...
+</literallayout>
+<para>
+When Exim processes an LDAP lookup and finds that the <quote>hostname</quote> is really
+a pathname, it uses the Unix domain socket code, even if the query actually
+specifies <literal>ldap</literal> or <literal>ldaps</literal>. In particular, no encryption is used for a
+socket connection. This behaviour means that you can use a setting of
+<option>ldap_default_servers</option> such as in the example above with traditional <literal>ldap</literal>
+or <literal>ldaps</literal> queries, and it will work. First, Exim tries a connection via
+the Unix domain socket; if that fails, it tries a TCP/IP connection to the
+backup host.
+</para>
+<para>
+If an explicit <literal>ldapi</literal> type is given in a query when a host name is
+specified, an error is diagnosed. However, if there are more items in
+<option>ldap_default_servers</option>, they are tried. In other words:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Using a pathname with <literal>ldap</literal> or <literal>ldaps</literal> forces the use of the Unix domain
+interface.
+</para>
+</listitem>
+<listitem>
+<para>
+Using <literal>ldapi</literal> with a host name causes an error.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Using <literal>ldapi</literal> with no host or path in the query, and no setting of
+<option>ldap_default_servers</option>, does whatever the library does by default.
+</para>
+</section>
+<section id="SECID70">
+<title>LDAP authentication and control information</title>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>authentication</secondary>
+</indexterm>
+The LDAP URL syntax provides no way of passing authentication and other control
+information to the server. To make this possible, the URL in an LDAP query may
+be preceded by any number of <<emphasis>name</emphasis>>=<<emphasis>value</emphasis>> settings, separated by
+spaces. If a value contains spaces it must be enclosed in double quotes, and
+when double quotes are used, backslash is interpreted in the usual way inside
+them. The following names are recognized:
+</para>
+<literallayout>
+<literal>DEREFERENCE</literal> set the dereferencing parameter
+<literal>NETTIME </literal> set a timeout for a network operation
+<literal>USER </literal> set the DN, for authenticating the LDAP bind
+<literal>PASS </literal> set the password, likewise
+<literal>REFERRALS </literal> set the referrals parameter
+<literal>SERVERS </literal> set alternate server list for this query only
+<literal>SIZE </literal> set the limit for the number of entries returned
+<literal>TIME </literal> set the maximum waiting time for a query
+</literallayout>
+<para>
+The value of the DEREFERENCE parameter must be one of the words <quote>never</quote>,
+<quote>searching</quote>, <quote>finding</quote>, or <quote>always</quote>. The value of the REFERRALS parameter
+must be <quote>follow</quote> (the default) or <quote>nofollow</quote>. The latter stops the LDAP
+library from trying to follow referrals issued by the LDAP server.
+</para>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>timeout</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>LDAP lookup</secondary>
+</indexterm>
+The name CONNECT is an obsolete name for NETTIME, retained for
+backwards compatibility. This timeout (specified as a number of seconds) is
+enforced from the client end for operations that can be carried out over a
+network. Specifically, it applies to network connections and calls to the
+<emphasis>ldap_result()</emphasis> function. If the value is greater than zero, it is used if
+LDAP_OPT_NETWORK_TIMEOUT is defined in the LDAP headers (OpenLDAP), or
+if LDAP_X_OPT_CONNECT_TIMEOUT is defined in the LDAP headers (Netscape
+SDK 4.1). A value of zero forces an explicit setting of <quote>no timeout</quote> for
+Netscape SDK; for OpenLDAP no action is taken.
+</para>
+<para>
+The TIME parameter (also a number of seconds) is passed to the server to
+set a server-side limit on the time taken to complete a search.
+</para>
+<para>
+The SERVERS parameter allows you to specify an alternate list of ldap servers
+to use for an individual lookup. The global <option>ldap_default_servers</option> option provides a
+default list of ldap servers, and a single lookup can specify a single ldap
+server to use. But when you need to do a lookup with a list of servers that is
+different than the default list (maybe different order, maybe a completely
+different set of servers), the SERVERS parameter allows you to specify this
+alternate list (colon-separated).
+</para>
+<para>
+Here is an example of an LDAP query in an Exim lookup that uses some of these
+values. This is a single line, folded to fit on the page:
+</para>
+<literallayout class="monospaced">
+${lookup ldap
+ {user="cn=manager,o=University of Cambridge,c=UK" pass=secret
+ ldap:///o=University%20of%20Cambridge,c=UK?sn?sub?(cn=foo)}
+ {$value}fail}
+</literallayout>
+<para>
+The encoding of spaces as <literal>%20</literal> is a URL thing which should not be done for
+any of the auxiliary data. Exim configuration settings that include lookups
+which contain password information should be preceded by <quote>hide</quote> to prevent
+non-admin users from using the <option>-bP</option> option to see their values.
+</para>
+<para>
+The auxiliary data items may be given in any order. The default is no
+connection timeout (the system timeout is used), no user or password, no limit
+on the number of entries returned, and no time limit on queries.
+</para>
+<para>
+When a DN is quoted in the USER= setting for LDAP authentication, Exim
+removes any URL quoting that it may contain before passing it LDAP. Apparently
+some libraries do this for themselves, but some do not. Removing the URL
+quoting has two advantages:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+It makes it possible to use the same <option>quote_ldap_dn</option> expansion for USER=
+DNs as with DNs inside actual queries.
+</para>
+</listitem>
+<listitem>
+<para>
+It permits spaces inside USER= DNs.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+For example, a setting such as
+</para>
+<literallayout class="monospaced">
+USER=cn=${quote_ldap_dn:$1}
+</literallayout>
+<para>
+should work even if <varname>$1</varname> contains spaces.
+</para>
+<para>
+Expanded data for the PASS= value should be quoted using the <option>quote</option>
+expansion operator, rather than the LDAP quote operators. The only reason this
+field needs quoting is to ensure that it conforms to the Exim syntax, which
+does not allow unquoted spaces. For example:
+</para>
+<literallayout class="monospaced">
+PASS=${quote:$3}
+</literallayout>
+<para>
+The LDAP authentication mechanism can be used to check passwords as part of
+SMTP authentication. See the <option>ldapauth</option> expansion string condition in chapter
+<xref linkend="CHAPexpand"/>.
+</para>
+</section>
+<section id="SECID71">
+<title>Format of data returned by LDAP</title>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>returned data formats</secondary>
+</indexterm>
+The <command>ldapdn</command> lookup type returns the Distinguished Name from a single entry
+as a sequence of values, for example
+</para>
+<literallayout class="monospaced">
+cn=manager,o=University of Cambridge,c=UK
+</literallayout>
+<para>
+The <command>ldap</command> lookup type generates an error if more than one entry matches the
+search filter, whereas <command>ldapm</command> permits this case, and inserts a newline in
+the result between the data from different entries. It is possible for multiple
+values to be returned for both <command>ldap</command> and <command>ldapm</command>, but in the former case
+you know that whatever values are returned all came from a single entry in the
+directory.
+</para>
+<para>
+In the common case where you specify a single attribute in your LDAP query, the
+result is not quoted, and does not contain the attribute name. If the attribute
+has multiple values, they are separated by commas. Any comma that is
+part of an attribute’s value is doubled.
+</para>
+<para>
+If you specify multiple attributes, the result contains space-separated, quoted
+strings, each preceded by the attribute name and an equals sign. Within the
+quotes, the quote character, backslash, and newline are escaped with
+backslashes, and commas are used to separate multiple values for the attribute.
+Any commas in attribute values are doubled
+(permitting treatment of the values as a comma-separated list).
+Apart from the escaping, the string within quotes takes the same form as the
+output when a single attribute is requested. Specifying no attributes is the
+same as specifying all of an entry’s attributes.
+</para>
+<para>
+Here are some examples of the output format. The first line of each pair is an
+LDAP query, and the second is the data that is returned. The attribute called
+<option>attr1</option> has two values, one of them with an embedded comma, whereas
+<option>attr2</option> has only one value. Both attributes are derived from <option>attr</option>
+(they have SUP <option>attr</option> in their schema definitions).
+</para>
+<literallayout class="monospaced">
+ldap:///o=base?attr1?sub?(uid=fred)
+value1.1,value1,,2
+
+ldap:///o=base?attr2?sub?(uid=fred)
+value two
+
+ldap:///o=base?attr?sub?(uid=fred)
+value1.1,value1,,2,value two
+
+ldap:///o=base?attr1,attr2?sub?(uid=fred)
+attr1="value1.1,value1,,2" attr2="value two"
+
+ldap:///o=base??sub?(uid=fred)
+objectClass="top" attr1="value1.1,value1,,2" attr2="value two"
+</literallayout>
+<para>
+You can
+make use of Exim’s <option>-be</option> option to run expansion tests and thereby check the
+results of LDAP lookups.
+The <option>extract</option> operator in string expansions can be used to pick out
+individual fields from data that consists of <emphasis>key</emphasis>=<emphasis>value</emphasis> pairs.
+The <option>listextract</option> operator should be used to pick out individual values
+of attributes, even when only a single value is expected.
+The doubling of embedded commas allows you to use the returned data as a
+comma separated list (using the "<," syntax for changing the input list separator).
+</para>
+</section>
+<section id="SECTnisplus">
+<title>More about NIS+</title>
+<para>
+<indexterm role="concept">
+<primary>NIS+ lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>NIS+</secondary>
+</indexterm>
+NIS+ queries consist of a NIS+ <emphasis>indexed name</emphasis> followed by an optional colon
+and field name. If this is given, the result of a successful query is the
+contents of the named field; otherwise the result consists of a concatenation
+of <emphasis>field-name=field-value</emphasis> pairs, separated by spaces. Empty values and
+values containing spaces are quoted. For example, the query
+</para>
+<literallayout class="monospaced">
+[name=mg1456],passwd.org_dir
+</literallayout>
+<para>
+might return the string
+</para>
+<literallayout class="monospaced">
+name=mg1456 passwd="" uid=999 gid=999 gcos="Martin Guerre"
+home=/home/mg1456 shell=/bin/bash shadow=""
+</literallayout>
+<para>
+(split over two lines here to fit on the page), whereas
+</para>
+<literallayout class="monospaced">
+[name=mg1456],passwd.org_dir:gcos
+</literallayout>
+<para>
+would just return
+</para>
+<literallayout class="monospaced">
+Martin Guerre
+</literallayout>
+<para>
+with no quotes. A NIS+ lookup fails if NIS+ returns more than one table entry
+for the given indexed key. The effect of the <option>quote_nisplus</option> expansion
+operator is to double any quote characters within the text.
+</para>
+</section>
+<section id="SECTsql">
+<title>SQL lookups</title>
+<para>
+<indexterm role="concept">
+<primary>SQL lookup types</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>MySQL</primary>
+<secondary>lookup type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>PostgreSQL lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>MySQL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>PostgreSQL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Oracle</primary>
+<secondary>lookup type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>Oracle</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>InterBase lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>InterBase</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Redis lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>Redis</secondary>
+</indexterm>
+Exim can support lookups in InterBase, MySQL, Oracle, PostgreSQL, Redis,
+and SQLite
+databases. Queries for these databases contain SQL statements, so an example
+might be
+</para>
+<literallayout class="monospaced">
+${lookup mysql{select mailbox from users where id='userx'}\
+ {$value}fail}
+</literallayout>
+<para>
+If the result of the query contains more than one field, the data for each
+field in the row is returned, preceded by its name, so the result of
+</para>
+<literallayout class="monospaced">
+${lookup pgsql{select home,name from users where id='userx'}\
+ {$value}}
+</literallayout>
+<para>
+might be
+</para>
+<literallayout class="monospaced">
+home=/home/userx name="Mister X"
+</literallayout>
+<para>
+Empty values and values containing spaces are double quoted, with embedded
+quotes escaped by a backslash. If the result of the query contains just one
+field, the value is passed back verbatim, without a field name, for example:
+</para>
+<literallayout class="monospaced">
+Mister X
+</literallayout>
+<para>
+If the result of the query yields more than one row, it is all concatenated,
+with a newline between the data for each row.
+</para>
+</section>
+<section id="SECID72">
+<title>More about MySQL, PostgreSQL, Oracle, InterBase, and Redis</title>
+<para>
+<indexterm role="concept">
+<primary>MySQL</primary>
+<secondary>lookup type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>PostgreSQL lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>MySQL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>PostgreSQL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Oracle</primary>
+<secondary>lookup type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>Oracle</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>InterBase lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>InterBase</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Redis lookup type</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>Redis</secondary>
+</indexterm>
+If any MySQL, PostgreSQL, Oracle, InterBase or Redis lookups are used, the
+<option>mysql_servers</option>, <option>pgsql_servers</option>, <option>oracle_servers</option>, <option>ibase_servers</option>,
+or <option>redis_servers</option>
+option (as appropriate) must be set to a colon-separated list of server
+information.
+<indexterm role="option">
+<primary><option>mysql_servers</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>pgsql_servers</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>oracle_servers</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>ibase_servers</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>redis_servers</option></primary>
+</indexterm>
+(For MySQL and PostgreSQL, the global option need not be set if all
+queries contain their own server information – see section
+<xref linkend="SECTspeserque"/>.)
+For all but Redis
+each item in the list is a slash-separated list of four
+items: host name, database name, user name, and password. In the case of
+Oracle, the host name field is used for the <quote>service name</quote>, and the database
+name field is not used and should be empty. For example:
+</para>
+<literallayout class="monospaced">
+hide oracle_servers = oracle.plc.example//userx/abcdwxyz
+</literallayout>
+<para>
+Because password data is sensitive, you should always precede the setting with
+<quote>hide</quote>, to prevent non-admin users from obtaining the setting via the <option>-bP</option>
+option. Here is an example where two MySQL servers are listed:
+</para>
+<literallayout class="monospaced">
+hide mysql_servers = localhost/users/root/secret:\
+ otherhost/users/root/othersecret
+</literallayout>
+<para>
+For MySQL and PostgreSQL, a host may be specified as <<emphasis>name</emphasis>>:<<emphasis>port</emphasis>> but
+because this is a colon-separated list, the colon has to be doubled. For each
+query, these parameter groups are tried in order until a connection is made and
+a query is successfully processed. The result of a query may be that no data is
+found, but that is still a successful query. In other words, the list of
+servers provides a backup facility, not a list of different places to look.
+</para>
+<para>
+For Redis the global option need not be specified if all queries contain their
+own server information – see section <xref linkend="SECTspeserque"/>.
+If specified, the option must be set to a colon-separated list of server
+information.
+Each item in the list is a slash-separated list of three items:
+host, database number, and password.
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+The host is required and may be either an IPv4 address and optional
+port number (separated by a colon, which needs doubling due to the
+higher-level list), or a Unix socket pathname enclosed in parentheses
+</para>
+</listitem>
+<listitem>
+<para>
+The database number is optional; if present that number is selected in the backend
+</para>
+</listitem>
+<listitem>
+<para>
+The password is optional; if present it is used to authenticate to the backend
+</para>
+</listitem>
+</orderedlist>
+<para>
+The <option>quote_mysql</option>, <option>quote_pgsql</option>, and <option>quote_oracle</option> expansion operators
+convert newline, tab, carriage return, and backspace to \n, \t, \r, and \b
+respectively, and the characters single-quote, double-quote, and backslash
+itself are escaped with backslashes.
+</para>
+<para>
+The <option>quote_redis</option> expansion operator
+escapes whitespace and backslash characters with a backslash.
+</para>
+</section>
+<section id="SECTspeserque">
+<title>Specifying the server in the query</title>
+<para revisionflag="changed">
+For MySQL, PostgreSQL and Redis lookups (but not currently for Oracle and InterBase),
+it is possible to specify a list of servers with an individual query. This is
+done by appending a comma-separated option to the query type:
+</para>
+<literallayout revisionflag="changed">
+</literallayout>
+<para revisionflag="changed">
+<literal>,servers=</literal><emphasis>server1:server2:server3:...</emphasis>
+</para>
+<para>
+Each item in the list may take one of two forms:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+If it contains no slashes it is assumed to be just a host name. The appropriate
+global option (<option>mysql_servers</option> or <option>pgsql_servers</option>) is searched for a host
+of the same name, and the remaining parameters (database, user, password) are
+taken from there.
+</para>
+</listitem>
+<listitem>
+<para>
+If it contains any slashes, it is taken as a complete parameter set.
+</para>
+</listitem>
+</orderedlist>
+<para>
+The list of servers is used in exactly the same way as the global list.
+Once a connection to a server has happened and a query has been
+successfully executed, processing of the lookup ceases.
+</para>
+<para>
+This feature is intended for use in master/slave situations where updates
+are occurring and you want to update the master rather than a slave. If the
+master is in the list as a backup for reading, you might have a global setting
+like this:
+</para>
+<literallayout class="monospaced">
+mysql_servers = slave1/db/name/pw:\
+ slave2/db/name/pw:\
+ master/db/name/pw
+</literallayout>
+<para>
+In an updating lookup, you could then write:
+</para>
+<literallayout class="monospaced">
+${lookup mysql,servers=master {UPDATE ...} }
+</literallayout>
+<para>
+That query would then be sent only to the master server. If, on the other hand,
+the master is not to be used for reading, and so is not present in the global
+option, you can still update it by a query of this form:
+</para>
+<literallayout class="monospaced">
+${lookup pgsql,servers=master/db/name/pw {UPDATE ...} }
+</literallayout>
+<para revisionflag="changed">
+An older syntax places the servers speciification before the qury,
+semicolon separated:
+</para>
+<literallayout class="monospaced" revisionflag="changed">
+${lookup mysql{servers=master; UPDATE ...} }
+</literallayout>
+<para revisionflag="changed">
+The new version avoids potential issues with tainted
+arguments in the query, for explicit expansion.
+<emphasis role="bold">Note</emphasis>: server specifications in list-style lookups are still problematic.
+</para>
+</section>
+<section id="SECID73">
+<title>Special MySQL features</title>
+<para>
+For MySQL, an empty host name or the use of <quote>localhost</quote> in <option>mysql_servers</option>
+causes a connection to the server on the local host by means of a Unix domain
+socket. An alternate socket can be specified in parentheses.
+An option group name for MySQL option files can be specified in square brackets;
+the default value is <quote>exim</quote>.
+The full syntax of each item in <option>mysql_servers</option> is:
+</para>
+<literallayout>
+<<emphasis>hostname</emphasis>>::<<emphasis>port</emphasis>>(<<emphasis>socket name</emphasis>>)[<<emphasis>option group</emphasis>>]/<<emphasis>database</emphasis>>/<<emphasis>user</emphasis>>/<<emphasis>password</emphasis>>
+</literallayout>
+<para>
+Any of the four sub-parts of the first field can be omitted. For normal use on
+the local host it can be left blank or set to just <quote>localhost</quote>.
+</para>
+<para>
+No database need be supplied – but if it is absent here, it must be given in
+the queries.
+</para>
+<para>
+If a MySQL query is issued that does not request any data (an insert, update,
+or delete command), the result of the lookup is the number of rows affected.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: This can be misleading. If an update does not actually change
+anything (for example, setting a field to the value it already has), the result
+is zero because no rows are affected.
+</para>
+</section>
+<section id="SECID74">
+<title>Special PostgreSQL features</title>
+<para>
+PostgreSQL lookups can also use Unix domain socket connections to the database.
+This is usually faster and costs less CPU time than a TCP/IP connection.
+However it can be used only if the mail server runs on the same machine as the
+database server. A configuration line for PostgreSQL via Unix domain sockets
+looks like this:
+</para>
+<literallayout class="monospaced">
+hide pgsql_servers = (/tmp/.s.PGSQL.5432)/db/user/password : ...
+</literallayout>
+<para>
+In other words, instead of supplying a host name, a path to the socket is
+given. The path name is enclosed in parentheses so that its slashes aren’t
+visually confused with the delimiters for the other server parameters.
+</para>
+<para>
+If a PostgreSQL query is issued that does not request any data (an insert,
+update, or delete command), the result of the lookup is the number of rows
+affected.
+</para>
+</section>
+<section id="SECTsqlite">
+<title>More about SQLite</title>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>SQLite</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>sqlite lookup type</primary>
+</indexterm>
+SQLite is different to the other SQL lookups because a filename is required in
+addition to the SQL query. An SQLite database is a single file, and there is no
+daemon as in the other SQL databases.
+</para>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>sqlite_dbfile</option></primary>
+</indexterm>
+The preferred way of specifying the file is by using the
+<option>sqlite_dbfile</option> option, set to
+an absolute path.
+</para>
+<para>
+A deprecated method is available, prefixing the query with the filename
+separated by white space.
+This means that the path name cannot contain white space.
+<indexterm role="concept">
+<primary>tainted data</primary>
+<secondary>sqlite file</secondary>
+</indexterm>
+It also means that the query cannot use any tainted values, as that taints
+the entire query including the filename - resulting in a refusal to open
+the file.
+</para>
+<para revisionflag="changed">
+Here is a lookup expansion example:
+</para>
+<literallayout class="monospaced" revisionflag="changed">
+sqlite_dbfile = /some/thing/sqlitedb
+...
+${lookup sqlite {select name from aliases where id='userx';}}
+</literallayout>
+<para revisionflag="changed">
+In a list, the syntax is similar. For example:
+</para>
+<literallayout class="monospaced" revisionflag="changed">
+domainlist relay_to_domains = sqlite;\
+ select * from relays where ip='$sender_host_address';
+</literallayout>
+<para>
+The only character affected by the <option>quote_sqlite</option> operator is a single
+quote, which it doubles.
+</para>
+<para>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>SQLite</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>sqlite</primary>
+<secondary>lookup timeout</secondary>
+</indexterm>
+The SQLite library handles multiple simultaneous accesses to the database
+internally. Multiple readers are permitted, but only one process can
+update at once. Attempts to access the database while it is being updated
+are rejected after a timeout period, during which the SQLite library
+waits for the lock to be released. In Exim, the default timeout is set
+to 5 seconds, but it can be changed by means of the <option>sqlite_lock_timeout</option>
+option.
+</para>
+</section>
+<section id="SECTredis">
+<title>More about Redis</title>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>Redis</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>redis lookup type</primary>
+</indexterm>
+Redis is a non-SQL database. Commands are simple get and set.
+Examples:
+</para>
+<literallayout class="monospaced">
+${lookup redis{set keyname ${quote_redis:objvalue plus}}}
+${lookup redis{get keyname}}
+</literallayout>
+<para>
+As of release 4.91, "lightweight" support for Redis Cluster is available.
+Requires <option>redis_servers</option> list to contain all the servers in the cluster, all
+of which must be reachable from the running exim instance. If the cluster has
+master/slave replication, the list must contain all the master and slave
+servers.
+</para>
+<para>
+When the Redis Cluster returns a "MOVED" response to a query, Exim does not
+immediately follow the redirection but treats the response as a DEFER, moving on
+to the next server in the <option>redis_servers</option> list until the correct server is
+reached.
+</para>
+<para>
+<indexterm role="concept" startref="IIDfidalo1" class="endofrange"/>
+<indexterm role="concept" startref="IIDfidalo2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPdomhosaddlists">
+<title>Domain, host, address, and local part lists</title>
+<titleabbrev>Domain, host, and address lists</titleabbrev>
+<para>
+<indexterm role="concept" id="IIDdohoadli" class="startofrange">
+<primary>lists of domains; hosts; etc.</primary>
+</indexterm>
+A number of Exim configuration options contain lists of domains, hosts,
+email addresses, or local parts. For example, the <option>hold_domains</option> option
+contains a list of domains whose delivery is currently suspended. These lists
+are also used as data in ACL statements (see chapter <xref linkend="CHAPACL"/>), and as
+arguments to expansion conditions such as <option>match_domain</option>.
+</para>
+<para>
+Each item in one of these lists is a pattern to be matched against a domain,
+host, email address, or local part, respectively. In the sections below, the
+different types of pattern for each case are described, but first we cover some
+general facilities that apply to all four kinds of list.
+</para>
+<para>
+Note that other parts of Exim use a <emphasis>string list</emphasis> which does not
+support all the complexity available in
+domain, host, address and local part lists.
+</para>
+<section id="SECTlistexpand">
+<title>Expansion of lists</title>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>of lists</secondary>
+</indexterm>
+Each list is expanded as a single string before it is used.
+</para>
+<para>
+<emphasis>Exception: the router headers_remove option, where list-item
+splitting is done before string-expansion.</emphasis>
+</para>
+<para>
+The result of
+expansion must be a list, possibly containing empty items, which is split up
+into separate items for matching. By default, colon is the separator character,
+but this can be varied if necessary. See sections <xref linkend="SECTlistconstruct"/> and
+<xref linkend="SECTempitelis"/> for details of the list syntax; the second of these
+discusses the way to specify empty list items.
+</para>
+<para>
+If the string expansion is forced to fail, Exim behaves as if the item it is
+testing (domain, host, address, or local part) is not in the list. Other
+expansion failures cause temporary errors.
+</para>
+<para>
+If an item in a list is a regular expression, backslashes, dollars and possibly
+other special characters in the expression must be protected against
+misinterpretation by the string expander. The easiest way to do this is to use
+the <literal>\N</literal> expansion feature to indicate that the contents of the regular
+expression should not be expanded. For example, in an ACL you might have:
+</para>
+<literallayout class="monospaced">
+deny senders = \N^\d{8}\w@.*\.baddomain\.example$\N : \
+ ${lookup{$domain}lsearch{/badsenders/bydomain}}
+</literallayout>
+<para>
+The first item is a regular expression that is protected from expansion by
+<literal>\N</literal>, whereas the second uses the expansion to obtain a list of unwanted
+senders based on the receiving domain.
+</para>
+</section>
+<section id="SECID76">
+<title>Negated items in lists</title>
+<para>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>negation</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>negation</primary>
+<secondary>in lists</secondary>
+</indexterm>
+Items in a list may be positive or negative. Negative items are indicated by a
+leading exclamation mark, which may be followed by optional white space. A list
+defines a set of items (domains, etc). When Exim processes one of these lists,
+it is trying to find out whether a domain, host, address, or local part
+(respectively) is in the set that is defined by the list. It works like this:
+</para>
+<para>
+The list is scanned from left to right. If a positive item is matched, the
+subject that is being checked is in the set; if a negative item is matched, the
+subject is not in the set. If the end of the list is reached without the
+subject having matched any of the patterns, it is in the set if the last item
+was a negative one, but not if it was a positive one. For example, the list in
+</para>
+<literallayout class="monospaced">
+domainlist relay_to_domains = !a.b.c : *.b.c
+</literallayout>
+<para>
+matches any domain ending in <emphasis>.b.c</emphasis> except for <emphasis>a.b.c</emphasis>. Domains that match
+neither <emphasis>a.b.c</emphasis> nor <emphasis>*.b.c</emphasis> do not match, because the last item in the
+list is positive. However, if the setting were
+</para>
+<literallayout class="monospaced">
+domainlist relay_to_domains = !a.b.c
+</literallayout>
+<para>
+then all domains other than <emphasis>a.b.c</emphasis> would match because the last item in the
+list is negative. In other words, a list that ends with a negative item behaves
+as if it had an extra item <literal>:*</literal> on the end.
+</para>
+<para>
+Another way of thinking about positive and negative items in lists is to read
+the connector as <quote>or</quote> after a positive item and as <quote>and</quote> after a negative
+item.
+</para>
+</section>
+<section id="SECTfilnamlis">
+<title>File names in lists</title>
+<para>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>filename in</secondary>
+</indexterm>
+If an item in a domain, host, address, or local part list is an absolute
+filename (beginning with a slash character), each line of the file is read and
+processed as if it were an independent item in the list, except that further
+filenames are not allowed,
+and no expansion of the data from the file takes place.
+Empty lines in the file are ignored, and the file may also contain comment
+lines:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+For domain and host lists, if a # character appears anywhere in a line of the
+file, it and all following characters are ignored.
+</para>
+</listitem>
+<listitem>
+<para>
+Because local parts may legitimately contain # characters, a comment in an
+address list or local part list file is recognized only if # is preceded by
+white space or the start of the line. For example:
+</para>
+<literallayout class="monospaced">
+not#comment@x.y.z # but this is a comment
+</literallayout>
+</listitem>
+</itemizedlist>
+<para>
+Putting a filename in a list has the same effect as inserting each line of the
+file as an item in the list (blank lines and comments excepted). However, there
+is one important difference: the file is read each time the list is processed,
+so if its contents vary over time, Exim’s behaviour changes.
+</para>
+<para>
+If a filename is preceded by an exclamation mark, the sense of any match
+within the file is inverted. For example, if
+</para>
+<literallayout class="monospaced">
+hold_domains = !/etc/nohold-domains
+</literallayout>
+<para>
+and the file contains the lines
+</para>
+<literallayout class="monospaced">
+!a.b.c
+*.b.c
+</literallayout>
+<para>
+then <emphasis>a.b.c</emphasis> is in the set of domains defined by <option>hold_domains</option>, whereas
+any domain matching <literal>*.b.c</literal> is not.
+</para>
+</section>
+<section id="SECID77">
+<title>An lsearch file is not an out-of-line list</title>
+<para>
+As will be described in the sections that follow, lookups can be used in lists
+to provide indexed methods of checking list membership. There has been some
+confusion about the way <command>lsearch</command> lookups work in lists. Because
+an <command>lsearch</command> file contains plain text and is scanned sequentially, it is
+sometimes thought that it is allowed to contain wild cards and other kinds of
+non-constant pattern. This is not the case. The keys in an <command>lsearch</command> file are
+always fixed strings, just as for any other single-key lookup type.
+</para>
+<para>
+If you want to use a file to contain wild-card patterns that form part of a
+list, just give the filename on its own, without a search type, as described
+in the previous section. You could also use the <command>wildlsearch</command> or
+<command>nwildlsearch</command>, but there is no advantage in doing this.
+</para>
+</section>
+<section id="SECTlistresults" revisionflag="changed">
+<title>Results of list checking</title>
+<para revisionflag="changed">
+The primary result of doing a list check is a truth value.
+In some contexts additional information is stored
+about the list element that matched:
+</para>
+<variablelist revisionflag="changed">
+<varlistentry revisionflag="changed">
+<term>hosts</term>
+<listitem>
+<para revisionflag="changed">
+A <option>hosts</option> ACL condition
+will store a result in the <varname>$host_data</varname> variable.
+</para>
+</listitem></varlistentry>
+<varlistentry revisionflag="changed">
+<term>local_parts</term>
+<listitem>
+<para revisionflag="changed">
+A <option>local_parts</option> router option or <option>local_parts</option> ACL condition
+will store a result in the <varname>$local_part_data</varname> variable.
+</para>
+</listitem></varlistentry>
+<varlistentry revisionflag="changed">
+<term>domains</term>
+<listitem>
+<para revisionflag="changed">
+A <option>domains</option> router option or <option>domains</option> ACL condition
+</para>
+</listitem></varlistentry>
+<varlistentry revisionflag="changed">
+<term>senders</term>
+<listitem>
+<para revisionflag="changed">
+A <option>senders</option> router option or <option>senders</option> ACL condition
+will store a result in the <varname>$sender_data</varname> variable.
+</para>
+</listitem></varlistentry>
+<varlistentry revisionflag="changed">
+<term>recipients</term>
+<listitem>
+<para revisionflag="changed">
+A <option>recipients</option> ACL condition
+will store a result in the <varname>$recipient_data</varname> variable.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para revisionflag="changed">
+The detail of the additional information depends on the
+type of match and is given below as the <emphasis role="bold">value</emphasis> information.
+</para>
+</section>
+<section id="SECTnamedlists">
+<title>Named lists</title>
+<para>
+<indexterm role="concept">
+<primary>named lists</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>named</secondary>
+</indexterm>
+A list of domains, hosts, email addresses, or local parts can be given a name
+which is then used to refer to the list elsewhere in the configuration. This is
+particularly convenient if the same list is required in several different
+places. It also allows lists to be given meaningful names, which can improve
+the readability of the configuration. For example, it is conventional to define
+a domain list called <emphasis>local_domains</emphasis> for all the domains that are handled
+locally on a host, using a configuration line such as
+</para>
+<literallayout class="monospaced">
+domainlist local_domains = localhost:my.dom.example
+</literallayout>
+<para>
+Named lists are referenced by giving their name preceded by a plus sign, so,
+for example, a router that is intended to handle local domains would be
+configured with the line
+</para>
+<literallayout class="monospaced">
+domains = +local_domains
+</literallayout>
+<para>
+The first router in a configuration is often one that handles all domains
+except the local ones, using a configuration with a negated item like this:
+</para>
+<literallayout class="monospaced">
+dnslookup:
+ driver = dnslookup
+ domains = ! +local_domains
+ transport = remote_smtp
+ no_more
+</literallayout>
+<para>
+The four kinds of named list are created by configuration lines starting with
+the words <option>domainlist</option>, <option>hostlist</option>, <option>addresslist</option>, or <option>localpartlist</option>,
+respectively. Then there follows the name that you are defining, followed by an
+equals sign and the list itself. For example:
+</para>
+<literallayout class="monospaced">
+hostlist relay_from_hosts = 192.168.23.0/24 : my.friend.example
+addresslist bad_senders = cdb;/etc/badsenders
+</literallayout>
+<para>
+A named list may refer to other named lists:
+</para>
+<literallayout class="monospaced">
+domainlist dom1 = first.example : second.example
+domainlist dom2 = +dom1 : third.example
+domainlist dom3 = fourth.example : +dom2 : fifth.example
+</literallayout>
+<para>
+<emphasis role="bold">Warning</emphasis>: If the last item in a referenced list is a negative one, the
+effect may not be what you intended, because the negation does not propagate
+out to the higher level. For example, consider:
+</para>
+<literallayout class="monospaced">
+domainlist dom1 = !a.b
+domainlist dom2 = +dom1 : *.b
+</literallayout>
+<para>
+The second list specifies <quote>either in the <option>dom1</option> list or <emphasis>*.b</emphasis></quote>. The first
+list specifies just <quote>not <emphasis>a.b</emphasis></quote>, so the domain <emphasis>x.y</emphasis> matches it. That
+means it matches the second list as well. The effect is not the same as
+</para>
+<literallayout class="monospaced">
+domainlist dom2 = !a.b : *.b
+</literallayout>
+<para>
+where <emphasis>x.y</emphasis> does not match. It’s best to avoid negation altogether in
+referenced lists if you can.
+</para>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>hiding named list values</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>named lists</primary>
+<secondary>hiding value of</secondary>
+</indexterm>
+Some named list definitions may contain sensitive data, for example, passwords for
+accessing databases. To stop non-admin users from using the <option>-bP</option> command
+line option to read these values, you can precede the definition with the
+word <quote>hide</quote>. For example:
+</para>
+<literallayout class="monospaced" revisionflag="changed">
+hide domainlist filter_for_domains = ldap;PASS=secret ldap::/// ...
+</literallayout>
+<para>
+Named lists may have a performance advantage. When Exim is routing an
+address or checking an incoming message, it caches the result of tests on named
+lists. So, if you have a setting such as
+</para>
+<literallayout class="monospaced">
+domains = +local_domains
+</literallayout>
+<para>
+on several of your routers
+or in several ACL statements,
+the actual test is done only for the first one. However, the caching works only
+if there are no expansions within the list itself or any sublists that it
+references. In other words, caching happens only for lists that are known to be
+the same each time they are referenced.
+</para>
+<para>
+By default, there may be up to 16 named lists of each type. This limit can be
+extended by changing a compile-time variable. The use of domain and host lists
+is recommended for concepts such as local domains, relay domains, and relay
+hosts. The default configuration is set up like this.
+</para>
+</section>
+<section id="SECID78">
+<title>Named lists compared with macros</title>
+<para>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>named compared with macro</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>macro</primary>
+<secondary>compared with named list</secondary>
+</indexterm>
+At first sight, named lists might seem to be no different from macros in the
+configuration file. However, macros are just textual substitutions. If you
+write
+</para>
+<literallayout class="monospaced">
+ALIST = host1 : host2
+auth_advertise_hosts = !ALIST
+</literallayout>
+<para>
+it probably won’t do what you want, because that is exactly the same as
+</para>
+<literallayout class="monospaced">
+auth_advertise_hosts = !host1 : host2
+</literallayout>
+<para>
+Notice that the second host name is not negated. However, if you use a host
+list, and write
+</para>
+<literallayout class="monospaced">
+hostlist alist = host1 : host2
+auth_advertise_hosts = ! +alist
+</literallayout>
+<para>
+the negation applies to the whole list, and so that is equivalent to
+</para>
+<literallayout class="monospaced">
+auth_advertise_hosts = !host1 : !host2
+</literallayout>
+</section>
+<section id="SECID79">
+<title>Named list caching</title>
+<para>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>caching of named</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>caching</primary>
+<secondary>named lists</secondary>
+</indexterm>
+While processing a message, Exim caches the result of checking a named list if
+it is sure that the list is the same each time. In practice, this means that
+the cache operates only if the list contains no $ characters, which guarantees
+that it will not change when it is expanded. Sometimes, however, you may have
+an expanded list that you know will be the same each time within a given
+message. For example:
+</para>
+<literallayout class="monospaced">
+domainlist special_domains = \
+ ${lookup{$sender_host_address}cdb{/some/file}}
+</literallayout>
+<para>
+This provides a list of domains that depends only on the sending host’s IP
+address. If this domain list is referenced a number of times (for example,
+in several ACL lines, or in several routers) the result of the check is not
+cached by default, because Exim does not know that it is going to be the
+same list each time.
+</para>
+<para>
+By appending <literal>_cache</literal> to <literal>domainlist</literal> you can tell Exim to go ahead and
+cache the result anyway. For example:
+</para>
+<literallayout class="monospaced">
+domainlist_cache special_domains = ${lookup{...
+</literallayout>
+<para>
+If you do this, you should be absolutely sure that caching is going to do
+the right thing in all cases. When in doubt, leave it out.
+</para>
+</section>
+<section id="SECTdomainlist">
+<title>Domain lists</title>
+<para>
+<indexterm role="concept">
+<primary>domain list</primary>
+<secondary>patterns for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>domain list</secondary>
+</indexterm>
+Domain lists contain patterns that are to be matched against a mail domain.
+The following types of item may appear in domain lists:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>primary host name</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>host name</primary>
+<secondary>matched in domain list</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>primary_hostname</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain list</primary>
+<secondary>matching primary host name</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>@ in a domain list</primary>
+</indexterm>
+If a pattern consists of a single @ character, it matches the local host name,
+as set by the <option>primary_hostname</option> option (or defaulted). This makes it
+possible to use the same configuration file on several different hosts that
+differ only in their names.
+</para>
+<para revisionflag="changed">
+The value for a match will be the primary host name.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>@[] in a domain list</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain list</primary>
+<secondary>matching local IP interfaces</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain literal</primary>
+</indexterm>
+If a pattern consists of the string <literal>@[]</literal> it matches an IP address enclosed
+in square brackets (as in an email address that contains a domain literal), but
+only if that IP address is recognized as local for email routing purposes. The
+<option>local_interfaces</option> and <option>extra_local_interfaces</option> options can be used to
+control which of a host’s several IP addresses are treated as local.
+In today’s Internet, the use of domain literals is controversial;
+see the <option>allow_domain_literals</option> main option.
+</para>
+<para revisionflag="changed">
+The value for a match will be the string <literal>@[]</literal>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>@mx_any</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>@mx_primary</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>@mx_secondary</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain list</primary>
+<secondary>matching MX pointers to local host</secondary>
+</indexterm>
+If a pattern consists of the string <literal>@mx_any</literal> it matches any domain that
+has an MX record pointing to the local host or to any host that is listed in
+<indexterm role="option">
+<primary><option>hosts_treat_as_local</option></primary>
+</indexterm>
+<option>hosts_treat_as_local</option>. The items <literal>@mx_primary</literal> and <literal>@mx_secondary</literal>
+are similar, except that the first matches only when a primary MX target is the
+local host, and the second only when no primary MX target is the local host,
+but a secondary MX target is. <quote>Primary</quote> means an MX record with the lowest
+preference value – there may of course be more than one of them.
+</para>
+<para>
+The MX lookup that takes place when matching a pattern of this type is
+performed with the resolver options for widening names turned off. Thus, for
+example, a single-component domain will <emphasis>not</emphasis> be expanded by adding the
+resolver’s default domain. See the <option>qualify_single</option> and <option>search_parents</option>
+options of the <command>dnslookup</command> router for a discussion of domain widening.
+</para>
+<para>
+Sometimes you may want to ignore certain IP addresses when using one of these
+patterns. You can specify this by following the pattern with <literal>/ignore=</literal><<emphasis>ip
+list</emphasis>>, where <<emphasis>ip list</emphasis>> is a list of IP addresses. These addresses are
+ignored when processing the pattern (compare the <option>ignore_target_hosts</option> option
+on a router). For example:
+</para>
+<literallayout class="monospaced">
+domains = @mx_any/ignore=127.0.0.1
+</literallayout>
+<para>
+This example matches any domain that has an MX record pointing to one of
+the local host’s IP addresses other than 127.0.0.1.
+</para>
+<para>
+The list of IP addresses is in fact processed by the same code that processes
+host lists, so it may contain CIDR-coded network specifications and it may also
+contain negative items.
+</para>
+<para>
+Because the list of IP addresses is a sublist within a domain list, you have to
+be careful about delimiters if there is more than one address. Like any other
+list, the default delimiter can be changed. Thus, you might have:
+</para>
+<literallayout class="monospaced">
+domains = @mx_any/ignore=<;127.0.0.1;0.0.0.0 : \
+ an.other.domain : ...
+</literallayout>
+<para>
+so that the sublist uses semicolons for delimiters. When IPv6 addresses are
+involved, it is easiest to change the delimiter for the main list as well:
+</para>
+<literallayout class="monospaced">
+domains = <? @mx_any/ignore=<;127.0.0.1;::1 ? \
+ an.other.domain ? ...
+</literallayout>
+<para revisionflag="changed">
+The value for a match will be the list element string (starting <literal>@mx_</literal>).
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>asterisk</primary>
+<secondary>in domain list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain list</primary>
+<secondary>asterisk in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain list</primary>
+<secondary>matching <quote>ends with</quote></secondary>
+</indexterm>
+If a pattern starts with an asterisk, the remaining characters of the pattern
+are compared with the terminating characters of the domain. The use of <quote>*</quote> in
+domain lists differs from its use in partial matching lookups. In a domain
+list, the character following the asterisk need not be a dot, whereas partial
+matching works only in terms of dot-separated components. For example, a domain
+list item such as <literal>*key.ex</literal> matches <emphasis>donkey.ex</emphasis> as well as
+<emphasis>cipher.key.ex</emphasis>.
+</para>
+<para revisionflag="changed">
+The value for a match will be the list element string (starting with the asterisk).
+Additionally, <varname>$0</varname> will be set to the matched string
+and <varname>$1</varname> to the variable portion which the asterisk matched.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>regular expressions</primary>
+<secondary>in domain list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain list</primary>
+<secondary>matching regular expression</secondary>
+</indexterm>
+If a pattern starts with a circumflex character, it is treated as a regular
+expression, and matched against the domain using a regular expression matching
+function. The circumflex is treated as part of the regular expression.
+Email domains are case-independent, so this regular expression match is by
+default case-independent, but you can make it case-dependent by starting it
+with <literal>(?-i)</literal>. References to descriptions of the syntax of regular expressions
+are given in chapter <xref linkend="CHAPregexp"/>.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: Because domain lists are expanded before being processed, you
+must escape any backslash and dollar characters in the regular expression, or
+use the special <literal>\N</literal> sequence (see chapter <xref linkend="CHAPexpand"/>) to specify that
+it is not to be expanded (unless you really do want to build a regular
+expression by expansion, of course).
+</para>
+<para revisionflag="changed">
+The value for a match will be the list element string (starting with the circumflex).
+Additionally, <varname>$0</varname> will be set to the string matching the regular expression,
+and <varname>$1</varname> (onwards) to any submatches identified by parentheses.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>in domain list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain list</primary>
+<secondary>matching by lookup</secondary>
+</indexterm>
+If a pattern starts with the name of a single-key lookup type followed by a
+semicolon (for example, <quote>dbm;</quote> or <quote>lsearch;</quote>), the remainder of the pattern
+must be a filename in a suitable format for the lookup type. For example, for
+<quote>cdb;</quote> it must be an absolute path:
+</para>
+<literallayout class="monospaced">
+domains = cdb;/etc/mail/local_domains.cdb
+</literallayout>
+<para>
+The appropriate type of lookup is done on the file using the domain name as the
+key. In most cases, the value resulting from the lookup is not used; Exim is interested
+only in whether or not the key is present in the file. However, when a lookup
+is used for the <option>domains</option> option on a router
+or a <option>domains</option> condition in an ACL statement, the value is preserved in the
+<varname>$domain_data</varname> variable and can be referred to in other router options or
+other statements in the same ACL.
+<indexterm role="concept">
+<primary>tainted data</primary>
+<secondary>de-tainting</secondary>
+</indexterm>
+The value will be untainted.
+</para>
+</listitem>
+<listitem>
+<para>
+Any of the single-key lookup type names may be preceded by
+<literal>partial</literal><<emphasis>n</emphasis>><literal>-</literal>, where the <<emphasis>n</emphasis>> is optional, for example,
+</para>
+<literallayout class="monospaced">
+domains = partial-dbm;/partial/domains
+</literallayout>
+<para>
+This causes partial matching logic to be invoked; a description of how this
+works is given in section <xref linkend="SECTpartiallookup"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>asterisk</primary>
+<secondary>in lookup type</secondary>
+</indexterm>
+Any of the single-key lookup types may be followed by an asterisk. This causes
+a default lookup for a key consisting of a single asterisk to be done if the
+original lookup fails. This is not a useful feature when using a domain list to
+select particular domains (because any domain would match), but it might have
+value if the result of the lookup is being used via the <varname>$domain_data</varname>
+expansion variable.
+</para>
+</listitem>
+<listitem>
+<para>
+If the pattern starts with the name of a query-style lookup type followed by a
+semicolon (for example, <quote>nisplus;</quote> or <quote>ldap;</quote>), the remainder of the
+pattern must be an appropriate query for the lookup type, as described in
+chapter <xref linkend="CHAPfdlookup"/>. For example:
+</para>
+<literallayout class="monospaced">
+hold_domains = mysql;select domain from holdlist \
+ where domain = '${quote_mysql:$domain}';
+</literallayout>
+<para>
+In most cases, the value resulting from the lookup is not used (so for an SQL query, for
+example, it doesn’t matter what field you select). Exim is interested only in
+whether or not the query succeeds. However, when a lookup is used for the
+<option>domains</option> option on a router, the value is preserved in the <varname>$domain_data</varname>
+variable and can be referred to in other options.
+<indexterm role="concept">
+<primary>tainted data</primary>
+<secondary>de-tainting</secondary>
+</indexterm>
+The value will be untainted.
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+If the pattern starts with the name of a lookup type
+of either kind (single-key or query-style) it may be
+followed by a comma and options,
+The options are lookup-type specific and consist of a comma-separated list.
+Each item starts with a tag and and equals "=".
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>domain list</primary>
+<secondary>matching literal domain name</secondary>
+</indexterm>
+If none of the above cases apply, a caseless textual comparison is made
+between the pattern and the domain.
+</para>
+<para>
+The value for a match will be the list element string.
+<indexterm role="concept">
+<primary>tainted data</primary>
+<secondary>de-tainting</secondary>
+</indexterm>
+Note that this is commonly untainted
+(depending on the way the list was created).
+This is a useful way of obtaining an untainted equivalent to
+the domain, for later operations.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Here is an example that uses several different kinds of pattern:
+</para>
+<literallayout class="monospaced">
+domainlist funny_domains = \
+ @ : \
+ lib.unseen.edu : \
+ *.foundation.fict.example : \
+ \N^[1-2]\d{3}\.fict\.example$\N : \
+ partial-dbm;/opt/data/penguin/book : \
+ nis;domains.byname : \
+ nisplus;[name=$domain,status=local],domains.org_dir
+</literallayout>
+<para>
+There are obvious processing trade-offs among the various matching modes. Using
+an asterisk is faster than a regular expression, and listing a few names
+explicitly probably is too. The use of a file or database lookup is expensive,
+but may be the only option if hundreds of names are required. Because the
+patterns are tested in order, it makes sense to put the most commonly matched
+patterns earlier.
+</para>
+</section>
+<section id="SECThostlist">
+<title>Host lists</title>
+<para>
+<indexterm role="concept">
+<primary>host list</primary>
+<secondary>patterns in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>host list</secondary>
+</indexterm>
+Host lists are used to control what remote hosts are allowed to do. For
+example, some hosts may be allowed to use the local host as a relay, and some
+may be permitted to use the SMTP ETRN command. Hosts can be identified in
+two different ways, by name or by IP address. In a host list, some types of
+pattern are matched to a host name, and some are matched to an IP address.
+You need to be particularly careful with this when single-key lookups are
+involved, to ensure that the right value is being used as the key.
+</para>
+</section>
+<section id="SECID80">
+<title>Special host list patterns</title>
+<para>
+<indexterm role="concept">
+<primary>empty item in hosts list</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>host list</primary>
+<secondary>empty string in</secondary>
+</indexterm>
+If a host list item is the empty string, it matches only when no remote host is
+involved. This is the case when a message is being received from a local
+process using SMTP on the standard input, that is, when a TCP/IP connection is
+not used.
+</para>
+<para>
+<indexterm role="concept">
+<primary>asterisk</primary>
+<secondary>in host list</secondary>
+</indexterm>
+The special pattern <quote>*</quote> in a host list matches any host or no host. Neither
+the IP address nor the name is actually inspected.
+</para>
+</section>
+<section id="SECThoslispatip">
+<title>Host list patterns that match by IP address</title>
+<para>
+<indexterm role="concept">
+<primary>host list</primary>
+<secondary>matching IP addresses</secondary>
+</indexterm>
+If an IPv4 host calls an IPv6 host and the call is accepted on an IPv6 socket,
+the incoming address actually appears in the IPv6 host as
+<literal>::ffff:</literal><<emphasis>v4address</emphasis>>. When such an address is tested against a host
+list, it is converted into a traditional IPv4 address first. (Not all operating
+systems accept IPv4 calls on IPv6 sockets, as there have been some security
+concerns.)
+</para>
+<para>
+The following types of pattern in a host list check the remote host by
+inspecting its IP address:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If the pattern is a plain domain name (not a regular expression, not starting
+with *, not a lookup of any kind), Exim calls the operating system function
+to find the associated IP address(es). Exim uses the newer
+<function>getipnodebyname()</function> function when available, otherwise <function>gethostbyname()</function>.
+This typically causes a forward DNS lookup of the name. The result is compared
+with the IP address of the subject host.
+</para>
+<para>
+If there is a temporary problem (such as a DNS timeout) with the host name
+lookup, a temporary error occurs. For example, if the list is being used in an
+ACL condition, the ACL gives a <quote>defer</quote> response, usually leading to a
+temporary SMTP error code. If no IP address can be found for the host name,
+what happens is described in section <xref linkend="SECTbehipnot"/> below.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>@ in a host list</primary>
+</indexterm>
+If the pattern is <quote>@</quote>, the primary host name is substituted and used as a
+domain name, as just described.
+</para>
+</listitem>
+<listitem>
+<para>
+If the pattern is an IP address, it is matched against the IP address of the
+subject host. IPv4 addresses are given in the normal <quote>dotted-quad</quote> notation.
+IPv6 addresses can be given in colon-separated format, but the colons have to
+be doubled so as not to be taken as item separators when the default list
+separator is used. IPv6 addresses are recognized even when Exim is compiled
+without IPv6 support. This means that if they appear in a host list on an
+IPv4-only host, Exim will not treat them as host names. They are just addresses
+that can never match a client host.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>@[] in a host list</primary>
+</indexterm>
+If the pattern is <quote>@[]</quote>, it matches the IP address of any IP interface on
+the local host. For example, if the local host is an IPv4 host with one
+interface address 10.45.23.56, these two ACL statements have the same effect:
+</para>
+<literallayout class="monospaced">
+accept hosts = 127.0.0.1 : 10.45.23.56
+accept hosts = @[]
+</literallayout>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>CIDR notation</primary>
+</indexterm>
+If the pattern is an IP address followed by a slash and a mask length (for
+example 10.11.42.0/24), it is matched against the IP address of the subject
+host under the given mask. This allows, an entire network of hosts to be
+included (or excluded) by a single item. The mask uses CIDR notation; it
+specifies the number of address bits that must match, starting from the most
+significant end of the address.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: The mask is <emphasis>not</emphasis> a count of addresses, nor is it the high number
+of a range of addresses. It is the number of bits in the network portion of the
+address. The above example specifies a 24-bit netmask, so it matches all 256
+addresses in the 10.11.42.0 network. An item such as
+</para>
+<literallayout class="monospaced">
+192.168.23.236/31
+</literallayout>
+<para>
+matches just two addresses, 192.168.23.236 and 192.168.23.237. A mask value of
+32 for an IPv4 address is the same as no mask at all; just a single address
+matches.
+</para>
+<para>
+Here is another example which shows an IPv4 and an IPv6 network:
+</para>
+<literallayout class="monospaced">
+recipient_unqualified_hosts = 192.168.0.0/16: \
+ 3ffe::ffff::836f::::/48
+</literallayout>
+<para>
+The doubling of list separator characters applies only when these items
+appear inline in a host list. It is not required when indirecting via a file.
+For example:
+</para>
+<literallayout class="monospaced">
+recipient_unqualified_hosts = /opt/exim/unqualnets
+</literallayout>
+<para>
+could make use of a file containing
+</para>
+<literallayout class="monospaced">
+172.16.0.0/12
+3ffe:ffff:836f::/48
+</literallayout>
+<para>
+to have exactly the same effect as the previous example. When listing IPv6
+addresses inline, it is usually more convenient to use the facility for
+changing separator characters. This list contains the same two networks:
+</para>
+<literallayout class="monospaced">
+recipient_unqualified_hosts = <; 172.16.0.0/12; \
+ 3ffe:ffff:836f::/48
+</literallayout>
+<para>
+The separator is changed to semicolon by the leading <quote><;</quote> at the start of the
+list.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECThoslispatsikey">
+<title>Host list patterns for single-key lookups by host address</title>
+<para>
+<indexterm role="concept">
+<primary>host list</primary>
+<secondary>lookup of IP address</secondary>
+</indexterm>
+When a host is to be identified by a single-key lookup of its complete IP
+address, the pattern takes this form:
+</para>
+<literallayout>
+<literal>net-<</literal><emphasis>single-key-search-type</emphasis><literal>>;<</literal><emphasis>search-data</emphasis><literal>></literal>
+</literallayout>
+<para>
+For example:
+</para>
+<literallayout class="monospaced">
+hosts_lookup = net-cdb;/hosts-by-ip.db
+</literallayout>
+<para>
+The text form of the IP address of the subject host is used as the lookup key.
+IPv6 addresses are converted to an unabbreviated form, using lower case
+letters, with dots as separators because colon is the key terminator in
+<command>lsearch</command> files. [Colons can in fact be used in keys in <command>lsearch</command> files by
+quoting the keys, but this is a facility that was added later.] The data
+returned by the lookup is not used.
+</para>
+<para>
+<indexterm role="concept">
+<primary>IP address</primary>
+<secondary>masking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>host list</primary>
+<secondary>masked IP address</secondary>
+</indexterm>
+Single-key lookups can also be performed using masked IP addresses, using
+patterns of this form:
+</para>
+<literallayout>
+<literal>net<</literal><emphasis>number</emphasis><literal>>-<</literal><emphasis>single-key-search-type</emphasis><literal>>;<</literal><emphasis>search-data</emphasis><literal>></literal>
+</literallayout>
+<para>
+For example:
+</para>
+<literallayout class="monospaced">
+net24-dbm;/networks.db
+</literallayout>
+<para>
+The IP address of the subject host is masked using <<emphasis>number</emphasis>> as the mask
+length. A textual string is constructed from the masked value, followed by the
+mask, and this is used as the lookup key. For example, if the host’s IP address
+is 192.168.34.6, the key that is looked up for the above example is
+<quote>192.168.34.0/24</quote>.
+</para>
+<para>
+When an IPv6 address is converted to a string, dots are normally used instead
+of colons, so that keys in <command>lsearch</command> files need not contain colons (which
+terminate <command>lsearch</command> keys). This was implemented some time before the ability
+to quote keys was made available in <command>lsearch</command> files. However, the more
+recently implemented <command>iplsearch</command> files do require colons in IPv6 keys
+(notated using the quoting facility) so as to distinguish them from IPv4 keys.
+For this reason, when the lookup type is <command>iplsearch</command>, IPv6 addresses are
+converted using colons and not dots.
+In all cases except IPv4-mapped IPv6, full, unabbreviated IPv6
+addresses are always used.
+The latter are converted to IPv4 addresses, in dotted-quad form.
+</para>
+<para>
+Ideally, it would be nice to tidy up this anomalous situation by changing to
+colons in all cases, given that quoting is now available for <command>lsearch</command>.
+However, this would be an incompatible change that might break some existing
+configurations.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: Specifying <option>net32-</option> (for an IPv4 address) or <option>net128-</option> (for an
+IPv6 address) is not the same as specifying just <option>net-</option> without a number. In
+the former case the key strings include the mask value, whereas in the latter
+case the IP address is used on its own.
+</para>
+</section>
+<section id="SECThoslispatnam">
+<title>Host list patterns that match by host name</title>
+<para>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>lookup failures</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>unknown host name</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>host list</primary>
+<secondary>matching host name</secondary>
+</indexterm>
+There are several types of pattern that require Exim to know the name of the
+remote host. These are either wildcard patterns or lookups by name. (If a
+complete hostname is given without any wildcarding, it is used to find an IP
+address to match against, as described in section <xref linkend="SECThoslispatip"/>
+above.)
+</para>
+<para>
+If the remote host name is not already known when Exim encounters one of these
+patterns, it has to be found from the IP address.
+Although many sites on the Internet are conscientious about maintaining reverse
+DNS data for their hosts, there are also many that do not do this.
+Consequently, a name cannot always be found, and this may lead to unwanted
+effects. Take care when configuring host lists with wildcarded name patterns.
+Consider what will happen if a name cannot be found.
+</para>
+<para>
+Because of the problems of determining host names from IP addresses, matching
+against host names is not as common as matching against IP addresses.
+</para>
+<para>
+By default, in order to find a host name, Exim first does a reverse DNS lookup;
+if no name is found in the DNS, the system function (<function>gethostbyaddr()</function> or
+<function>getipnodebyaddr()</function> if available) is tried. The order in which these lookups
+are done can be changed by setting the <option>host_lookup_order</option> option. For
+security, once Exim has found one or more names, it looks up the IP addresses
+for these names and compares them with the IP address that it started with.
+Only those names whose IP addresses match are accepted. Any other names are
+discarded. If no names are left, Exim behaves as if the host name cannot be
+found. In the most common case there is only one name and one IP address.
+</para>
+<para>
+There are some options that control what happens if a host name cannot be
+found. These are described in section <xref linkend="SECTbehipnot"/> below.
+</para>
+<para>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>alias for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>alias for host</primary>
+</indexterm>
+As a result of aliasing, hosts may have more than one name. When processing any
+of the following types of pattern, all the host’s names are checked:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>asterisk</primary>
+<secondary>in host list</secondary>
+</indexterm>
+If a pattern starts with <quote>*</quote> the remainder of the item must match the end of
+the host name. For example, <literal>*.b.c</literal> matches all hosts whose names end in
+<emphasis>.b.c</emphasis>. This special simple form is provided because this is a very common
+requirement. Other kinds of wildcarding require the use of a regular
+expression.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>regular expressions</primary>
+<secondary>in host list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>host list</primary>
+<secondary>regular expression in</secondary>
+</indexterm>
+If the item starts with <quote>^</quote> it is taken to be a regular expression which is
+matched against the host name. Host names are case-independent, so this regular
+expression match is by default case-independent, but you can make it
+case-dependent by starting it with <literal>(?-i)</literal>. References to descriptions of the
+syntax of regular expressions are given in chapter <xref linkend="CHAPregexp"/>. For
+example,
+</para>
+<literallayout class="monospaced">
+^(a|b)\.c\.d$
+</literallayout>
+<para>
+is a regular expression that matches either of the two hosts <emphasis>a.c.d</emphasis> or
+<emphasis>b.c.d</emphasis>. When a regular expression is used in a host list, you must take care
+that backslash and dollar characters are not misinterpreted as part of the
+string expansion. The simplest way to do this is to use <literal>\N</literal> to mark that
+part of the string as non-expandable. For example:
+</para>
+<literallayout class="monospaced">
+sender_unqualified_hosts = \N^(a|b)\.c\.d$\N : ....
+</literallayout>
+<para>
+<emphasis role="bold">Warning</emphasis>: If you want to match a complete host name, you must include the
+<literal>$</literal> terminating metacharacter in the regular expression, as in the above
+example. Without it, a match at the start of the host name is all that is
+required.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECTbehipnot">
+<title>Behaviour when an IP address or name cannot be found</title>
+<para>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>lookup failures, permanent</secondary>
+</indexterm>
+While processing a host list, Exim may need to look up an IP address from a
+name (see section <xref linkend="SECThoslispatip"/>), or it may need to look up a host name
+from an IP address (see section <xref linkend="SECThoslispatnam"/>). In either case, the
+behaviour when it fails to find the information it is seeking is the same.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: This section applies to permanent lookup failures. It does <emphasis>not</emphasis>
+apply to temporary DNS errors, whose handling is described in the next section.
+</para>
+<para>
+<indexterm role="concept">
+<primary><literal>+include_unknown</literal></primary>
+</indexterm>
+<indexterm role="concept">
+<primary><literal>+ignore_unknown</literal></primary>
+</indexterm>
+Exim parses a host list from left to right. If it encounters a permanent
+lookup failure in any item in the host list before it has found a match,
+Exim treats it as a failure and the default behavior is as if the host
+does not match the list. This may not always be what you want to happen.
+To change Exim’s behaviour, the special items <literal>+include_unknown</literal> or
+<literal>+ignore_unknown</literal> may appear in the list (at top level – they are
+not recognized in an indirected file).
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If any item that follows <literal>+include_unknown</literal> requires information that
+cannot found, Exim behaves as if the host does match the list. For example,
+</para>
+<literallayout class="monospaced">
+host_reject_connection = +include_unknown:*.enemy.ex
+</literallayout>
+<para>
+rejects connections from any host whose name matches <literal>*.enemy.ex</literal>, and also
+any hosts whose name it cannot find.
+</para>
+</listitem>
+<listitem>
+<para>
+If any item that follows <literal>+ignore_unknown</literal> requires information that cannot
+be found, Exim ignores that item and proceeds to the rest of the list. For
+example:
+</para>
+<literallayout class="monospaced">
+accept hosts = +ignore_unknown : friend.example : \
+ 192.168.4.5
+</literallayout>
+<para>
+accepts from any host whose name is <emphasis>friend.example</emphasis> and from 192.168.4.5,
+whether or not its host name can be found. Without <literal>+ignore_unknown</literal>, if no
+name can be found for 192.168.4.5, it is rejected.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Both <literal>+include_unknown</literal> and <literal>+ignore_unknown</literal> may appear in the same
+list. The effect of each one lasts until the next, or until the end of the
+list.
+</para>
+</section>
+<section id="SECTmixwilhos">
+<title>Mixing wildcarded host names and addresses in host lists</title>
+<para>
+<indexterm role="concept">
+<primary>host list</primary>
+<secondary>mixing names and addresses in</secondary>
+</indexterm>
+</para>
+<para>
+This section explains the host/ip processing logic with the same concepts
+as the previous section, but specifically addresses what happens when a
+wildcarded hostname is one of the items in the hostlist.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+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, in an ACL you could have:
+</para>
+<literallayout class="monospaced">
+accept hosts = 10.9.8.7 : *.friend.example
+</literallayout>
+<para>
+The reason you normally would order it this way 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
+<option>accept</option> statement fails for a host whose name cannot be found, even
+if its IP address is 10.9.8.7.
+</para>
+</listitem>
+<listitem>
+<para>
+If you really do want to do the name check first, and still recognize the IP
+address, you can rewrite the ACL like this:
+</para>
+<literallayout class="monospaced">
+accept hosts = *.friend.example
+accept hosts = 10.9.8.7
+</literallayout>
+<para>
+If the first <option>accept</option> fails, Exim goes on to try the second one. See chapter
+<xref linkend="CHAPACL"/> for details of ACLs. Alternatively, you can use
+<literal>+ignore_unknown</literal>, which was discussed in depth in the first example in
+this section.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECTtemdnserr">
+<title>Temporary DNS errors when looking up host information</title>
+<para>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>lookup failures, temporary</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><literal>+include_defer</literal></primary>
+</indexterm>
+<indexterm role="concept">
+<primary><literal>+ignore_defer</literal></primary>
+</indexterm>
+A temporary DNS lookup failure normally causes a defer action (except when
+<option>dns_again_means_nonexist</option> converts it into a permanent error). However,
+host lists can include <literal>+ignore_defer</literal> and <literal>+include_defer</literal>, analogous to
+<literal>+ignore_unknown</literal> and <literal>+include_unknown</literal>, as described in the previous
+section. These options should be used with care, probably only in non-critical
+host lists such as whitelists.
+</para>
+</section>
+<section id="SECThoslispatnamsk">
+<title>Host list patterns for single-key lookups by host name</title>
+<para>
+<indexterm role="concept">
+<primary>unknown host name</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>host list</primary>
+<secondary>matching host name</secondary>
+</indexterm>
+If a pattern is of the form
+</para>
+<literallayout>
+<<emphasis>single-key-search-type</emphasis>>;<<emphasis>search-data</emphasis>>
+</literallayout>
+<para>
+for example
+</para>
+<literallayout class="monospaced">
+dbm;/host/accept/list
+</literallayout>
+<para>
+a single-key lookup is performed, using the host name as its key. If the
+lookup succeeds, the host matches the item. The actual data that is looked up
+is not used.
+</para>
+<para>
+<emphasis role="bold">Reminder</emphasis>: With this kind of pattern, you must have host <emphasis>names</emphasis> as
+keys in the file, not IP addresses. If you want to do lookups based on IP
+addresses, you must precede the search type with <quote>net-</quote> (see section
+<xref linkend="SECThoslispatsikey"/>). There is, however, no reason why you could not use
+two items in the same list, one doing an address lookup and one doing a name
+lookup, both using the same file.
+</para>
+</section>
+<section id="SECID81">
+<title>Host list patterns for query-style lookups</title>
+<para>
+If a pattern is of the form
+</para>
+<literallayout>
+<<emphasis>query-style-search-type</emphasis>>;<<emphasis>query</emphasis>>
+</literallayout>
+<para>
+the query is obeyed, and if it succeeds, the host matches the item. The actual
+data that is looked up is not used. The variables <varname>$sender_host_address</varname> and
+<varname>$sender_host_name</varname> can be used in the query. For example:
+</para>
+<literallayout class="monospaced">
+hosts_lookup = pgsql;\
+ select ip from hostlist where ip='$sender_host_address'
+</literallayout>
+<para>
+The value of <varname>$sender_host_address</varname> for an IPv6 address contains colons. You
+can use the <option>sg</option> expansion item to change this if you need to. If you want to
+use masked IP addresses in database queries, you can use the <option>mask</option> expansion
+operator.
+</para>
+<para>
+If the query contains a reference to <varname>$sender_host_name</varname>, Exim automatically
+looks up the host name if it has not already done so. (See section
+<xref linkend="SECThoslispatnam"/> for comments on finding host names.)
+</para>
+<para>
+Historical note: prior to release 4.30, Exim would always attempt to find a
+host name before running the query, unless the search type was preceded by
+<literal>net-</literal>. This is no longer the case. For backwards compatibility, <literal>net-</literal> is
+still recognized for query-style lookups, but its presence or absence has no
+effect. (Of course, for single-key lookups, <literal>net-</literal> <emphasis>is</emphasis> important.
+See section <xref linkend="SECThoslispatsikey"/>.)
+</para>
+</section>
+<section id="SECTaddresslist">
+<title>Address lists</title>
+<para>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>address list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address list</primary>
+<secondary>empty item</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address list</primary>
+<secondary>patterns</secondary>
+</indexterm>
+Address lists contain patterns that are matched against mail addresses. There
+is one special case to be considered: the sender address of a bounce message is
+always empty. You can test for this by providing an empty item in an address
+list. For example, you can set up a router to process bounce messages by
+using this option setting:
+</para>
+<literallayout class="monospaced">
+senders = :
+</literallayout>
+<para>
+The presence of the colon creates an empty item. If you do not provide any
+data, the list is empty and matches nothing. The empty sender can also be
+detected by a regular expression that matches an empty string,
+and by a query-style lookup that succeeds when <varname>$sender_address</varname> is empty.
+</para>
+<para>
+Non-empty items in an address list can be straightforward email addresses. For
+example:
+</para>
+<literallayout class="monospaced">
+senders = jbc@askone.example : hs@anacreon.example
+</literallayout>
+<para>
+A certain amount of wildcarding is permitted. If a pattern contains an @
+character, but is not a regular expression and does not begin with a
+semicolon-terminated lookup type (described below), the local part of the
+subject address is compared with the local part of the pattern, which may start
+with an asterisk. If the local parts match, the domain is checked in exactly
+the same way as for a pattern in a domain list. For example, the domain can be
+wildcarded, refer to a named list, or be a lookup:
+</para>
+<literallayout class="monospaced">
+deny senders = *@*.spamming.site:\
+ *@+hostile_domains:\
+ bozo@partial-lsearch;/list/of/dodgy/sites:\
+ *@dbm;/bad/domains.db
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>starting with !</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address list</primary>
+<secondary>local part starting with !</secondary>
+</indexterm>
+If a local part that begins with an exclamation mark is required, it has to be
+specified using a regular expression, because otherwise the exclamation mark is
+treated as a sign of negation, as is standard in lists.
+</para>
+<para>
+If a non-empty pattern that is not a regular expression or a lookup does not
+contain an @ character, it is matched against the domain part of the subject
+address. The only two formats that are recognized this way are a literal
+domain, or a domain pattern that starts with *. In both these cases, the effect
+is the same as if <literal>*@</literal> preceded the pattern. For example:
+</para>
+<literallayout class="monospaced">
+deny senders = enemy.domain : *.enemy.domain
+</literallayout>
+<para>
+The following kinds of more complicated address list pattern can match any
+address, including the empty address that is characteristic of bounce message
+senders:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>regular expressions</primary>
+<secondary>in address list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address list</primary>
+<secondary>regular expression in</secondary>
+</indexterm>
+If (after expansion) a pattern starts with <quote>^</quote>, a regular expression match is
+done against the complete address, with the pattern as the regular expression.
+You must take care that backslash and dollar characters are not misinterpreted
+as part of the string expansion. The simplest way to do this is to use <literal>\N</literal>
+to mark that part of the string as non-expandable. For example:
+</para>
+<literallayout class="monospaced">
+deny senders = \N^.*this.*@example\.com$\N : \
+ \N^\d{8}.+@spamhaus.example$\N : ...
+</literallayout>
+<para>
+The <literal>\N</literal> sequences are removed by the expansion, so these items do indeed
+start with <quote>^</quote> by the time they are being interpreted as address patterns.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>address list</primary>
+<secondary>lookup for complete address</secondary>
+</indexterm>
+Complete addresses can be looked up by using a pattern that starts with a
+lookup type terminated by a semicolon, followed by the data for the lookup. For
+example:
+</para>
+<literallayout class="monospaced">
+deny senders = cdb;/etc/blocked.senders : \
+ mysql;select address from blocked where \
+ address='${quote_mysql:$sender_address}'
+</literallayout>
+<para>
+Both query-style and single-key lookup types can be used. For a single-key
+lookup type, Exim uses the complete address as the key. However, empty keys are
+not supported for single-key lookups, so a match against the empty address
+always fails. This restriction does not apply to query-style lookups.
+</para>
+<para>
+Partial matching for single-key lookups (section <xref linkend="SECTpartiallookup"/>)
+cannot be used, and is ignored if specified, with an entry being written to the
+panic log.
+<indexterm role="concept">
+<primary>*@ with single-key lookup</primary>
+</indexterm>
+However, you can configure lookup defaults, as described in section
+<xref linkend="SECTdefaultvaluelookups"/>, but this is useful only for the <quote>*@</quote> type of
+default. For example, with this lookup:
+</para>
+<literallayout class="monospaced">
+accept senders = lsearch*@;/some/file
+</literallayout>
+<para>
+the file could contains lines like this:
+</para>
+<literallayout class="monospaced">
+user1@domain1.example
+*@domain2.example
+</literallayout>
+<para>
+and for the sender address <emphasis>nimrod@jaeger.example</emphasis>, the sequence of keys
+that are tried is:
+</para>
+<literallayout class="monospaced">
+nimrod@jaeger.example
+*@jaeger.example
+*
+</literallayout>
+<para>
+<emphasis role="bold">Warning 1</emphasis>: Do not include a line keyed by <quote>*</quote> in the file, because that
+would mean that every address matches, thus rendering the test useless.
+</para>
+<para>
+<emphasis role="bold">Warning 2</emphasis>: Do not confuse these two kinds of item:
+</para>
+<literallayout class="monospaced">
+deny recipients = dbm*@;/some/file
+deny recipients = *@dbm;/some/file
+</literallayout>
+<para>
+The first does a whole address lookup, with defaulting, as just described,
+because it starts with a lookup type. The second matches the local part and
+domain independently, as described in a bullet point below.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The following kinds of address list pattern can match only non-empty addresses.
+If the subject address is empty, a match against any of these pattern types
+always fails.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>@@ with single-key lookup</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>address list</primary>
+<secondary>@@ lookup type</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address list</primary>
+<secondary>split local part and domain</secondary>
+</indexterm>
+If a pattern starts with <quote>@@</quote> followed by a single-key lookup item
+(for example, <literal>@@lsearch;/some/file</literal>), the address that is being checked is
+split into a local part and a domain. The domain is looked up in the file. If
+it is not found, there is no match. If it is found, the data that is looked up
+from the file is treated as a colon-separated list of local part patterns, each
+of which is matched against the subject local part in turn.
+</para>
+<para>
+<indexterm role="concept">
+<primary>asterisk</primary>
+<secondary>in address list</secondary>
+</indexterm>
+The lookup may be a partial one, and/or one involving a search for a default
+keyed by <quote>*</quote> (see section <xref linkend="SECTdefaultvaluelookups"/>). The local part
+patterns that are looked up can be regular expressions or begin with <quote>*</quote>, or
+even be further lookups. They may also be independently negated. For example,
+with
+</para>
+<literallayout class="monospaced">
+deny senders = @@dbm;/etc/reject-by-domain
+</literallayout>
+<para>
+the data from which the DBM file is built could contain lines like
+</para>
+<literallayout class="monospaced">
+baddomain.com: !postmaster : *
+</literallayout>
+<para>
+to reject all senders except <option>postmaster</option> from that domain.
+</para>
+<para>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>starting with !</secondary>
+</indexterm>
+If a local part that actually begins with an exclamation mark is required, it
+has to be specified using a regular expression. In <command>lsearch</command> files, an entry
+may be split over several lines by indenting the second and subsequent lines,
+but the separating colon must still be included at line breaks. White space
+surrounding the colons is ignored. For example:
+</para>
+<literallayout class="monospaced">
+aol.com: spammer1 : spammer2 : ^[0-9]+$ :
+ spammer3 : spammer4
+</literallayout>
+<para>
+As in all colon-separated lists in Exim, a colon can be included in an item by
+doubling.
+</para>
+<para>
+If the last item in the list starts with a right angle-bracket, the remainder
+of the item is taken as a new key to look up in order to obtain a continuation
+list of local parts. The new key can be any sequence of characters. Thus one
+might have entries like
+</para>
+<literallayout class="monospaced">
+aol.com: spammer1 : spammer 2 : >*
+xyz.com: spammer3 : >*
+*: ^\d{8}$
+</literallayout>
+<para>
+in a file that was searched with <option>@@dbm*</option>, to specify a match for 8-digit
+local parts for all domains, in addition to the specific local parts listed for
+each domain. Of course, using this feature costs another lookup each time a
+chain is followed, but the effort needed to maintain the data is reduced.
+</para>
+<para>
+<indexterm role="concept">
+<primary>loop</primary>
+<secondary>in lookups</secondary>
+</indexterm>
+It is possible to construct loops using this facility, and in order to catch
+them, the chains may be no more than fifty items long.
+</para>
+</listitem>
+<listitem>
+<para>
+The @@<<emphasis>lookup</emphasis>> style of item can also be used with a query-style
+lookup, but in this case, the chaining facility is not available. The lookup
+can only return a single list of local parts.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+<emphasis role="bold">Warning</emphasis>: There is an important difference between the address list items
+in these two examples:
+</para>
+<literallayout class="monospaced">
+senders = +my_list
+senders = *@+my_list
+</literallayout>
+<para>
+In the first one, <literal>my_list</literal> is a named address list, whereas in the second
+example it is a named domain list.
+</para>
+</section>
+<section id="SECTcasletadd">
+<title>Case of letters in address lists</title>
+<para>
+<indexterm role="concept">
+<primary>case of local parts</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>address list</primary>
+<secondary>case forcing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>case forcing in address lists</primary>
+</indexterm>
+Domains in email addresses are always handled caselessly, but for local parts
+case may be significant on some systems (see <option>caseful_local_part</option> for how
+Exim deals with this when routing addresses). However, RFC 2505 (<emphasis>Anti-Spam
+Recommendations for SMTP MTAs</emphasis>) suggests that matching of addresses to
+blocking lists should be done in a case-independent manner. Since most address
+lists in Exim are used for this kind of control, Exim attempts to do this by
+default.
+</para>
+<para>
+The domain portion of an address is always lowercased before matching it to an
+address list. The local part is lowercased by default, and any string
+comparisons that take place are done caselessly. This means that the data in
+the address list itself, in files included as plain filenames, and in any file
+that is looked up using the <quote>@@</quote> mechanism, can be in any case. However, the
+keys in files that are looked up by a search type other than <command>lsearch</command> (which
+works caselessly) must be in lower case, because these lookups are not
+case-independent.
+</para>
+<para>
+<indexterm role="concept">
+<primary><literal>+caseful</literal></primary>
+</indexterm>
+To allow for the possibility of caseful address list matching, if an item in
+an address list is the string <quote>+caseful</quote>, the original case of the local
+part is restored for any comparisons that follow, and string comparisons are no
+longer case-independent. This does not affect the domain, which remains in
+lower case. However, although independent matches on the domain alone are still
+performed caselessly, regular expressions that match against an entire address
+become case-sensitive after <quote>+caseful</quote> has been seen.
+</para>
+</section>
+<section id="SECTlocparlis">
+<title>Local part lists</title>
+<para>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>local part list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>list</secondary>
+</indexterm>
+Case-sensitivity in local part lists is handled in the same way as for address
+lists, as just described. The <quote>+caseful</quote> item can be used if required. In a
+setting of the <option>local_parts</option> option in a router with <option>caseful_local_part</option>
+set false, the subject is lowercased and the matching is initially
+case-insensitive. In this case, <quote>+caseful</quote> will restore case-sensitive
+matching in the local part list, but not elsewhere in the router. If
+<option>caseful_local_part</option> is set true in a router, matching in the <option>local_parts</option>
+option is case-sensitive from the start.
+</para>
+<para>
+If a local part list is indirected to a file (see section <xref linkend="SECTfilnamlis"/>),
+comments are handled in the same way as address lists – they are recognized
+only if the # is preceded by white space or the start of the line.
+Otherwise, local part lists are matched in the same way as domain lists, except
+that the special items that refer to the local host (<literal>@</literal>, <literal>@[]</literal>,
+<literal>@mx_any</literal>, <literal>@mx_primary</literal>, and <literal>@mx_secondary</literal>) are not recognized.
+Refer to section <xref linkend="SECTdomainlist"/> for details of the other available item
+types.
+<indexterm role="concept" startref="IIDdohoadli" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPexpand">
+<title>String expansions</title>
+<para>
+<indexterm role="concept" id="IIDstrexp" class="startofrange">
+<primary>expansion</primary>
+<secondary>of strings</secondary>
+</indexterm>
+Many strings in Exim’s runtime configuration are expanded before use. Some of
+them are expanded every time they are used; others are expanded only once.
+</para>
+<para>
+When a string is being expanded it is copied verbatim from left to right except
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>string concatenation</secondary>
+</indexterm>
+when a dollar or backslash character is encountered. A dollar specifies the
+start of a portion of the string that is interpreted and replaced as described
+below in section <xref linkend="SECTexpansionitems"/> onwards. Backslash is used as an
+escape character, as described in the following section.
+</para>
+<para>
+Whether a string is expanded depends upon the context. Usually this is solely
+dependent upon the option for which a value is sought; in this documentation,
+options for which string expansion is performed are marked with † after
+the data type. ACL rules always expand strings. A couple of expansion
+conditions do not expand some of the brace-delimited branches, for security
+reasons,
+<indexterm role="concept">
+<primary>tainted data</primary>
+<secondary>expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>tainted data</secondary>
+</indexterm>
+and expansion of data deriving from the sender (<quote>tainted data</quote>)
+is not permitted.
+</para>
+<section id="SECTlittext">
+<title>Literal text in expanded strings</title>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>including literal text</secondary>
+</indexterm>
+An uninterpreted dollar can be included in an expanded string by putting a
+backslash in front of it. A backslash can be used to prevent any special
+character being treated specially in an expansion, including backslash itself.
+If the string appears in quotes in the configuration file, two backslashes are
+required because the quotes themselves cause interpretation of backslashes when
+the string is read in (see section <xref linkend="SECTstrings"/>).
+</para>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>non-expandable substrings</secondary>
+</indexterm>
+A portion of the string can specified as non-expandable by placing it between
+two occurrences of <literal>\N</literal>. This is particularly useful for protecting regular
+expressions, which often contain backslashes and dollar signs. For example:
+</para>
+<literallayout class="monospaced">
+deny senders = \N^\d{8}[a-z]@some\.site\.example$\N
+</literallayout>
+<para>
+On encountering the first <literal>\N</literal>, the expander copies subsequent characters
+without interpretation until it reaches the next <literal>\N</literal> or the end of the
+string.
+</para>
+</section>
+<section id="SECID82">
+<title>Character escape sequences in expanded strings</title>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>escape sequences</secondary>
+</indexterm>
+A backslash followed by one of the letters <quote>n</quote>, <quote>r</quote>, or <quote>t</quote> in an
+expanded string is recognized as an escape sequence for the character newline,
+carriage return, or tab, respectively. A backslash followed by up to three
+octal digits is recognized as an octal encoding for a single character, and a
+backslash followed by <quote>x</quote> and up to two hexadecimal digits is a hexadecimal
+encoding.
+</para>
+<para>
+These escape sequences are also recognized in quoted strings when they are read
+in. Their interpretation in expansions as well is useful for unquoted strings,
+and for other cases such as looked-up strings that are then expanded.
+</para>
+</section>
+<section id="SECID83">
+<title>Testing string expansions</title>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>testing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>string expansion</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-be</option></primary>
+</indexterm>
+Many expansions can be tested by calling Exim with the <option>-be</option> option. This
+takes the command arguments, or lines from the standard input if there are no
+arguments, runs them through the string expansion code, and writes the results
+to the standard output. Variables based on configuration values are set up, but
+since no message is being processed, variables such as <varname>$local_part</varname> have no
+value. Nevertheless the <option>-be</option> option can be useful for checking out file and
+database lookups, and the use of expansion operators such as <option>sg</option>, <option>substr</option>
+and <option>nhash</option>.
+</para>
+<para>
+Exim gives up its root privilege when it is called with the <option>-be</option> option, and
+instead runs under the uid and gid it was called with, to prevent users from
+using <option>-be</option> for reading files to which they do not have access.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>-bem</option></primary>
+</indexterm>
+If you want to test expansions that include variables whose values are taken
+from a message, there are two other options that can be used. The <option>-bem</option>
+option is like <option>-be</option> except that it is followed by a filename. The file is
+read as a message before doing the test expansions. For example:
+</para>
+<literallayout class="monospaced">
+exim -bem /tmp/test.message '$h_subject:'
+</literallayout>
+<para>
+The <option>-Mset</option> option is used in conjunction with <option>-be</option> and is followed by an
+Exim message identifier. For example:
+</para>
+<literallayout class="monospaced">
+exim -be -Mset 1GrA8W-0004WS-LQ '$recipients'
+</literallayout>
+<para>
+This loads the message from Exim’s spool before doing the test expansions, and
+is therefore restricted to admin users.
+</para>
+</section>
+<section id="SECTforexpfai">
+<title>Forced expansion failure</title>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>forced failure</secondary>
+</indexterm>
+A number of expansions that are described in the following section have
+alternative <quote>true</quote> and <quote>false</quote> substrings, enclosed in brace characters
+(which are sometimes called <quote>curly brackets</quote>). Which of the two strings is
+used depends on some condition that is evaluated as part of the expansion. If,
+instead of a <quote>false</quote> substring, the word <quote>fail</quote> is used (not in braces),
+the entire string expansion fails in a way that can be detected by the code
+that requested the expansion. This is called <quote>forced expansion failure</quote>, and
+its consequences depend on the circumstances. In some cases it is no different
+from any other expansion failure, but in others a different action may be
+taken. Such variations are mentioned in the documentation of the option that is
+being expanded.
+</para>
+</section>
+<section id="SECTexpansionitems">
+<title>Expansion items</title>
+<para>
+The following items are recognized in expanded strings. White space may be used
+between sub-items that are keywords or substrings enclosed in braces inside an
+outer set of braces, to improve readability. <emphasis role="bold">Warning</emphasis>: Within braces,
+white space is significant.
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">$</emphasis><<emphasis>variable name</emphasis>> or <emphasis role="bold">${</emphasis><<emphasis>variable name</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>variables</secondary>
+</indexterm>
+Substitute the contents of the named variable, for example:
+</para>
+<literallayout class="monospaced">
+$local_part
+${domain}
+</literallayout>
+<para>
+The second form can be used to separate the name from subsequent alphanumeric
+characters. This form (using braces) is available only for variables; it does
+<emphasis>not</emphasis> apply to message headers. The names of the variables are given in
+section <xref linkend="SECTexpvar"/> below. If the name of a non-existent variable is
+given, the expansion fails.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${</emphasis><<emphasis>op</emphasis>><emphasis role="bold">:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>operators</secondary>
+</indexterm>
+The string is first itself expanded, and then the operation specified by
+<<emphasis>op</emphasis>> is applied to it. For example:
+</para>
+<literallayout class="monospaced">
+${lc:$local_part}
+</literallayout>
+<para>
+The string starts with the first character after the colon, which may be
+leading white space. A list of operators is given in section <xref linkend="SECTexpop"/>
+below. The operator notation is used for simple expansion items that have just
+one argument, because it reduces the number of braces and therefore makes the
+string easier to understand.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">$bheader_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis> or <emphasis role="bold">$bh_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis></term>
+<listitem>
+<para>
+This item inserts <quote>basic</quote> header lines. It is described with the <option>header</option>
+expansion item below.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${acl{</emphasis><<emphasis>name</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>arg</emphasis>><emphasis role="bold">}...}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>calling an acl</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>acl</option></primary>
+<secondary>call from expansion</secondary>
+</indexterm>
+The name and zero to nine argument strings are first expanded separately. The expanded
+arguments are assigned to the variables <varname>$acl_arg1</varname> to <varname>$acl_arg9</varname> in order.
+Any unused are made empty. The variable <varname>$acl_narg</varname> is set to the number of
+arguments. The named ACL (see chapter <xref linkend="CHAPACL"/>) is called
+and may use the variables; if another acl expansion is used the values
+are restored after it returns. If the ACL sets
+a value using a "message =" modifier and returns accept or deny, the value becomes
+the result of the expansion.
+If no message is set and the ACL returns accept or deny
+the expansion result is an empty string.
+If the ACL returns defer the result is a forced-fail. Otherwise the expansion fails.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${authresults{</emphasis><<emphasis>authserv-id</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>results header</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>headers</primary>
+<secondary>authentication-results:</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>expansion item</secondary>
+</indexterm>
+This item returns a string suitable for insertion as an
+<emphasis>Authentication-Results:</emphasis>
+header line.
+The given <<emphasis>authserv-id</emphasis>> is included in the result; typically this
+will be a domain name identifying the system performing the authentications.
+Methods that might be present in the result include:
+</para>
+<literallayout class="monospaced">
+none
+iprev
+auth
+spf
+dkim
+</literallayout>
+<para>
+Example use (as an ACL modifier):
+</para>
+<literallayout class="monospaced">
+ add_header = :at_start:${authresults {$primary_hostname}}
+</literallayout>
+<para>
+This is safe even if no authentication results are available.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${certextract{</emphasis><<emphasis>field</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>certificate</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string3</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>extracting certificate fields</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>certextract</option></primary>
+<secondary>certificate fields</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>extracting fields</secondary>
+</indexterm>
+The <<emphasis>certificate</emphasis>> must be a variable of type certificate.
+The field name is expanded and used to retrieve the relevant field from
+the certificate. Supported fields are:
+</para>
+<literallayout>
+<literal>version </literal>
+<literal>serial_number </literal>
+<literal>subject </literal> RFC4514 DN
+<literal>issuer </literal> RFC4514 DN
+<literal>notbefore </literal> time
+<literal>notafter </literal> time
+<literal>sig_algorithm </literal>
+<literal>signature </literal>
+<literal>subj_altname </literal> tagged list
+<literal>ocsp_uri </literal> list
+<literal>crl_uri </literal> list
+</literallayout>
+<para>
+If the field is found,
+<<emphasis>string2</emphasis>> is expanded, and replaces the whole item;
+otherwise <<emphasis>string3</emphasis>> is used. During the expansion of <<emphasis>string2</emphasis>> the
+variable <varname>$value</varname> contains the value that has been extracted. Afterwards, it
+is restored to any previous value it might have had.
+</para>
+<para>
+If {<<emphasis>string3</emphasis>>} is omitted, the item is replaced by an empty string if the
+key is not found. If {<<emphasis>string2</emphasis>>} is also omitted, the value that was
+extracted is used.
+</para>
+<para>
+Some field names take optional modifiers, appended and separated by commas.
+</para>
+<para>
+The field selectors marked as "RFC4514" above
+output a Distinguished Name string which is
+not quite
+parseable by Exim as a comma-separated tagged list
+(the exceptions being elements containing commas).
+RDN elements of a single type may be selected by
+a modifier of the type label; if so the expansion
+result is a list (newline-separated by default).
+The separator may be changed by another modifier of
+a right angle-bracket followed immediately by the new separator.
+Recognised RDN type labels include "CN", "O", "OU" and "DC".
+</para>
+<para>
+The field selectors marked as "time" above
+take an optional modifier of "int"
+for which the result is the number of seconds since epoch.
+Otherwise the result is a human-readable string
+in the timezone selected by the main "timezone" option.
+</para>
+<para>
+The field selectors marked as "list" above return a list,
+newline-separated by default,
+(embedded separator characters in elements are doubled).
+The separator may be changed by a modifier of
+a right angle-bracket followed immediately by the new separator.
+</para>
+<para>
+The field selectors marked as "tagged" above
+prefix each list element with a type string and an equals sign.
+Elements of only one type may be selected by a modifier
+which is one of "dns", "uri" or "mail";
+if so the element tags are omitted.
+</para>
+<para>
+If not otherwise noted field values are presented in human-readable form.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${dlfunc{</emphasis><<emphasis>file</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>function</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>arg</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>arg</emphasis>><emphasis role="bold">}...}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>dlfunc</option></primary>
+</indexterm>
+This expansion dynamically loads and then calls a locally-written C function.
+This functionality is available only if Exim is compiled with
+</para>
+<literallayout class="monospaced">
+EXPAND_DLFUNC=yes
+</literallayout>
+<para>
+set in <filename>Local/Makefile</filename>. Once loaded, Exim remembers the dynamically loaded
+object so that it doesn’t reload the same object file in the same Exim process
+(but of course Exim does start new processes frequently).
+</para>
+<para>
+There may be from zero to eight arguments to the function.
+</para>
+<para>
+When compiling
+a local function that is to be called in this way,
+first <filename>DLFUNC_IMPL</filename> should be defined,
+and second <filename>local_scan.h</filename> should be included.
+The Exim variables and functions that are defined by that API
+are also available for dynamically loaded functions. The function itself
+must have the following type:
+</para>
+<literallayout class="monospaced">
+int dlfunction(uschar **yield, int argc, uschar *argv[])
+</literallayout>
+<para>
+Where <literal>uschar</literal> is a typedef for <literal>unsigned char</literal> in <filename>local_scan.h</filename>. The
+function should return one of the following values:
+</para>
+<para>
+<literal>OK</literal>: Success. The string that is placed in the variable <emphasis>yield</emphasis> is put
+into the expanded string that is being built.
+</para>
+<para>
+<literal>FAIL</literal>: A non-forced expansion failure occurs, with the error message taken
+from <emphasis>yield</emphasis>, if it is set.
+</para>
+<para>
+<literal>FAIL_FORCED</literal>: A forced expansion failure occurs, with the error message
+taken from <emphasis>yield</emphasis> if it is set.
+</para>
+<para>
+<literal>ERROR</literal>: Same as <literal>FAIL</literal>, except that a panic log entry is written.
+</para>
+<para>
+When compiling a function that is to be used in this way with gcc,
+you need to add <option>-shared</option> to the gcc command. Also, in the Exim build-time
+configuration, you must add <option>-export-dynamic</option> to EXTRALIBS.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${env{</emphasis><<emphasis>key</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>extracting value from environment</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>environment</primary>
+<secondary>values from</secondary>
+</indexterm>
+The key is first expanded separately, and leading and trailing white space
+removed.
+This is then searched for as a name in the environment.
+If a variable is found then its value is placed in <varname>$value</varname>
+and <<emphasis>string1</emphasis>> is expanded, otherwise <<emphasis>string2</emphasis>> is expanded.
+</para>
+<para>
+Instead of {<<emphasis>string2</emphasis>>} the word <quote>fail</quote> (not in curly brackets) can
+appear, for example:
+</para>
+<literallayout class="monospaced">
+${env{USER}{$value} fail }
+</literallayout>
+<para>
+This forces an expansion failure (see section <xref linkend="SECTforexpfai"/>);
+{<<emphasis>string1</emphasis>>} must be present for <quote>fail</quote> to be recognized.
+</para>
+<para>
+If {<<emphasis>string2</emphasis>>} is omitted an empty string is substituted on
+search failure.
+If {<<emphasis>string1</emphasis>>} is omitted the search result is substituted on
+search success.
+</para>
+<para>
+The environment is adjusted by the <option>keep_environment</option> and
+<option>add_environment</option> main section options.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${extract{</emphasis><<emphasis>key</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string3</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>extracting substrings by key</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>extract</option></primary>
+<secondary>substrings by key</secondary>
+</indexterm>
+The key and <<emphasis>string1</emphasis>> are first expanded separately. Leading and trailing
+white space is removed from the key (but not from any of the strings). The key
+must not be empty and must not consist entirely of digits.
+The expanded <<emphasis>string1</emphasis>> must be of the form:
+</para>
+<literallayout>
+<<emphasis>key1</emphasis>> = <<emphasis>value1</emphasis>> <<emphasis>key2</emphasis>> = <<emphasis>value2</emphasis>> ...
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$value</varname></primary>
+</indexterm>
+where the equals signs and spaces (but not both) are optional. If any of the
+values contain white space, they must be enclosed in double quotes, and any
+values that are enclosed in double quotes are subject to escape processing as
+described in section <xref linkend="SECTstrings"/>. The expanded <<emphasis>string1</emphasis>> is searched
+for the value that corresponds to the key. The search is case-insensitive. If
+the key is found, <<emphasis>string2</emphasis>> is expanded, and replaces the whole item;
+otherwise <<emphasis>string3</emphasis>> is used. During the expansion of <<emphasis>string2</emphasis>> the
+variable <varname>$value</varname> contains the value that has been extracted. Afterwards, it
+is restored to any previous value it might have had.
+</para>
+<para>
+If {<<emphasis>string3</emphasis>>} is omitted, the item is replaced by an empty string if the
+key is not found. If {<<emphasis>string2</emphasis>>} is also omitted, the value that was
+extracted is used. Thus, for example, these two expansions are identical, and
+yield <quote>2001</quote>:
+</para>
+<literallayout class="monospaced">
+${extract{gid}{uid=1984 gid=2001}}
+${extract{gid}{uid=1984 gid=2001}{$value}}
+</literallayout>
+<para>
+Instead of {<<emphasis>string3</emphasis>>} the word <quote>fail</quote> (not in curly brackets) can
+appear, for example:
+</para>
+<literallayout class="monospaced">
+${extract{Z}{A=... B=...}{$value} fail }
+</literallayout>
+<para>
+This forces an expansion failure (see section <xref linkend="SECTforexpfai"/>);
+{<<emphasis>string2</emphasis>>} must be present for <quote>fail</quote> to be recognized.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${extract json{</emphasis><<emphasis>key</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string3</emphasis>><emphasis role="bold">}}</emphasis></term>
+<term><emphasis role="bold">${extract jsons{</emphasis><<emphasis>key</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string3</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>extracting from JSON object</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>JSON</primary>
+<secondary>expansions</secondary>
+</indexterm>
+The key and <<emphasis>string1</emphasis>> are first expanded separately. Leading and trailing
+white space is removed from the key (but not from any of the strings). The key
+must not be empty and must not consist entirely of digits.
+The expanded <<emphasis>string1</emphasis>> must be of the form:
+</para>
+<literallayout>
+{ <<emphasis>"key1"</emphasis>> : <<emphasis>value1</emphasis>> , <<emphasis>"key2"</emphasis>> , <<emphasis>value2</emphasis>> ... }
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$value</varname></primary>
+</indexterm>
+The braces, commas and colons, and the quoting of the member name are required;
+the spaces are optional.
+Matching of the key against the member names is done case-sensitively.
+For the <quote>json</quote> variant,
+if a returned value is a JSON string, it retains its leading and
+trailing quotes.
+For the <quote>jsons</quote> variant, which is intended for use with JSON strings, the
+leading and trailing quotes are removed from the returned value.
+</para>
+<para>
+The results of matching are handled as above.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${extract{</emphasis><<emphasis>number</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>separators</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string3</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>extracting substrings by number</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>extract</option></primary>
+<secondary>substrings by number</secondary>
+</indexterm>
+The <<emphasis>number</emphasis>> argument must consist entirely of decimal digits,
+apart from leading and trailing white space, which is ignored.
+This is what distinguishes this form of <option>extract</option> from the previous kind. It
+behaves in the same way, except that, instead of extracting a named field, it
+extracts from <<emphasis>string1</emphasis>> the field whose number is given as the first
+argument. You can use <varname>$value</varname> in <<emphasis>string2</emphasis>> or <literal>fail</literal> instead of
+<<emphasis>string3</emphasis>> as before.
+</para>
+<para>
+The fields in the string are separated by any one of the characters in the
+separator string. These may include space or tab characters.
+The first field is numbered one. If the number is negative, the fields are
+counted from the end of the string, with the rightmost one numbered -1. If the
+number given is zero, the entire string is returned. If the modulus of the
+number is greater than the number of fields in the string, the result is the
+expansion of <<emphasis>string3</emphasis>>, or the empty string if <<emphasis>string3</emphasis>> is not
+provided. For example:
+</para>
+<literallayout class="monospaced">
+${extract{2}{:}{x:42:99:& Mailer::/bin/bash}}
+</literallayout>
+<para>
+yields <quote>42</quote>, and
+</para>
+<literallayout class="monospaced">
+${extract{-4}{:}{x:42:99:& Mailer::/bin/bash}}
+</literallayout>
+<para>
+yields <quote>99</quote>. Two successive separators mean that the field between them is
+empty (for example, the fifth field above).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${extract json {</emphasis><<emphasis>number</emphasis>><emphasis role="bold">}}{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string3</emphasis>><emphasis role="bold">}}</emphasis></term>
+<term><emphasis role="bold">${extract jsons{</emphasis><<emphasis>number</emphasis>><emphasis role="bold">}}{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string3</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>extracting from JSON array</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>JSON</primary>
+<secondary>expansions</secondary>
+</indexterm>
+The <<emphasis>number</emphasis>> argument must consist entirely of decimal digits,
+apart from leading and trailing white space, which is ignored.
+</para>
+<para>
+Field selection and result handling is as above;
+there is no choice of field separator.
+For the <quote>json</quote> variant,
+if a returned value is a JSON string, it retains its leading and
+trailing quotes.
+For the <quote>jsons</quote> variant, which is intended for use with JSON strings, the
+leading and trailing quotes are removed from the returned value.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${filter{</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>condition</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>selecting by condition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>selecting from list by condition</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$item</varname></primary>
+</indexterm>
+After expansion, <<emphasis>string</emphasis>> is interpreted as a list, colon-separated by
+default, but the separator can be changed in the usual way (<xref linkend="SECTlistsepchange"/>).
+For each item
+in this list, its value is place in <varname>$item</varname>, and then the condition is
+evaluated. If the condition is true, <varname>$item</varname> is added to the output as an
+item in a new list; if the condition is false, the item is discarded. The
+separator used for the output list is the same as the one used for the
+input, but a separator setting is not included in the output. For example:
+</para>
+<literallayout class="monospaced">
+${filter{a:b:c}{!eq{$item}{b}}}
+</literallayout>
+<para>
+yields <literal>a:c</literal>. At the end of the expansion, the value of <varname>$item</varname> is restored
+to what it was before. See also the <option>map</option> and <option>reduce</option> expansion items.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${hash{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string3</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>hash function</primary>
+<secondary>textual</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>textual hash</secondary>
+</indexterm>
+This is a textual hashing function, and was the first to be implemented in
+early versions of Exim. In current releases, there are other hashing functions
+(numeric, MD5, and SHA-1), which are described below.
+</para>
+<para>
+The first two strings, after expansion, must be numbers. Call them <<emphasis>m</emphasis>> and
+<<emphasis>n</emphasis>>. If you are using fixed values for these numbers, that is, if
+<<emphasis>string1</emphasis>> and <<emphasis>string2</emphasis>> do not change when they are expanded, you can
+use the simpler operator notation that avoids some of the braces:
+</para>
+<literallayout class="monospaced">
+${hash_<n>_<m>:<string>}
+</literallayout>
+<para>
+The second number is optional (in both notations). If <<emphasis>n</emphasis>> is greater than
+or equal to the length of the string, the expansion item returns the string.
+Otherwise it computes a new string of length <<emphasis>n</emphasis>> by applying a hashing
+function to the string. The new string consists of characters taken from the
+first <<emphasis>m</emphasis>> characters of the string
+</para>
+<literallayout class="monospaced">
+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQWRSTUVWXYZ0123456789
+</literallayout>
+<para>
+If <<emphasis>m</emphasis>> is not present the value 26 is used, so that only lower case
+letters appear. For example:
+</para>
+<literallayout>
+<literal>$hash{3}{monty}} </literal> yields <literal>jmg</literal>
+<literal>$hash{5}{monty}} </literal> yields <literal>monty</literal>
+<literal>$hash{4}{62}{monty python}}</literal> yields <literal>fbWx</literal>
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">$header_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis> or <emphasis role="bold">$h_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis></term>
+<term><emphasis role="bold">$bheader_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis> or <emphasis role="bold">$bh_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis></term>
+<term><emphasis role="bold">$lheader_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis> or <emphasis role="bold">$lh_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis></term>
+<term><emphasis role="bold">$rheader_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis> or <emphasis role="bold">$rh_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>header insertion</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$header_</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$bheader_</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$lheader_</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$rheader_</varname></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>in expansion strings</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>character sets</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>decoding</secondary>
+</indexterm>
+Substitute the contents of the named message header line, for example
+</para>
+<literallayout class="monospaced">
+$header_reply-to:
+</literallayout>
+<para>
+The newline that terminates a header line is not included in the expansion, but
+internal newlines (caused by splitting the header line over several physical
+lines) may be present.
+</para>
+<para>
+The difference between the four pairs of expansions is in the way
+the data in the header line is interpreted.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>white space</primary>
+<secondary>in header lines</secondary>
+</indexterm>
+<option>rheader</option> gives the original <quote>raw</quote> content of the header line, with no
+processing at all, and without the removal of leading and trailing white space.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>of header lines</secondary>
+</indexterm>
+<option>lheader</option> gives a colon-separated list, one element per header when there
+are multiple headers with a given name.
+Any embedded colon characters within an element are doubled, so normal Exim
+list-processing facilities can be used.
+The terminating newline of each element is removed; in other respects
+the content is <quote>raw</quote>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>base64 encoding</primary>
+<secondary>in header lines</secondary>
+</indexterm>
+<option>bheader</option> removes leading and trailing white space, and then decodes base64
+or quoted-printable MIME <quote>words</quote> within the header text, but does no
+character set translation. If decoding of what looks superficially like a MIME
+<quote>word</quote> fails, the raw string is returned. If decoding
+<indexterm role="concept">
+<primary>binary zero</primary>
+<secondary>in header line</secondary>
+</indexterm>
+produces a binary zero character, it is replaced by a question mark – this is
+what Exim does for binary zeros that are actually received in header lines.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>header</option> tries to translate the string as decoded by <option>bheader</option> to a
+standard character set. This is an attempt to produce the same string as would
+be displayed on a user’s MUA. If translation fails, the <option>bheader</option> string is
+returned. Translation is attempted only on operating systems that support the
+<function>iconv()</function> function. This is indicated by the compile-time macro HAVE_ICONV in
+a system Makefile or in <filename>Local/Makefile</filename>.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+In a filter file, the target character set for <option>header</option> can be specified by a
+command of the following form:
+</para>
+<literallayout class="monospaced">
+headers charset "UTF-8"
+</literallayout>
+<para>
+This command affects all references to <varname>$h_</varname> (or <varname>$header_</varname>) expansions in
+subsequently obeyed filter commands. In the absence of this command, the target
+character set in a filter is taken from the setting of the <option>headers_charset</option>
+option in the runtime configuration. The value of this option defaults to the
+value of HEADERS_CHARSET in <filename>Local/Makefile</filename>. The ultimate default is
+ISO-8859-1.
+</para>
+<para>
+Header names follow the syntax of RFC 2822, which states that they may contain
+any printing characters except space and colon. Consequently, curly brackets
+<emphasis>do not</emphasis> terminate header names, and should not be used to enclose them as
+if they were variables. Attempting to do so causes a syntax error.
+</para>
+<para>
+Only header lines that are common to all copies of a message are visible to
+this mechanism. These are the original header lines that are received with the
+message, and any that are added by an ACL statement or by a system
+filter. Header lines that are added to a particular copy of a message by a
+router or transport are not accessible.
+</para>
+<para>
+For incoming SMTP messages, no header lines are visible in
+ACLs that are obeyed before the data phase completes,
+because the header structure is not set up until the message is received.
+They are visible in DKIM, PRDR and DATA ACLs.
+Header lines that are added in a RCPT ACL (for example)
+are saved until the message’s incoming header lines are available, at which
+point they are added.
+When any of the above ACLs ar
+running, however, header lines added by earlier ACLs are visible.
+</para>
+<para>
+Upper case and lower case letters are synonymous in header names. If the
+following character is white space, the terminating colon may be omitted, but
+this is not recommended, because you may then forget it when it is needed. When
+white space terminates the header name, this white space is included in the
+expanded string. If the message does not contain the given header, the
+expansion item is replaced by an empty string. (See the <option>def</option> condition in
+section <xref linkend="SECTexpcond"/> for a means of testing for the existence of a
+header.)
+</para>
+<para>
+If there is more than one header with the same name, they are all concatenated
+to form the substitution string, up to a maximum length of 64K. Unless
+<option>rheader</option> is being used, leading and trailing white space is removed from
+each header before concatenation, and a completely empty header is ignored. A
+newline character is then inserted between non-empty headers, but there is no
+newline at the very end. For the <option>header</option> and <option>bheader</option> expansion, for
+those headers that contain lists of addresses, a comma is also inserted at the
+junctions between headers. This does not happen for the <option>rheader</option> expansion.
+</para>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>tainted data</primary>
+</indexterm>
+When the headers are from an incoming message,
+the result of expanding any of these variables is tainted.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${hmac{</emphasis><<emphasis>hashname</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>secret</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>hmac hashing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>hmac</option></primary>
+</indexterm>
+This function uses cryptographic hashing (either MD5 or SHA-1) to convert a
+shared secret and some text into a message authentication code, as specified in
+RFC 2104. This differs from <literal>${md5:secret_text...}</literal> or
+<literal>${sha1:secret_text...}</literal> in that the hmac step adds a signature to the
+cryptographic hash, allowing for authentication that is not possible with MD5
+or SHA-1 alone. The hash name must expand to either <literal>md5</literal> or <literal>sha1</literal> at
+present. For example:
+</para>
+<literallayout class="monospaced">
+${hmac{md5}{somesecret}{$primary_hostname $tod_log}}
+</literallayout>
+<para>
+For the hostname <emphasis>mail.example.com</emphasis> and time 2002-10-17 11:30:59, this
+produces:
+</para>
+<literallayout class="monospaced">
+dd97e3ba5d1a61b5006108f8c8252953
+</literallayout>
+<para>
+As an example of how this might be used, you might put in the main part of
+an Exim configuration:
+</para>
+<literallayout class="monospaced">
+SPAMSCAN_SECRET=cohgheeLei2thahw
+</literallayout>
+<para>
+In a router or a transport you could then have:
+</para>
+<literallayout class="monospaced">
+headers_add = \
+ X-Spam-Scanned: ${primary_hostname} ${message_exim_id} \
+ ${hmac{md5}{SPAMSCAN_SECRET}\
+ {${primary_hostname},${message_exim_id},$h_message-id:}}
+</literallayout>
+<para>
+Then given a message, you can check where it was scanned by looking at the
+<emphasis>X-Spam-Scanned:</emphasis> header line. If you know the secret, you can check that
+this header line is authentic by recomputing the authentication code from the
+host name, message ID and the <emphasis>Message-id:</emphasis> header line. This can be done
+using Exim’s <option>-be</option> option, or by other means, for example, by using the
+<emphasis>hmac_md5_hex()</emphasis> function in Perl.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${if </emphasis><<emphasis>condition</emphasis>><emphasis role="bold"> {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>conditional</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>if</option>, expansion item</primary>
+</indexterm>
+If <<emphasis>condition</emphasis>> is true, <<emphasis>string1</emphasis>> is expanded and replaces the whole
+item; otherwise <<emphasis>string2</emphasis>> is used. The available conditions are described
+in section <xref linkend="SECTexpcond"/> below. For example:
+</para>
+<literallayout class="monospaced">
+${if eq {$local_part}{postmaster} {yes}{no} }
+</literallayout>
+<para>
+The second string need not be present; if it is not and the condition is not
+true, the item is replaced with nothing. Alternatively, the word <quote>fail</quote> may
+be present instead of the second string (without any curly brackets). In this
+case, the expansion is forced to fail if the condition is not true (see section
+<xref linkend="SECTforexpfai"/>).
+</para>
+<para>
+If both strings are omitted, the result is the string <literal>true</literal> if the condition
+is true, and the empty string if the condition is false. This makes it less
+cumbersome to write custom ACL and router conditions. For example, instead of
+</para>
+<literallayout class="monospaced">
+condition = ${if >{$acl_m4}{3}{true}{false}}
+</literallayout>
+<para>
+you can use
+</para>
+<literallayout class="monospaced">
+condition = ${if >{$acl_m4}{3}}
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${imapfolder{</emphasis><<emphasis>foldername</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>imap folder</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>imapfolder</option> expansion item</primary>
+</indexterm>
+This item converts a (possibly multilevel, or with non-ASCII characters)
+folder specification to a Maildir name for filesystem use.
+For information on internationalisation support see <xref linkend="SECTi18nMDA"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${length{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>string truncation</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>length</option> expansion item</primary>
+</indexterm>
+The <option>length</option> item is used to extract the initial portion of a string. Both
+strings are expanded, and the first one must yield a number, <<emphasis>n</emphasis>>, say. If
+you are using a fixed value for the number, that is, if <<emphasis>string1</emphasis>> does not
+change when expanded, you can use the simpler operator notation that avoids
+some of the braces:
+</para>
+<literallayout class="monospaced">
+${length_<n>:<string>}
+</literallayout>
+<para>
+The result of this item is either the first <<emphasis>n</emphasis>> bytes or the whole
+of <<emphasis>string2</emphasis>>, whichever is the shorter. Do not confuse <option>length</option> with
+<option>strlen</option>, which gives the length of a string.
+All measurement is done in bytes and is not UTF-8 aware.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${listextract{</emphasis><<emphasis>number</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string3</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>extracting list elements by number</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>listextract</option></primary>
+<secondary>extract list elements by number</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>extracting elements by number</secondary>
+</indexterm>
+The <<emphasis>number</emphasis>> argument must consist entirely of decimal digits,
+apart from an optional leading minus,
+and leading and trailing white space (which is ignored).
+</para>
+<para>
+After expansion, <<emphasis>string1</emphasis>> is interpreted as a list, colon-separated by
+default, but the separator can be changed in the usual way (<xref linkend="SECTlistsepchange"/>).
+</para>
+<para>
+The first field of the list is numbered one.
+If the number is negative, the fields are
+counted from the end of the list, with the rightmost one numbered -1.
+The numbered element of the list is extracted and placed in <varname>$value</varname>,
+then <<emphasis>string2</emphasis>> is expanded as the result.
+</para>
+<para>
+If the modulus of the
+number is zero or greater than the number of fields in the string,
+the result is the expansion of <<emphasis>string3</emphasis>>.
+</para>
+<para>
+For example:
+</para>
+<literallayout class="monospaced">
+${listextract{2}{x:42:99}}
+</literallayout>
+<para>
+yields <quote>42</quote>, and
+</para>
+<literallayout class="monospaced">
+${listextract{-3}{<, x,42,99,& Mailer,,/bin/bash}{result: $value}}
+</literallayout>
+<para>
+yields <quote>result: 42</quote>.
+</para>
+<para>
+If {<<emphasis>string3</emphasis>>} is omitted, an empty string is used for string3.
+If {<<emphasis>string2</emphasis>>} is also omitted, the value that was
+extracted is used.
+You can use <literal>fail</literal> instead of {<<emphasis>string3</emphasis>>} as in a string extract.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${lookup{</emphasis><<emphasis>key</emphasis>><emphasis role="bold">} </emphasis><<emphasis>search type</emphasis>><emphasis role="bold"> {</emphasis><<emphasis>file</emphasis>><emphasis role="bold">} {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">} {</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+This is the first of one of two different types of lookup item, which are both
+described in the next item.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${lookup </emphasis><<emphasis>search type</emphasis>><emphasis role="bold"> {</emphasis><<emphasis>query</emphasis>><emphasis role="bold">} {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">} {</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>lookup in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>lookups</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>in expanded string</secondary>
+</indexterm>
+The two forms of lookup item specify data lookups in files and databases, as
+discussed in chapter <xref linkend="CHAPfdlookup"/>. The first form is used for single-key
+lookups, and the second is used for query-style lookups. The <<emphasis>key</emphasis>>,
+<<emphasis>file</emphasis>>, and <<emphasis>query</emphasis>> strings are expanded before use.
+</para>
+<para>
+If there is any white space in a lookup item which is part of a filter command,
+a retry or rewrite rule, a routing rule for the <command>manualroute</command> router, or any
+other place where white space is significant, the lookup item must be enclosed
+in double quotes. The use of data lookups in users’ filter files may be locked
+out by the system administrator.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$value</varname></primary>
+</indexterm>
+If the lookup succeeds, <<emphasis>string1</emphasis>> is expanded and replaces the entire item.
+During its expansion, the variable <varname>$value</varname> contains the data returned by the
+lookup. Afterwards it reverts to the value it had previously (at the outer
+level it is empty). If the lookup fails, <<emphasis>string2</emphasis>> is expanded and replaces
+the entire item. If {<<emphasis>string2</emphasis>>} is omitted, the replacement is the empty
+string on failure. If <<emphasis>string2</emphasis>> is provided, it can itself be a nested
+lookup, thus providing a mechanism for looking up a default value when the
+original lookup fails.
+</para>
+<para>
+If a nested lookup is used as part of <<emphasis>string1</emphasis>>, <varname>$value</varname> contains the
+data for the outer lookup while the parameters of the second lookup are
+expanded, and also while <<emphasis>string2</emphasis>> of the second lookup is expanded, should
+the second lookup fail. Instead of {<<emphasis>string2</emphasis>>} the word <quote>fail</quote> can
+appear, and in this case, if the lookup fails, the entire expansion is forced
+to fail (see section <xref linkend="SECTforexpfai"/>). If both {<<emphasis>string1</emphasis>>} and
+{<<emphasis>string2</emphasis>>} are omitted, the result is the looked up value in the case of a
+successful lookup, and nothing in the case of failure.
+</para>
+<para>
+For single-key lookups, the string <quote>partial</quote> is permitted to precede the
+search type in order to do partial matching, and * or *@ may follow a search
+type to request default lookups if the key does not match (see sections
+<xref linkend="SECTdefaultvaluelookups"/> and <xref linkend="SECTpartiallookup"/> for details).
+</para>
+<para>
+<indexterm role="concept">
+<primary>numerical variables (<varname>$1</varname> <varname>$2</varname> etc)</primary>
+<secondary>in lookup expansion</secondary>
+</indexterm>
+If a partial search is used, the variables <varname>$1</varname> and <varname>$2</varname> contain the wild
+and non-wild parts of the key during the expansion of the replacement text.
+They return to their previous values at the end of the lookup item.
+</para>
+<para>
+This example looks up the postmaster alias in the conventional alias file:
+</para>
+<literallayout class="monospaced">
+${lookup {postmaster} lsearch {/etc/aliases} {$value}}
+</literallayout>
+<para>
+This example uses NIS+ to look up the full name of the user corresponding to
+the local part of an address, forcing the expansion to fail if it is not found:
+</para>
+<literallayout class="monospaced">
+${lookup nisplus {[name=$local_part],passwd.org_dir:gcos} \
+ {$value}fail}
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${map{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>list creation</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$item</varname></primary>
+</indexterm>
+After expansion, <<emphasis>string1</emphasis>> is interpreted as a list, colon-separated by
+default, but the separator can be changed in the usual way (<xref linkend="SECTlistsepchange"/>).
+For each item
+in this list, its value is place in <varname>$item</varname>, and then <<emphasis>string2</emphasis>> is
+expanded and added to the output as an item in a new list. The separator used
+for the output list is the same as the one used for the input, but a separator
+setting is not included in the output. For example:
+</para>
+<literallayout class="monospaced">
+${map{a:b:c}{[$item]}} ${map{<- x-y-z}{($item)}}
+</literallayout>
+<para>
+expands to <literal>[a]:[b]:[c] (x)-(y)-(z)</literal>. At the end of the expansion, the
+value of <varname>$item</varname> is restored to what it was before. See also the <option>filter</option>
+and <option>reduce</option> expansion items.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${nhash{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string3</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>numeric hash</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>hash function</primary>
+<secondary>numeric</secondary>
+</indexterm>
+The three strings are expanded; the first two must yield numbers. Call them
+<<emphasis>n</emphasis>> and <<emphasis>m</emphasis>>. If you are using fixed values for these numbers, that is,
+if <<emphasis>string1</emphasis>> and <<emphasis>string2</emphasis>> do not change when they are expanded, you
+can use the simpler operator notation that avoids some of the braces:
+</para>
+<literallayout class="monospaced">
+${nhash_<n>_<m>:<string>}
+</literallayout>
+<para>
+The second number is optional (in both notations). If there is only one number,
+the result is a number in the range 0–<<emphasis>n</emphasis>>-1. Otherwise, the string is
+processed by a div/mod hash function that returns two numbers, separated by a
+slash, in the ranges 0 to <<emphasis>n</emphasis>>-1 and 0 to <<emphasis>m</emphasis>>-1, respectively. For
+example,
+</para>
+<literallayout class="monospaced">
+${nhash{8}{64}{supercalifragilisticexpialidocious}}
+</literallayout>
+<para>
+returns the string <quote>6/33</quote>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${perl{</emphasis><<emphasis>subroutine</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>arg</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>arg</emphasis>><emphasis role="bold">}...}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>Perl</primary>
+<secondary>use in expanded string</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>calling Perl from</secondary>
+</indexterm>
+This item is available only if Exim has been built to include an embedded Perl
+interpreter. The subroutine name and the arguments are first separately
+expanded, and then the Perl subroutine is called with those arguments. No
+additional arguments need be given; the maximum number permitted, including the
+name of the subroutine, is nine.
+</para>
+<para>
+The return value of the subroutine is inserted into the expanded string, unless
+the return value is <option>undef</option>. In that case, the expansion fails in the same
+way as an explicit <quote>fail</quote> on a lookup item. The return value is a scalar.
+Whatever you return is evaluated in a scalar context. For example, if you
+return the name of a Perl vector, the return value is the size of the vector,
+not its contents.
+</para>
+<para>
+If the subroutine exits by calling Perl’s <option>die</option> function, the expansion fails
+with the error message that was passed to <option>die</option>. More details of the embedded
+Perl facility are given in chapter <xref linkend="CHAPperl"/>.
+</para>
+<para>
+The <command>redirect</command> router has an option called <option>forbid_filter_perl</option> which locks
+out the use of this expansion item in filter files.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${prvs{</emphasis><<emphasis>address</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>secret</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>keynumber</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>prvs</option> expansion item</primary>
+</indexterm>
+The first argument is a complete email address and the second is secret
+keystring. The third argument, specifying a key number, is optional. If absent,
+it defaults to 0. The result of the expansion is a prvs-signed email address,
+to be typically used with the <option>return_path</option> option on an <command>smtp</command> transport
+as part of a bounce address tag validation (BATV) scheme. For more discussion
+and an example, see section <xref linkend="SECTverifyPRVS"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${prvscheck{</emphasis><<emphasis>address</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>secret</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>prvscheck</option> expansion item</primary>
+</indexterm>
+This expansion item is the complement of the <option>prvs</option> item. It is used for
+checking prvs-signed addresses. If the expansion of the first argument does not
+yield a syntactically valid prvs-signed address, the whole item expands to the
+empty string. When the first argument does expand to a syntactically valid
+prvs-signed address, the second argument is expanded, with the prvs-decoded
+version of the address and the key number extracted from the address in the
+variables <varname>$prvscheck_address</varname> and <varname>$prvscheck_keynum</varname>, respectively.
+</para>
+<para>
+These two variables can be used in the expansion of the second argument to
+retrieve the secret. The validity of the prvs-signed address is then checked
+against the secret. The result is stored in the variable <varname>$prvscheck_result</varname>,
+which is empty for failure or <quote>1</quote> for success.
+</para>
+<para>
+The third argument is optional; if it is missing, it defaults to an empty
+string. This argument is now expanded. If the result is an empty string, the
+result of the expansion is the decoded version of the address. This is the case
+whether or not the signature was valid. Otherwise, the result of the expansion
+is the expansion of the third argument.
+</para>
+<para>
+All three variables can be used in the expansion of the third argument.
+However, once the expansion is complete, only <varname>$prvscheck_result</varname> remains set.
+For more discussion and an example, see section <xref linkend="SECTverifyPRVS"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${readfile{</emphasis><<emphasis>file name</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>eol string</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>inserting an entire file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>inserting into expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>readfile</option> expansion item</primary>
+</indexterm>
+The filename and end-of-line string are first expanded separately. The file is
+then read, and its contents replace the entire item. All newline characters in
+the file are replaced by the end-of-line string if it is present. Otherwise,
+newlines are left in the string.
+String expansion is not applied to the contents of the file. If you want this,
+you must wrap the item in an <option>expand</option> operator. If the file cannot be read,
+the string expansion fails.
+</para>
+<para>
+The <command>redirect</command> router has an option called <option>forbid_filter_readfile</option> which
+locks out the use of this expansion item in filter files.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${readsocket{</emphasis><<emphasis>name</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>request</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>options</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>eol string</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>fail string</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>inserting from a socket</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>socket, use of in expansion</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>readsocket</option> expansion item</primary>
+</indexterm>
+This item inserts data from a Unix domain or TCP socket into the expanded
+string. The minimal way of using it uses just two arguments, as in these
+examples:
+</para>
+<literallayout class="monospaced">
+${readsocket{/socket/name}{request string}}
+${readsocket{inet:some.host:1234}{request string}}
+</literallayout>
+<para>
+For a Unix domain socket, the first substring must be the path to the socket.
+For an Internet socket, the first substring must contain <literal>inet:</literal> followed by
+a host name or IP address, followed by a colon and a port, which can be a
+number or the name of a TCP port in <filename>/etc/services</filename>. An IP address may
+optionally be enclosed in square brackets. This is best for IPv6 addresses. For
+example:
+</para>
+<literallayout class="monospaced">
+${readsocket{inet:[::1]:1234}{request string}}
+</literallayout>
+<para>
+Only a single host name may be given, but if looking it up yields more than
+one IP address, they are each tried in turn until a connection is made. For
+both kinds of socket, Exim makes a connection, writes the request string
+unless it is an empty string; and no terminating NUL is ever sent)
+and reads from the socket until an end-of-file
+is read. A timeout of 5 seconds is applied. Additional, optional arguments
+extend what can be done. Firstly, you can vary the timeout. For example:
+</para>
+<literallayout class="monospaced">
+${readsocket{/socket/name}{request string}{3s}}
+</literallayout>
+<para>
+The third argument is a list of options, of which the first element is the timeout
+and must be present if any options are given.
+Further elements are options of form <emphasis>name=value</emphasis>.
+Example:
+</para>
+<literallayout class="monospaced">
+${readsocket{/socket/name}{request string}{3s:shutdown=no}}
+</literallayout>
+<para revisionflag="changed">
+The following option names are recognised:
+</para>
+<itemizedlist revisionflag="changed">
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">cache</emphasis>
+Defines if the result data can be cached for use by a later identical
+request in the same process.
+Values are <quote>yes</quote> or <quote>no</quote> (the default).
+If not, all cached results for this connection specification
+will be invalidated.
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">shutdown</emphasis>
+Defines whether or not a write-shutdown is done on the connection after
+sending the request. Values are <quote>yes</quote> (the default) or <quote>no</quote>
+(preferred, eg. by some webservers).
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">tls</emphasis>
+Controls the use of TLS on the connection.
+Values are <quote>yes</quote> or <quote>no</quote> (the default).
+If it is enabled, a shutdown as descripbed above is never done.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+A fourth argument allows you to change any newlines that are in the data
+that is read, in the same way as for <option>readfile</option> (see above). This example
+turns them into spaces:
+</para>
+<literallayout class="monospaced">
+${readsocket{inet:127.0.0.1:3294}{request string}{3s}{ }}
+</literallayout>
+<para>
+As with all expansions, the substrings are expanded before the processing
+happens. Errors in these sub-expansions cause the expansion to fail. In
+addition, the following errors can occur:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Failure to create a socket file descriptor;
+</para>
+</listitem>
+<listitem>
+<para>
+Failure to connect the socket;
+</para>
+</listitem>
+<listitem>
+<para>
+Failure to write the request string;
+</para>
+</listitem>
+<listitem>
+<para>
+Timeout on reading from the socket.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+By default, any of these errors causes the expansion to fail. However, if
+you supply a fifth substring, it is expanded and used when any of the above
+errors occurs. For example:
+</para>
+<literallayout class="monospaced">
+${readsocket{/socket/name}{request string}{3s}{\n}\
+ {socket failure}}
+</literallayout>
+<para>
+You can test for the existence of a Unix domain socket by wrapping this
+expansion in <literal>${if exists</literal>, but there is a race condition between that test
+and the actual opening of the socket, so it is safer to use the fifth argument
+if you want to be absolutely sure of avoiding an expansion error for a
+non-existent Unix domain socket, or a failure to connect to an Internet socket.
+</para>
+<para>
+The <command>redirect</command> router has an option called <option>forbid_filter_readsocket</option> which
+locks out the use of this expansion item in filter files.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${reduce{</emphasis><<emphasis>string1</emphasis>>}{<<emphasis>string2</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string3</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>reducing a list to a scalar</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>reducing to a scalar</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$value</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$item</varname></primary>
+</indexterm>
+This operation reduces a list to a single, scalar string. After expansion,
+<<emphasis>string1</emphasis>> is interpreted as a list, colon-separated by default, but the
+separator can be changed in the usual way (<xref linkend="SECTlistsepchange"/>).
+Then <<emphasis>string2</emphasis>> is expanded and
+assigned to the <varname>$value</varname> variable. After this, each item in the <<emphasis>string1</emphasis>>
+list is assigned to <varname>$item</varname>, in turn, and <<emphasis>string3</emphasis>> is expanded for each of
+them. The result of that expansion is assigned to <varname>$value</varname> before the next
+iteration. When the end of the list is reached, the final value of <varname>$value</varname> is
+added to the expansion output. The <option>reduce</option> expansion item can be used in a
+number of ways. For example, to add up a list of numbers:
+</para>
+<literallayout class="monospaced">
+${reduce {<, 1,2,3}{0}{${eval:$value+$item}}}
+</literallayout>
+<para>
+The result of that expansion would be <literal>6</literal>. The maximum of a list of numbers
+can be found:
+</para>
+<literallayout class="monospaced">
+${reduce {3:0:9:4:6}{0}{${if >{$item}{$value}{$item}{$value}}}}
+</literallayout>
+<para>
+At the end of a <emphasis role="bold">reduce</emphasis> expansion, the values of <varname>$item</varname> and <varname>$value</varname> are
+restored to what they were before. See also the <option>filter</option> and <option>map</option>
+expansion items.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">$rheader_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis> or <emphasis role="bold">$rh_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis></term>
+<listitem>
+<para>
+This item inserts <quote>raw</quote> header lines. It is described with the <option>header</option>
+expansion item in section <xref linkend="SECTexpansionitems"/> above.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${run{</emphasis><<emphasis>command</emphasis>><emphasis role="bold"> </emphasis><<emphasis>args</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>running a command</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>run</option> expansion item</primary>
+</indexterm>
+The command and its arguments are first expanded as one string. The string is
+split apart into individual arguments by spaces, and then the command is run
+in a separate process, but under the same uid and gid. As in other command
+executions from Exim, a shell is not used by default. If the command requires
+a shell, you must explicitly code it.
+</para>
+<para>
+Since the arguments are split by spaces, when there is a variable expansion
+which has an empty result, it will cause the situation that the argument will
+simply be omitted when the program is actually executed by Exim. If the
+script/program requires a specific number of arguments and the expanded
+variable could possibly result in this empty expansion, the variable must be
+quoted. This is more difficult if the expanded variable itself could result
+in a string containing quotes, because it would interfere with the quotes
+around the command arguments. A possible guard against this is to wrap the
+variable in the <option>sg</option> operator to change any quote marks to some other
+character.
+</para>
+<para>
+The standard input for the command exists, but is empty. The standard output
+and standard error are set to the same file descriptor.
+<indexterm role="concept">
+<primary>return code</primary>
+<secondary>from <option>run</option> expansion</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$value</varname></primary>
+</indexterm>
+If the command succeeds (gives a zero return code) <<emphasis>string1</emphasis>> is expanded
+and replaces the entire item; during this expansion, the standard output/error
+from the command is in the variable <varname>$value</varname>. If the command fails,
+<<emphasis>string2</emphasis>>, if present, is expanded and used. Once again, during the
+expansion, the standard output/error from the command is in the variable
+<varname>$value</varname>.
+</para>
+<para>
+If <<emphasis>string2</emphasis>> is absent, the result is empty. Alternatively, <<emphasis>string2</emphasis>>
+can be the word <quote>fail</quote> (not in braces) to force expansion failure if the
+command does not succeed. If both strings are omitted, the result is contents
+of the standard output/error on success, and nothing on failure.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$run_in_acl</varname></primary>
+</indexterm>
+The standard output/error of the command is put in the variable <varname>$value</varname>.
+In this ACL example, the output of a command is logged for the admin to
+troubleshoot:
+</para>
+<literallayout class="monospaced">
+warn condition = ${run{/usr/bin/id}{yes}{no}}
+ log_message = Output of id: $value
+</literallayout>
+<para>
+If the command requires shell idioms, such as the > redirect operator, the
+shell must be invoked directly, such as with:
+</para>
+<literallayout class="monospaced">
+${run{/bin/bash -c "/usr/bin/id >/tmp/id"}{yes}{yes}}
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$runrc</varname></primary>
+</indexterm>
+The return code from the command is put in the variable <varname>$runrc</varname>, and this
+remains set afterwards, so in a filter file you can do things like this:
+</para>
+<literallayout class="monospaced">
+if "${run{x y z}{}}$runrc" is 1 then ...
+ elif $runrc is 2 then ...
+ ...
+endif
+</literallayout>
+<para>
+If execution of the command fails (for example, the command does not exist),
+the return code is 127 – the same code that shells use for non-existent
+commands.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: In a router or transport, you cannot assume the order in which
+option values are expanded, except for those preconditions whose order of
+testing is documented. Therefore, you cannot reliably expect to set <varname>$runrc</varname>
+by the expansion of one option, and use it in another.
+</para>
+<para>
+The <command>redirect</command> router has an option called <option>forbid_filter_run</option> which locks
+out the use of this expansion item in filter files.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${sg{</emphasis><<emphasis>subject</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>regex</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>replacement</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>string substitution</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>sg</option> expansion item</primary>
+</indexterm>
+This item works like Perl’s substitution operator (s) with the global (/g)
+option; hence its name. However, unlike the Perl equivalent, Exim does not
+modify the subject string; instead it returns the modified string for insertion
+into the overall expansion. The item takes three arguments: the subject string,
+a regular expression, and a substitution string. For example:
+</para>
+<literallayout class="monospaced">
+${sg{abcdefabcdef}{abc}{xyz}}
+</literallayout>
+<para>
+yields <quote>xyzdefxyzdef</quote>. Because all three arguments are expanded before use,
+if any $, } or \ characters are required in the regular expression or in the
+substitution string, they have to be escaped. For example:
+</para>
+<literallayout class="monospaced">
+${sg{abcdef}{^(...)(...)\$}{\$2\$1}}
+</literallayout>
+<para>
+yields <quote>defabc</quote>, and
+</para>
+<literallayout class="monospaced">
+${sg{1=A 4=D 3=C}{\N(\d+)=\N}{K\$1=}}
+</literallayout>
+<para>
+yields <quote>K1=A K4=D K3=C</quote>. Note the use of <literal>\N</literal> to protect the contents of
+the regular expression from string expansion.
+</para>
+<para>
+The regular expression is compiled in 8-bit mode, working against bytes
+rather than any Unicode-aware character handling.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${sort{</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>comparator</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>extractor</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>sorting</primary>
+<secondary>a list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>sorting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>list sorting</secondary>
+</indexterm>
+After expansion, <<emphasis>string</emphasis>> is interpreted as a list, colon-separated by
+default, but the separator can be changed in the usual way (<xref linkend="SECTlistsepchange"/>).
+The <<emphasis>comparator</emphasis>> argument is interpreted as the operator
+of a two-argument expansion condition.
+The numeric operators plus ge, gt, le, lt (and ~i variants) are supported.
+The comparison should return true when applied to two values
+if the first value should sort before the second value.
+The <<emphasis>extractor</emphasis>> expansion is applied repeatedly to elements of the list,
+the element being placed in <varname>$item</varname>,
+to give values for comparison.
+</para>
+<para>
+The item result is a sorted list,
+with the original list separator,
+of the list elements (in full) of the original.
+</para>
+<para>
+Examples:
+</para>
+<literallayout class="monospaced">
+${sort{3:2:1:4}{<}{$item}}
+</literallayout>
+<para>
+sorts a list of numbers, and
+</para>
+<literallayout class="monospaced">
+${sort {${lookup dnsdb{>:,,mx=example.com}}} {<} {${listextract{1}{<,$item}}}}
+</literallayout>
+<para>
+will sort an MX lookup into priority order.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${substr{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string3</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>substr</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>substring extraction</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>substring extraction</secondary>
+</indexterm>
+The three strings are expanded; the first two must yield numbers. Call them
+<<emphasis>n</emphasis>> and <<emphasis>m</emphasis>>. If you are using fixed values for these numbers, that is,
+if <<emphasis>string1</emphasis>> and <<emphasis>string2</emphasis>> do not change when they are expanded, you
+can use the simpler operator notation that avoids some of the braces:
+</para>
+<literallayout class="monospaced">
+${substr_<n>_<m>:<string>}
+</literallayout>
+<para>
+The second number is optional (in both notations).
+If it is absent in the simpler format, the preceding underscore must also be
+omitted.
+</para>
+<para>
+The <option>substr</option> item can be used to extract more general substrings than
+<option>length</option>. The first number, <<emphasis>n</emphasis>>, is a starting offset, and <<emphasis>m</emphasis>> is the
+length required. For example
+</para>
+<literallayout class="monospaced">
+${substr{3}{2}{$local_part}}
+</literallayout>
+<para>
+If the starting offset is greater than the string length the result is the
+null string; if the length plus starting offset is greater than the string
+length, the result is the right-hand part of the string, starting from the
+given offset. The first byte (character) in the string has offset zero.
+</para>
+<para>
+The <option>substr</option> expansion item can take negative offset values to count
+from the right-hand end of its operand. The last byte (character) is offset -1,
+the second-last is offset -2, and so on. Thus, for example,
+</para>
+<literallayout class="monospaced">
+${substr{-5}{2}{1234567}}
+</literallayout>
+<para>
+yields <quote>34</quote>. If the absolute value of a negative offset is greater than the
+length of the string, the substring starts at the beginning of the string, and
+the length is reduced by the amount of overshoot. Thus, for example,
+</para>
+<literallayout class="monospaced">
+${substr{-5}{2}{12}}
+</literallayout>
+<para>
+yields an empty string, but
+</para>
+<literallayout class="monospaced">
+${substr{-3}{2}{12}}
+</literallayout>
+<para>
+yields <quote>1</quote>.
+</para>
+<para>
+When the second number is omitted from <option>substr</option>, the remainder of the string
+is taken if the offset is positive. If it is negative, all bytes (characters) in the
+string preceding the offset point are taken. For example, an offset of -1 and
+no length, as in these semantically identical examples:
+</para>
+<literallayout class="monospaced">
+${substr_-1:abcde}
+${substr{-1}{abcde}}
+</literallayout>
+<para>
+yields all but the last character of the string, that is, <quote>abcd</quote>.
+</para>
+<para>
+All measurement is done in bytes and is not UTF-8 aware.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${tr{</emphasis><<emphasis>subject</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>characters</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>replacements</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>character translation</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>tr</option> expansion item</primary>
+</indexterm>
+This item does single-character (in bytes) translation on its subject string. The second
+argument is a list of characters to be translated in the subject string. Each
+matching character is replaced by the corresponding character from the
+replacement list. For example
+</para>
+<literallayout class="monospaced">
+${tr{abcdea}{ac}{13}}
+</literallayout>
+<para>
+yields <literal>1b3de1</literal>. If there are duplicates in the second character string, the
+last occurrence is used. If the third string is shorter than the second, its
+last character is replicated. However, if it is empty, no translation takes
+place.
+</para>
+<para>
+All character handling is done in bytes and is not UTF-8 aware.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</section>
+<section id="SECTexpop">
+<title>Expansion operators</title>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>operators</secondary>
+</indexterm>
+For expansion items that perform transformations on a single argument string,
+the <quote>operator</quote> notation is used because it is simpler and uses fewer braces.
+The substring is first expanded before the operation is applied to it. The
+following operations can be performed:
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">${address:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>RFC 2822 address handling</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>address</option> expansion item</primary>
+</indexterm>
+The string is interpreted as an RFC 2822 address, as it might appear in a
+header line, and the effective address is extracted from it. If the string does
+not parse successfully, the result is empty.
+</para>
+<para>
+The parsing correctly handles SMTPUTF8 Unicode in the string.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${addresses:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>RFC 2822 address handling</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>addresses</option> expansion item</primary>
+</indexterm>
+The string (after expansion) is interpreted as a list of addresses in RFC
+2822 format, such as can be found in a <emphasis>To:</emphasis> or <emphasis>Cc:</emphasis> header line. The
+operative address (<emphasis>local-part@domain</emphasis>) is extracted from each item, and the
+result of the expansion is a colon-separated list, with appropriate
+doubling of colons should any happen to be present in the email addresses.
+Syntactically invalid RFC2822 address items are omitted from the output.
+</para>
+<para>
+It is possible to specify a character other than colon for the output
+separator by starting the string with > followed by the new separator
+character. For example:
+</para>
+<literallayout class="monospaced">
+${addresses:>& Chief <ceo@up.stairs>, sec@base.ment (dogsbody)}
+</literallayout>
+<para>
+expands to <literal>ceo@up.stairs&sec@base.ment</literal>. The string is expanded
+first, so if the expanded string starts with >, it may change the output
+separator unintentionally. This can be avoided by setting the output
+separator explicitly:
+</para>
+<literallayout class="monospaced">
+${addresses:>:$h_from:}
+</literallayout>
+<para>
+Compare the <option>address</option> (singular)
+expansion item, which extracts the working address from a single RFC2822
+address. See the <option>filter</option>, <option>map</option>, and <option>reduce</option> items for ways of
+processing lists.
+</para>
+<para>
+To clarify "list of addresses in RFC 2822 format" mentioned above, Exim follows
+a strict interpretation of header line formatting. Exim parses the bare,
+unquoted portion of an email address and if it finds a comma, treats it as an
+email address separator. For the example header line:
+</para>
+<literallayout class="monospaced">
+From: =?iso-8859-2?Q?Last=2C_First?= <user@example.com>
+</literallayout>
+<para>
+The first example below demonstrates that Q-encoded email addresses are parsed
+properly if it is given the raw header (in this example, <literal>$rheader_from:</literal>).
+It does not see the comma because it’s still encoded as "=2C". The second
+example below is passed the contents of <literal>$header_from:</literal>, meaning it gets
+de-mimed. Exim sees the decoded "," so it treats it as <emphasis role="bold">two</emphasis> email addresses.
+The third example shows that the presence of a comma is skipped when it is
+quoted. The fourth example shows SMTPUTF8 handling.
+</para>
+<literallayout class="monospaced">
+# exim -be '${addresses:From: \
+=?iso-8859-2?Q?Last=2C_First?= <user@example.com>}'
+user@example.com
+# exim -be '${addresses:From: Last, First <user@example.com>}'
+Last:user@example.com
+# exim -be '${addresses:From: "Last, First" <user@example.com>}'
+user@example.com
+# exim -be '${addresses:フィル <フィリップ@example.jp>}'
+フィリップ@example.jp
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${base32:</emphasis><<emphasis>digits</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>base32</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>conversion to base 32</secondary>
+</indexterm>
+The string must consist entirely of decimal digits. The number is converted to
+base 32 and output as a (empty, for zero) string of characters.
+Only lowercase letters are used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${base32d:</emphasis><<emphasis>base-32 digits</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>base32d</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>conversion to base 32</secondary>
+</indexterm>
+The string must consist entirely of base-32 digits.
+The number is converted to decimal and output as a string.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${base62:</emphasis><<emphasis>digits</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>base62</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>conversion to base 62</secondary>
+</indexterm>
+The string must consist entirely of decimal digits. The number is converted to
+base 62 and output as a string of six characters, including leading zeros. In
+the few operating environments where Exim uses base 36 instead of base 62 for
+its message identifiers (because those systems do not have case-sensitive
+filenames), base 36 is used by this operator, despite its name. <emphasis role="bold">Note</emphasis>: Just
+to be absolutely clear: this is <emphasis>not</emphasis> base64 encoding.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${base62d:</emphasis><<emphasis>base-62 digits</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>base62d</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>conversion to base 62</secondary>
+</indexterm>
+The string must consist entirely of base-62 digits, or, in operating
+environments where Exim uses base 36 instead of base 62 for its message
+identifiers, base-36 digits. The number is converted to decimal and output as a
+string.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${base64:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>base64 encoding</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>base64 encoding</primary>
+<secondary>in string expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>base64</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>base64 of DER</secondary>
+</indexterm>
+This operator converts a string into one that is base64 encoded.
+</para>
+<para>
+If the string is a single variable of type certificate,
+returns the base64 encoding of the DER form of the certificate.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${base64d:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>base64 decoding</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>base64 decoding</primary>
+<secondary>in string expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>base64d</option> expansion item</primary>
+</indexterm>
+This operator converts a base64-encoded string into the un-coded form.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${domain:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>domain</primary>
+<secondary>extraction</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>domain extraction</secondary>
+</indexterm>
+The string is interpreted as an RFC 2822 address and the domain is extracted
+from it. If the string does not parse successfully, the result is empty.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${escape:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>escaping non-printing characters</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>escape</option> expansion item</primary>
+</indexterm>
+If the string contains any non-printing characters, they are converted to
+escape sequences starting with a backslash. Whether characters with the most
+significant bit set (so-called <quote>8-bit characters</quote>) count as printing or not
+is controlled by the <option>print_topbitchars</option> option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${escape8bit:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>escaping 8-bit characters</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>escape8bit</option> expansion item</primary>
+</indexterm>
+If the string contains and characters with the most significant bit set,
+they are converted to escape sequences starting with a backslash.
+Backslashes and DEL characters are also converted.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${eval:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis> and <emphasis role="bold">${eval10:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>expression evaluation</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>arithmetic expression</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>eval</option> expansion item</primary>
+</indexterm>
+These items supports simple arithmetic and bitwise logical operations in
+expansion strings. The string (after expansion) must be a conventional
+arithmetic expression, but it is limited to basic arithmetic operators, bitwise
+logical operators, and parentheses. All operations are carried out using
+integer arithmetic. The operator priorities are as follows (the same as in the
+C programming language):
+</para>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="70pt" align="left"/>
+<colspec colwidth="300pt" align="left"/>
+<tbody>
+<row>
+<entry> <emphasis>highest:</emphasis></entry>
+<entry>not (~), negate (-)</entry>
+</row>
+<row>
+<entry> </entry>
+<entry>multiply (*), divide (/), remainder (%)</entry>
+</row>
+<row>
+<entry> </entry>
+<entry>plus (+), minus (-)</entry>
+</row>
+<row>
+<entry> </entry>
+<entry>shift-left (<<), shift-right (>>)</entry>
+</row>
+<row>
+<entry> </entry>
+<entry>and (&)</entry>
+</row>
+<row>
+<entry> </entry>
+<entry>xor (^)</entry>
+</row>
+<row>
+<entry> <emphasis>lowest:</emphasis></entry>
+<entry>or (|)</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Binary operators with the same priority are evaluated from left to right. White
+space is permitted before or after operators.
+</para>
+<para>
+For <option>eval</option>, numbers may be decimal, octal (starting with <quote>0</quote>) or
+hexadecimal (starting with <quote>0x</quote>). For <option>eval10</option>, all numbers are taken as
+decimal, even if they start with a leading zero; hexadecimal numbers are not
+permitted. This can be useful when processing numbers extracted from dates or
+times, which often do have leading zeros.
+</para>
+<para>
+A number may be followed by <quote>K</quote>, <quote>M</quote> or <quote>G</quote> to multiply it by 1024, 1024*1024
+or 1024*1024*1024,
+respectively. Negative numbers are supported. The result of the computation is
+a decimal representation of the answer (without <quote>K</quote>, <quote>M</quote> or <quote>G</quote>). For example:
+</para>
+<literallayout>
+<literal>${eval:1+1} </literal> yields 2
+<literal>${eval:1+2*3} </literal> yields 7
+<literal>${eval:(1+2)*3} </literal> yields 9
+<literal>${eval:2+42%5} </literal> yields 4
+<literal>${eval:0xc&5} </literal> yields 4
+<literal>${eval:0xc|5} </literal> yields 13
+<literal>${eval:0xc^5} </literal> yields 9
+<literal>${eval:0xc>>1} </literal> yields 6
+<literal>${eval:0xc<<1} </literal> yields 24
+<literal>${eval:~255&0x1234} </literal> yields 4608
+<literal>${eval:-(~255&0x1234)} </literal> yields -4608
+</literallayout>
+<para>
+As a more realistic example, in an ACL you might have
+</para>
+<literallayout class="monospaced">
+deny condition = \
+ ${if and { \
+ {>{$rcpt_count}{10}} \
+ { \
+ < \
+ {$recipients_count} \
+ {${eval:$rcpt_count/2}} \
+ } \
+ }{yes}{no}}
+ message = Too many bad recipients
+</literallayout>
+<para>
+The condition is true if there have been more than 10 RCPT commands and
+fewer than half of them have resulted in a valid recipient.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${expand:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>re-expansion of substring</secondary>
+</indexterm>
+The <option>expand</option> operator causes a string to be expanded for a second time. For
+example,
+</para>
+<literallayout class="monospaced">
+${expand:${lookup{$domain}dbm{/some/file}{$value}}}
+</literallayout>
+<para>
+first looks up a string in a file while expanding the operand for <option>expand</option>,
+and then re-expands what it has found.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${from_utf8:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>Unicode</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>UTF-8</primary>
+<secondary>conversion from</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>UTF-8 conversion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>from_utf8</option> expansion item</primary>
+</indexterm>
+The world is slowly moving towards Unicode, although there are no standards for
+email yet. However, other applications (including some databases) are starting
+to store data in Unicode, using UTF-8 encoding. This operator converts from a
+UTF-8 string to an ISO-8859-1 string. UTF-8 code values greater than 255 are
+converted to underscores. The input must be a valid UTF-8 string. If it is not,
+the result is an undefined sequence of bytes.
+</para>
+<para>
+Unicode code points with values less than 256 are compatible with ASCII and
+ISO-8859-1 (also known as Latin-1).
+For example, character 169 is the copyright symbol in both cases, though the
+way it is encoded is different. In UTF-8, more than one byte is needed for
+characters with code values greater than 127, whereas ISO-8859-1 is a
+single-byte encoding (but thereby limited to 256 characters). This makes
+translation from UTF-8 to ISO-8859-1 straightforward.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${hash_</emphasis><<emphasis>n</emphasis>><emphasis role="bold">_</emphasis><<emphasis>m</emphasis>><emphasis role="bold">:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>hash function</primary>
+<secondary>textual</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>textual hash</secondary>
+</indexterm>
+The <option>hash</option> operator is a simpler interface to the hashing function that can
+be used when the two parameters are fixed numbers (as opposed to strings that
+change when expanded). The effect is the same as
+</para>
+<literallayout class="monospaced">
+${hash{<n>}{<m>}{<string>}}
+</literallayout>
+<para>
+See the description of the general <option>hash</option> item above for details. The
+abbreviation <option>h</option> can be used when <option>hash</option> is used as an operator.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${hex2b64:</emphasis><<emphasis>hexstring</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>base64 encoding</primary>
+<secondary>conversion from hex</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>hex to base64</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>hex2b64</option> expansion item</primary>
+</indexterm>
+This operator converts a hex string into one that is base64 encoded. This can
+be useful for processing the output of the various hashing functions.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${hexquote:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>quoting</primary>
+<secondary>hex-encoded unprintable characters</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>hexquote</option> expansion item</primary>
+</indexterm>
+This operator converts non-printable characters in a string into a hex
+escape form. Byte values between 33 (!) and 126 (~) inclusive are left
+as is, and other byte values are converted to <literal>\xNN</literal>, for example, a
+byte value 127 is converted to <literal>\x7f</literal>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${ipv6denorm:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>ipv6denorm</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>IP address</primary>
+<secondary>normalisation</secondary>
+</indexterm>
+This expands an IPv6 address to a full eight-element colon-separated set
+of hex digits including leading zeroes.
+A trailing ipv4-style dotted-decimal set is converted to hex.
+Pure IPv4 addresses are converted to IPv4-mapped IPv6.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${ipv6norm:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>ipv6norm</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>IP address</primary>
+<secondary>normalisation</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>IP address</primary>
+<secondary>canonical form</secondary>
+</indexterm>
+This converts an IPv6 address to canonical form.
+Leading zeroes of groups are omitted, and the longest
+set of zero-valued groups is replaced with a double colon.
+A trailing ipv4-style dotted-decimal set is converted to hex.
+Pure IPv4 addresses are converted to IPv4-mapped IPv6.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${lc:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>case forcing in strings</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>string</primary>
+<secondary>case forcing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lower casing</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>case forcing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>lc</option> expansion item</primary>
+</indexterm>
+This forces the letters in the string into lower-case, for example:
+</para>
+<literallayout class="monospaced">
+${lc:$local_part}
+</literallayout>
+<para>
+Case is defined per the system C locale.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${length_</emphasis><<emphasis>number</emphasis>><emphasis role="bold">:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>string truncation</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>length</option> expansion item</primary>
+</indexterm>
+The <option>length</option> operator is a simpler interface to the <option>length</option> function that
+can be used when the parameter is a fixed number (as opposed to a string that
+changes when expanded). The effect is the same as
+</para>
+<literallayout class="monospaced">
+${length{<number>}{<string>}}
+</literallayout>
+<para>
+See the description of the general <option>length</option> item above for details. Note that
+<option>length</option> is not the same as <option>strlen</option>. The abbreviation <option>l</option> can be used
+when <option>length</option> is used as an operator.
+All measurement is done in bytes and is not UTF-8 aware.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${listcount:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>list item count</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>item count</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>count of items</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>listcount</option> expansion item</primary>
+</indexterm>
+The string is interpreted as a list and the number of items is returned.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${listnamed:</emphasis><<emphasis>name</emphasis>><emphasis role="bold">}</emphasis> and <emphasis role="bold">${listnamed_</emphasis><<emphasis>type</emphasis>><emphasis role="bold">:</emphasis><<emphasis>name</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>named list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>listnamed</option> expansion item</primary>
+</indexterm>
+The name is interpreted as a named list and the content of the list is returned,
+expanding any referenced lists, re-quoting as needed for colon-separation.
+If the optional type is given it must be one of "a", "d", "h" or "l"
+and selects address-, domain-, host- or localpart- lists to search among respectively.
+Otherwise all types are searched in an undefined order and the first
+matching list is returned.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${local_part:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>local part extraction</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>local_part</option> expansion item</primary>
+</indexterm>
+The string is interpreted as an RFC 2822 address and the local part is
+extracted from it. If the string does not parse successfully, the result is
+empty.
+The parsing correctly handles SMTPUTF8 Unicode in the string.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${mask:</emphasis><<emphasis>IP address</emphasis>><emphasis role="bold">/</emphasis><<emphasis>bit count</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>masked IP address</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>IP address</primary>
+<secondary>masking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>CIDR notation</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>IP address masking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>mask</option> expansion item</primary>
+</indexterm>
+If the form of the string to be operated on is not an IP address followed by a
+slash and an integer (that is, a network address in CIDR notation), the
+expansion fails. Otherwise, this operator converts the IP address to binary,
+masks off the least significant bits according to the bit count, and converts
+the result back to text, with mask appended. For example,
+</para>
+<literallayout class="monospaced">
+${mask:10.111.131.206/28}
+</literallayout>
+<para>
+returns the string <quote>10.111.131.192/28</quote>. Since this operation is expected to
+be mostly used for looking up masked addresses in files, the result for an IPv6
+address uses dots to separate components instead of colons, because colon
+terminates a key string in lsearch files. So, for example,
+</para>
+<literallayout class="monospaced">
+${mask:3ffe:ffff:836f:0a00:000a:0800:200a:c031/99}
+</literallayout>
+<para>
+returns the string
+</para>
+<literallayout class="monospaced">
+3ffe.ffff.836f.0a00.000a.0800.2000.0000/99
+</literallayout>
+<para>
+Letters in IPv6 addresses are always output in lower case.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${md5:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>MD5 hash</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>MD5 hash</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>fingerprint</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>md5</option> expansion item</primary>
+</indexterm>
+The <option>md5</option> operator computes the MD5 hash value of the string, and returns it
+as a 32-digit hexadecimal number, in which any letters are in lower case.
+</para>
+<para>
+If the string is a single variable of type certificate,
+returns the MD5 hash fingerprint of the certificate.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${nhash_</emphasis><<emphasis>n</emphasis>><emphasis role="bold">_</emphasis><<emphasis>m</emphasis>><emphasis role="bold">:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>numeric hash</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>hash function</primary>
+<secondary>numeric</secondary>
+</indexterm>
+The <option>nhash</option> operator is a simpler interface to the numeric hashing function
+that can be used when the two parameters are fixed numbers (as opposed to
+strings that change when expanded). The effect is the same as
+</para>
+<literallayout class="monospaced">
+${nhash{<n>}{<m>}{<string>}}
+</literallayout>
+<para>
+See the description of the general <option>nhash</option> item above for details.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${quote:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>quoting</primary>
+<secondary>in string expansions</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>quoting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>quote</option> expansion item</primary>
+</indexterm>
+The <option>quote</option> operator puts its argument into double quotes if it
+is an empty string or
+contains anything other than letters, digits, underscores, dots, and hyphens.
+Any occurrences of double quotes and backslashes are escaped with a backslash.
+Newlines and carriage returns are converted to <literal>\n</literal> and <literal>\r</literal>,
+respectively For example,
+</para>
+<literallayout class="monospaced">
+${quote:ab"*"cd}
+</literallayout>
+<para>
+becomes
+</para>
+<literallayout class="monospaced">
+"ab\"*\"cd"
+</literallayout>
+<para>
+The place where this is useful is when the argument is a substitution from a
+variable or a message header.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${quote_local_part:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>quote_local_part</option> expansion item</primary>
+</indexterm>
+This operator is like <option>quote</option>, except that it quotes the string only if
+required to do so by the rules of RFC 2822 for quoting local parts. For
+example, a plus sign would not cause quoting (but it would for <option>quote</option>).
+If you are creating a new email address from the contents of <varname>$local_part</varname>
+(or any other unknown data), you should always use this operator.
+</para>
+<para>
+This quoting determination is not SMTPUTF8-aware, thus quoting non-ASCII data
+will likely use the quoting form.
+Thus <emphasis>${quote_local_part:フィル}</emphasis> will always become <emphasis>"フィル"</emphasis>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${quote_</emphasis><<emphasis>lookup-type</emphasis>><emphasis role="bold">:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>quoting</primary>
+<secondary>lookup-specific</secondary>
+</indexterm>
+This operator applies lookup-specific quoting rules to the string. Each
+query-style lookup type has its own quoting rules which are described with
+the lookups in chapter <xref linkend="CHAPfdlookup"/>. For example,
+</para>
+<literallayout class="monospaced">
+${quote_ldap:two * two}
+</literallayout>
+<para>
+returns
+</para>
+<literallayout class="monospaced">
+two%20%5C2A%20two
+</literallayout>
+<para>
+For single-key lookup types, no quoting is ever necessary and this operator
+yields an unchanged string.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${randint:</emphasis><<emphasis>n</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>random number</primary>
+</indexterm>
+This operator returns a somewhat random number which is less than the
+supplied number and is at least 0. The quality of this randomness depends
+on how Exim was built; the values are not suitable for keying material.
+If Exim is linked against OpenSSL then RAND_pseudo_bytes() is used.
+If Exim is linked against GnuTLS then gnutls_rnd(GNUTLS_RND_NONCE) is used,
+for versions of GnuTLS with that function.
+Otherwise, the implementation may be arc4random(), random() seeded by
+srandomdev() or srandom(), or a custom implementation even weaker than
+random().
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${reverse_ip:</emphasis><<emphasis>ipaddr</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>IP address</secondary>
+</indexterm>
+This operator reverses an IP address; for IPv4 addresses, the result is in
+dotted-quad decimal form, while for IPv6 addresses the result is in
+dotted-nibble hexadecimal form. In both cases, this is the "natural" form
+for DNS. For example,
+</para>
+<literallayout class="monospaced">
+${reverse_ip:192.0.2.4}
+${reverse_ip:2001:0db8:c42:9:1:abcd:192.0.2.127}
+</literallayout>
+<para>
+returns
+</para>
+<literallayout class="monospaced">
+4.2.0.192
+f.7.2.0.0.0.0.c.d.c.b.a.1.0.0.0.9.0.0.0.2.4.c.0.8.b.d.0.1.0.0.2
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${rfc2047:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>RFC 2047</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>RFC 2047</primary>
+<secondary>expansion operator</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>rfc2047</option> expansion item</primary>
+</indexterm>
+This operator encodes text according to the rules of RFC 2047. This is an
+encoding that is used in header lines to encode non-ASCII characters. It is
+assumed that the input string is in the encoding specified by the
+<option>headers_charset</option> option, which gets its default at build time. If the string
+contains only characters in the range 33–126, and no instances of the
+characters
+</para>
+<literallayout class="monospaced">
+? = ( ) < > @ , ; : \ " . [ ] _
+</literallayout>
+<para>
+it is not modified. Otherwise, the result is the RFC 2047 encoding of the
+string, using as many <quote>encoded words</quote> as necessary to encode all the
+characters.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${rfc2047d:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>RFC 2047</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>RFC 2047</primary>
+<secondary>decoding</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>rfc2047d</option> expansion item</primary>
+</indexterm>
+This operator decodes strings that are encoded as per RFC 2047. Binary zero
+bytes are replaced by question marks. Characters are converted into the
+character set defined by <option>headers_charset</option>. Overlong RFC 2047 <quote>words</quote> are
+not recognized unless <option>check_rfc2047_length</option> is set false.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: If you use <option>$header</option>_<emphasis>xxx</emphasis><emphasis role="bold">:</emphasis> (or <option>$h</option>_<emphasis>xxx</emphasis><emphasis role="bold">:</emphasis>) to
+access a header line, RFC 2047 decoding is done automatically. You do not need
+to use this operator as well.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${rxquote:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>quoting</primary>
+<secondary>in regular expressions</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>regular expressions</primary>
+<secondary>quoting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>rxquote</option> expansion item</primary>
+</indexterm>
+The <option>rxquote</option> operator inserts a backslash before any non-alphanumeric
+characters in its argument. This is useful when substituting the values of
+variables or headers inside regular expressions.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${sha1:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>SHA-1 hash</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>SHA-1 hashing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>fingerprint</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>sha1</option> expansion item</primary>
+</indexterm>
+The <option>sha1</option> operator computes the SHA-1 hash value of the string, and returns
+it as a 40-digit hexadecimal number, in which any letters are in upper case.
+</para>
+<para>
+If the string is a single variable of type certificate,
+returns the SHA-1 hash fingerprint of the certificate.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${sha256:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">${sha2:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">${sha2_<n>:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>SHA-256 hash</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SHA-2 hash</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>fingerprint</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>SHA-256 hashing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>sha256</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>sha2</option> expansion item</primary>
+</indexterm>
+The <option>sha256</option> operator computes the SHA-256 hash value of the string
+and returns
+it as a 64-digit hexadecimal number, in which any letters are in upper case.
+</para>
+<para>
+If the string is a single variable of type certificate,
+returns the SHA-256 hash fingerprint of the certificate.
+</para>
+<para>
+The operator can also be spelled <option>sha2</option> and does the same as <option>sha256</option>
+(except for certificates, which are not supported).
+Finally, if an underbar
+and a number is appended it specifies the output length, selecting a
+member of the SHA-2 family of hash functions.
+Values of 256, 384 and 512 are accepted, with 256 being the default.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${sha3:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">${sha3_<n>:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>SHA3 hash</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>SHA3 hashing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>sha3</option> expansion item</primary>
+</indexterm>
+The <option>sha3</option> operator computes the SHA3-256 hash value of the string
+and returns
+it as a 64-digit hexadecimal number, in which any letters are in upper case.
+</para>
+<para>
+If a number is appended, separated by an underbar, it specifies
+the output length. Values of 224, 256, 384 and 512 are accepted;
+with 256 being the default.
+</para>
+<para>
+The <option>sha3</option> expansion item is only supported if Exim has been
+compiled with GnuTLS 3.5.0 or later,
+or OpenSSL 1.1.1 or later.
+The macro "_CRYPTO_HASH_SHA3" will be defined if it is supported.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${stat:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>statting a file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>extracting characteristics</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>stat</option> expansion item</primary>
+</indexterm>
+The string, after expansion, must be a file path. A call to the <function>stat()</function>
+function is made for this path. If <function>stat()</function> fails, an error occurs and the
+expansion fails. If it succeeds, the data from the stat replaces the item, as a
+series of <<emphasis>name</emphasis>>=<<emphasis>value</emphasis>> pairs, where the values are all numerical,
+except for the value of <quote>smode</quote>. The names are: <quote>mode</quote> (giving the mode as
+a 4-digit octal number), <quote>smode</quote> (giving the mode in symbolic format as a
+10-character string, as for the <emphasis>ls</emphasis> command), <quote>inode</quote>, <quote>device</quote>,
+<quote>links</quote>, <quote>uid</quote>, <quote>gid</quote>, <quote>size</quote>, <quote>atime</quote>, <quote>mtime</quote>, and <quote>ctime</quote>. You
+can extract individual fields using the <option>extract</option> expansion item.
+</para>
+<para>
+The use of the <option>stat</option> expansion in users’ filter files can be locked out by
+the system administrator. <emphasis role="bold">Warning</emphasis>: The file size may be incorrect on 32-bit
+systems for files larger than 2GB.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${str2b64:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>str2b64</option> expansion item</primary>
+</indexterm>
+Now deprecated, a synonym for the <option>base64</option> expansion operator.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${strlen:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>string length</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>string</primary>
+<secondary>length in expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>strlen</option> expansion item</primary>
+</indexterm>
+The item is replace by the length of the expanded string, expressed as a
+decimal number. <emphasis role="bold">Note</emphasis>: Do not confuse <option>strlen</option> with <option>length</option>.
+All measurement is done in bytes and is not UTF-8 aware.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${substr_</emphasis><<emphasis>start</emphasis>><emphasis role="bold">_</emphasis><<emphasis>length</emphasis>><emphasis role="bold">:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>substr</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>substring extraction</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>substring expansion</secondary>
+</indexterm>
+The <option>substr</option> operator is a simpler interface to the <option>substr</option> function that
+can be used when the two parameters are fixed numbers (as opposed to strings
+that change when expanded). The effect is the same as
+</para>
+<literallayout class="monospaced">
+${substr{<start>}{<length>}{<string>}}
+</literallayout>
+<para>
+See the description of the general <option>substr</option> item above for details. The
+abbreviation <option>s</option> can be used when <option>substr</option> is used as an operator.
+All measurement is done in bytes and is not UTF-8 aware.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${time_eval:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>time_eval</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>time interval</primary>
+<secondary>decoding</secondary>
+</indexterm>
+This item converts an Exim time interval such as <literal>2d4h5m</literal> into a number of
+seconds.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${time_interval:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>time_interval</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>time interval</primary>
+<secondary>formatting</secondary>
+</indexterm>
+The argument (after sub-expansion) must be a sequence of decimal digits that
+represents an interval of time as a number of seconds. It is converted into a
+number of larger units and output in Exim’s normal time format, for example,
+<literal>1w3d4h2m6s</literal>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${uc:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>case forcing in strings</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>string</primary>
+<secondary>case forcing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>upper casing</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>case forcing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>uc</option> expansion item</primary>
+</indexterm>
+This forces the letters in the string into upper-case.
+Case is defined per the system C locale.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${utf8clean:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>correction of invalid utf-8 sequences in strings</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>utf-8</primary>
+<secondary>utf-8 sequences</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>incorrect utf-8</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>utf-8 forcing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>utf8clean</option> expansion item</primary>
+</indexterm>
+This replaces any invalid utf-8 sequence in the string by the character <literal>?</literal>.
+In versions of Exim before 4.92, this did not correctly do so for a truncated
+final codepoint’s encoding, and the character would be silently dropped.
+If you must handle detection of this scenario across both sets of Exim behavior,
+the complexity will depend upon the task.
+For instance, to detect if the first character is multibyte and a 1-byte
+extraction can be successfully used as a path component (as is common for
+dividing up delivery folders), you might use:
+</para>
+<literallayout class="monospaced">
+condition = ${if inlist{${utf8clean:${length_1:$local_part}}}{:?}{yes}{no}}
+</literallayout>
+<para>
+(which will false-positive if the first character of the local part is a
+literal question mark).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">${utf8_domain_to_alabel:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">${utf8_domain_from_alabel:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">${utf8_localpart_to_alabel:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">${utf8_localpart_from_alabel:</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>UTF-8</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>UTF-8</primary>
+<secondary>expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>EAI</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>internationalisation</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>utf8_domain_to_alabel</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>utf8_domain_from_alabel</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>utf8_localpart_to_alabel</option> expansion item</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>utf8_localpart_from_alabel</option> expansion item</primary>
+</indexterm>
+These convert EAI mail name components between UTF-8 and a-label forms.
+For information on internationalisation support see <xref linkend="SECTi18nMTA"/>.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</section>
+<section id="SECTexpcond">
+<title>Expansion conditions</title>
+<para>
+<indexterm role="concept" id="IIDexpcond" class="startofrange">
+<primary>expansion</primary>
+<secondary>conditions</secondary>
+</indexterm>
+The following conditions are available for testing by the <option>${if</option> construct
+while expanding strings:
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">!</emphasis><<emphasis>condition</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>negating a condition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>negation</primary>
+<secondary>in expansion condition</secondary>
+</indexterm>
+Preceding any condition with an exclamation mark negates the result of the
+condition.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><<emphasis>symbolic operator</emphasis>> <emphasis role="bold">{</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>numeric comparison</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>numeric comparison</secondary>
+</indexterm>
+There are a number of symbolic operators for doing numeric comparisons. They
+are:
+</para>
+<literallayout>
+<literal>= </literal> equal
+<literal>== </literal> equal
+<literal>> </literal> greater
+<literal>>= </literal> greater or equal
+<literal>< </literal> less
+<literal><= </literal> less or equal
+</literallayout>
+<para>
+For example:
+</para>
+<literallayout class="monospaced">
+${if >{$message_size}{10M} ...
+</literallayout>
+<para>
+Note that the general negation operator provides for inequality testing. The
+two strings must take the form of optionally signed decimal integers,
+optionally followed by one of the letters <quote>K</quote>, <quote>M</quote> or <quote>G</quote> (in either upper or
+lower case), signifying multiplication by 1024, 1024*1024 or 1024*1024*1024, respectively.
+As a special case, the numerical value of an empty string is taken as
+zero.
+</para>
+<para>
+In all cases, a relative comparator OP is testing if <<emphasis>string1</emphasis>> OP
+<<emphasis>string2</emphasis>>; the above example is checking if <varname>$message_size</varname> is larger than
+10M, not if 10M is larger than <varname>$message_size</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">acl {{</emphasis><<emphasis>name</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>arg1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>arg2</emphasis>><emphasis role="bold">}...}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>calling an acl</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>acl</option></primary>
+<secondary>expansion condition</secondary>
+</indexterm>
+The name and zero to nine argument strings are first expanded separately. The expanded
+arguments are assigned to the variables <varname>$acl_arg1</varname> to <varname>$acl_arg9</varname> in order.
+Any unused are made empty. The variable <varname>$acl_narg</varname> is set to the number of
+arguments. The named ACL (see chapter <xref linkend="CHAPACL"/>) is called
+and may use the variables; if another acl expansion is used the values
+are restored after it returns. If the ACL sets
+a value using a "message =" modifier the variable $value becomes
+the result of the expansion, otherwise it is empty.
+If the ACL returns accept the condition is true; if deny, false.
+If the ACL returns defer the result is a forced-fail.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">bool {</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>boolean parsing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>bool</option> expansion condition</primary>
+</indexterm>
+This condition turns a string holding a true or false representation into
+a boolean state. It parses <quote>true</quote>, <quote>false</quote>, <quote>yes</quote> and <quote>no</quote>
+(case-insensitively); also integer numbers map to true if non-zero,
+false if zero.
+An empty string is treated as false.
+Leading and trailing whitespace is ignored;
+thus a string consisting only of whitespace is false.
+All other string values will result in expansion failure.
+</para>
+<para>
+When combined with ACL variables, this expansion condition will let you
+make decisions in one place and act on those decisions in another place.
+For example:
+</para>
+<literallayout class="monospaced">
+${if bool{$acl_m_privileged_sender} ...
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">bool_lax {</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>boolean parsing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>bool_lax</option> expansion condition</primary>
+</indexterm>
+Like <option>bool</option>, this condition turns a string into a boolean state. But
+where <option>bool</option> accepts a strict set of strings, <option>bool_lax</option> uses the same
+loose definition that the Router <option>condition</option> option uses. The empty string
+and the values <quote>false</quote>, <quote>no</quote> and <quote>0</quote> map to false, all others map to
+true. Leading and trailing whitespace is ignored.
+</para>
+<para>
+Note that where <quote>bool{00}</quote> is false, <quote>bool_lax{00}</quote> is true.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">crypteq {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>encrypted comparison</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>encrypted strings, comparing</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>crypteq</option> expansion condition</primary>
+</indexterm>
+This condition is included in the Exim binary if it is built to support any
+authentication mechanisms (see chapter <xref linkend="CHAPSMTPAUTH"/>). Otherwise, it is
+necessary to define SUPPORT_CRYPTEQ in <filename>Local/Makefile</filename> to get <option>crypteq</option>
+included in the binary.
+</para>
+<para>
+The <option>crypteq</option> condition has two arguments. The first is encrypted and
+compared against the second, which is already encrypted. The second string may
+be in the LDAP form for storing encrypted strings, which starts with the
+encryption type in curly brackets, followed by the data. If the second string
+does not begin with <quote>{</quote> it is assumed to be encrypted with <function>crypt()</function> or
+<function>crypt16()</function> (see below), since such strings cannot begin with <quote>{</quote>.
+Typically this will be a field from a password file. An example of an encrypted
+string in LDAP form is:
+</para>
+<literallayout class="monospaced">
+{md5}CY9rzUYh03PK3k6DJie09g==
+</literallayout>
+<para>
+If such a string appears directly in an expansion, the curly brackets have to
+be quoted, because they are part of the expansion syntax. For example:
+</para>
+<literallayout class="monospaced">
+${if crypteq {test}{\{md5\}CY9rzUYh03PK3k6DJie09g==}{yes}{no}}
+</literallayout>
+<para>
+The following encryption types (whose names are matched case-independently) are
+supported:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>MD5 hash</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>base64 encoding</primary>
+<secondary>in encrypted password</secondary>
+</indexterm>
+<option>{md5}</option> computes the MD5 digest of the first string, and expresses this as
+printable characters to compare with the remainder of the second string. If the
+length of the comparison string is 24, Exim assumes that it is base64 encoded
+(as in the above example). If the length is 32, Exim assumes that it is a
+hexadecimal encoding of the MD5 digest. If the length not 24 or 32, the
+comparison fails.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>SHA-1 hash</primary>
+</indexterm>
+<option>{sha1}</option> computes the SHA-1 digest of the first string, and expresses this as
+printable characters to compare with the remainder of the second string. If the
+length of the comparison string is 28, Exim assumes that it is base64 encoded.
+If the length is 40, Exim assumes that it is a hexadecimal encoding of the
+SHA-1 digest. If the length is not 28 or 40, the comparison fails.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><function>crypt()</function></primary>
+</indexterm>
+<option>{crypt}</option> calls the <function>crypt()</function> function, which traditionally used to use
+only the first eight characters of the password. However, in modern operating
+systems this is no longer true, and in many cases the entire password is used,
+whatever its length.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><function>crypt16()</function></primary>
+</indexterm>
+<option>{crypt16}</option> calls the <function>crypt16()</function> function, which was originally created to
+use up to 16 characters of the password in some operating systems. Again, in
+modern operating systems, more characters may be used.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Exim has its own version of <function>crypt16()</function>, which is just a double call to
+<function>crypt()</function>. For operating systems that have their own version, setting
+HAVE_CRYPT16 in <filename>Local/Makefile</filename> when building Exim causes it to use the
+operating system version instead of its own. This option is set by default in
+the OS-dependent <filename>Makefile</filename> for those operating systems that are known to
+support <function>crypt16()</function>.
+</para>
+<para>
+Some years after Exim’s <function>crypt16()</function> was implemented, a user discovered that
+it was not using the same algorithm as some operating systems’ versions. It
+turns out that as well as <function>crypt16()</function> there is a function called
+<function>bigcrypt()</function> in some operating systems. This may or may not use the same
+algorithm, and both of them may be different to Exim’s built-in <function>crypt16()</function>.
+</para>
+<para>
+However, since there is now a move away from the traditional <function>crypt()</function>
+functions towards using SHA1 and other algorithms, tidying up this area of
+Exim is seen as very low priority.
+</para>
+<para>
+If you do not put a encryption type (in curly brackets) in a <option>crypteq</option>
+comparison, the default is usually either <literal>{crypt}</literal> or <literal>{crypt16}</literal>, as
+determined by the setting of DEFAULT_CRYPT in <filename>Local/Makefile</filename>. The default
+default is <literal>{crypt}</literal>. Whatever the default, you can always use either
+function by specifying it explicitly in curly brackets.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">def:</emphasis><<emphasis>variable name</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>checking for empty variable</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>def</option> expansion condition</primary>
+</indexterm>
+The <option>def</option> condition must be followed by the name of one of the expansion
+variables defined in section <xref linkend="SECTexpvar"/>. The condition is true if the
+variable does not contain the empty string. For example:
+</para>
+<literallayout class="monospaced">
+${if def:sender_ident {from $sender_ident}}
+</literallayout>
+<para>
+Note that the variable name is given without a leading <option>$</option> character. If the
+variable does not exist, the expansion fails.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">def:header_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis> or <emphasis role="bold">def:h_</emphasis><<emphasis>header name</emphasis>><emphasis role="bold">:</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>checking header line existence</secondary>
+</indexterm>
+This condition is true if a message is being processed and the named header
+exists in the message. For example,
+</para>
+<literallayout class="monospaced">
+${if def:header_reply-to:{$h_reply-to:}{$h_from:}}
+</literallayout>
+<para>
+<emphasis role="bold">Note</emphasis>: No <option>$</option> appears before <option>header_</option> or <option>h_</option> in the condition, and
+the header name must be terminated by a colon if white space does not follow.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">eq {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">eqi {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>string</primary>
+<secondary>comparison</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>string comparison</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>eq</option> expansion condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>eqi</option> expansion condition</primary>
+</indexterm>
+The two substrings are first expanded. The condition is true if the two
+resulting strings are identical. For <option>eq</option> the comparison includes the case of
+letters, whereas for <option>eqi</option> the comparison is case-independent, where
+case is defined per the system C locale.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">exists {</emphasis><<emphasis>file name</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>file existence test</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>existence test</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>exists</option>, expansion condition</primary>
+</indexterm>
+The substring is first expanded and then interpreted as an absolute path. The
+condition is true if the named file (or directory) exists. The existence test
+is done by calling the <function>stat()</function> function. The use of the <option>exists</option> test in
+users’ filter files may be locked out by the system administrator.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">first_delivery</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>first</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>first delivery</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>first delivery test</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>first_delivery</option> expansion condition</primary>
+</indexterm>
+This condition, which has no data, is true during a message’s first delivery
+attempt. It is false during any subsequent delivery attempts.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">forall{</emphasis><<emphasis>a list</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>a condition</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">forany{</emphasis><<emphasis>a list</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>a condition</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>iterative conditions</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary><emphasis role="bold">forall</emphasis> condition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary><emphasis role="bold">forany</emphasis> condition</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$item</varname></primary>
+</indexterm>
+These conditions iterate over a list. The first argument is expanded to form
+the list. By default, the list separator is a colon, but it can be changed by
+the normal method (<xref linkend="SECTlistsepchange"/>).
+The second argument is interpreted as a condition that is to
+be applied to each item in the list in turn. During the interpretation of the
+condition, the current list item is placed in a variable called <varname>$item</varname>.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+For <emphasis role="bold">forany</emphasis>, interpretation stops if the condition is true for any item, and
+the result of the whole condition is true. If the condition is false for all
+items in the list, the overall condition is false.
+</para>
+</listitem>
+<listitem>
+<para>
+For <emphasis role="bold">forall</emphasis>, interpretation stops if the condition is false for any item,
+and the result of the whole condition is false. If the condition is true for
+all items in the list, the overall condition is true.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Note that negation of <emphasis role="bold">forany</emphasis> means that the condition must be false for all
+items for the overall condition to succeed, and negation of <emphasis role="bold">forall</emphasis> means
+that the condition must be false for at least one item. In this example, the
+list separator is changed to a comma:
+</para>
+<literallayout class="monospaced">
+${if forany{<, $recipients}{match{$item}{^user3@}}{yes}{no}}
+</literallayout>
+<para>
+The value of <varname>$item</varname> is saved and restored while <option>forany</option> or <option>forall</option> is
+being processed, to enable these expansion items to be nested.
+</para>
+<para>
+To scan a named list, expand it with the <emphasis role="bold">listnamed</emphasis> operator.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">forall_json{</emphasis><<emphasis>a JSON array</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>a condition</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">forany_json{</emphasis><<emphasis>a JSON array</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>a condition</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">forall_jsons{</emphasis><<emphasis>a JSON array</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>a condition</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">forany_jsons{</emphasis><<emphasis>a JSON array</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>a condition</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>JSON</primary>
+<secondary>iterative conditions</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>JSON</primary>
+<secondary>expansions</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary><emphasis role="bold">forall_json</emphasis> condition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary><emphasis role="bold">forany_json</emphasis> condition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary><emphasis role="bold">forall_jsons</emphasis> condition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary><emphasis role="bold">forany_jsons</emphasis> condition</secondary>
+</indexterm>
+As for the above, except that the first argument must, after expansion,
+be a JSON array.
+The array separator is not changeable.
+For the <quote>jsons</quote> variants the elements are expected to be JSON strings
+and have their quotes removed before the evaluation of the condition.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">ge {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">gei {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>string</primary>
+<secondary>comparison</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>string comparison</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>ge</option> expansion condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>gei</option> expansion condition</primary>
+</indexterm>
+The two substrings are first expanded. The condition is true if the first
+string is lexically greater than or equal to the second string. For <option>ge</option> the
+comparison includes the case of letters, whereas for <option>gei</option> the comparison is
+case-independent.
+Case and collation order are defined per the system C locale.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">gt {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">gti {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>string</primary>
+<secondary>comparison</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>string comparison</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>gt</option> expansion condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>gti</option> expansion condition</primary>
+</indexterm>
+The two substrings are first expanded. The condition is true if the first
+string is lexically greater than the second string. For <option>gt</option> the comparison
+includes the case of letters, whereas for <option>gti</option> the comparison is
+case-independent.
+Case and collation order are defined per the system C locale.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">inlist {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">inlisti {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>string</primary>
+<secondary>comparison</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>list</primary>
+<secondary>iterative conditions</secondary>
+</indexterm>
+Both strings are expanded; the second string is treated as a list of simple
+strings; if the first string is a member of the second, then the condition
+is true.
+For the case-independent <option>inlisti</option> condition, case is defined per the system C locale.
+</para>
+<para>
+These are simpler to use versions of the more powerful <emphasis role="bold">forany</emphasis> condition.
+Examples, and the <emphasis role="bold">forany</emphasis> equivalents:
+</para>
+<literallayout class="monospaced">
+${if inlist{needle}{foo:needle:bar}}
+ ${if forany{foo:needle:bar}{eq{$item}{needle}}}
+${if inlisti{Needle}{fOo:NeeDLE:bAr}}
+ ${if forany{fOo:NeeDLE:bAr}{eqi{$item}{Needle}}}
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">isip {</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">isip4 {</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">isip6 {</emphasis><<emphasis>string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>IP address</primary>
+<secondary>testing string format</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>string</primary>
+<secondary>testing for IP address</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>isip</option> expansion condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>isip4</option> expansion condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>isip6</option> expansion condition</primary>
+</indexterm>
+The substring is first expanded, and then tested to see if it has the form of
+an IP address. Both IPv4 and IPv6 addresses are valid for <option>isip</option>, whereas
+<option>isip4</option> and <option>isip6</option> test specifically for IPv4 or IPv6 addresses.
+</para>
+<para>
+For an IPv4 address, the test is for four dot-separated components, each of
+which consists of from one to three digits. For an IPv6 address, up to eight
+colon-separated components are permitted, each containing from one to four
+hexadecimal digits. There may be fewer than eight components if an empty
+component (adjacent colons) is present. Only one empty component is permitted.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: The checks used to be just on the form of the address; actual numerical
+values were not considered. Thus, for example, 999.999.999.999 passed the IPv4
+check.
+This is no longer the case.
+</para>
+<para>
+The main use of these tests is to distinguish between IP addresses and
+host names, or between IPv4 and IPv6 addresses. For example, you could use
+</para>
+<literallayout class="monospaced">
+${if isip4{$sender_host_address}...
+</literallayout>
+<para>
+to test which IP version an incoming SMTP connection is using.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">ldapauth {</emphasis><<emphasis>ldap query</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>use for authentication</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>LDAP authentication test</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>ldapauth</option> expansion condition</primary>
+</indexterm>
+This condition supports user authentication using LDAP. See section
+<xref linkend="SECTldap"/> for details of how to use LDAP in lookups and the syntax of
+queries. For this use, the query must contain a user name and password. The
+query itself is not used, and can be empty. The condition is true if the
+password is not empty, and the user name and password are accepted by the LDAP
+server. An empty password is rejected without calling LDAP because LDAP binds
+with an empty password are considered anonymous regardless of the username, and
+will succeed in most configurations. See chapter <xref linkend="CHAPSMTPAUTH"/> for details
+of SMTP authentication, and chapter <xref linkend="CHAPplaintext"/> for an example of how
+this can be used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">le {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">lei {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>string</primary>
+<secondary>comparison</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>string comparison</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>le</option> expansion condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>lei</option> expansion condition</primary>
+</indexterm>
+The two substrings are first expanded. The condition is true if the first
+string is lexically less than or equal to the second string. For <option>le</option> the
+comparison includes the case of letters, whereas for <option>lei</option> the comparison is
+case-independent.
+Case and collation order are defined per the system C locale.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">lt {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<term><emphasis role="bold">lti {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>string</primary>
+<secondary>comparison</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>string comparison</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>lt</option> expansion condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>lti</option> expansion condition</primary>
+</indexterm>
+The two substrings are first expanded. The condition is true if the first
+string is lexically less than the second string. For <option>lt</option> the comparison
+includes the case of letters, whereas for <option>lti</option> the comparison is
+case-independent.
+Case and collation order are defined per the system C locale.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">match {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>regular expression comparison</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>regular expressions</primary>
+<secondary>match in expanded string</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>match</option> expansion condition</primary>
+</indexterm>
+The two substrings are first expanded. The second is then treated as a regular
+expression and applied to the first. Because of the pre-expansion, if the
+regular expression contains dollar, or backslash characters, they must be
+escaped. Care must also be taken if the regular expression contains braces
+(curly brackets). A closing brace must be escaped so that it is not taken as a
+premature termination of <<emphasis>string2</emphasis>>. The easiest approach is to use the
+<literal>\N</literal> feature to disable expansion of the regular expression.
+For example,
+</para>
+<literallayout class="monospaced">
+${if match {$local_part}{\N^\d{3}\N} ...
+</literallayout>
+<para>
+If the whole expansion string is in double quotes, further escaping of
+backslashes is also required.
+</para>
+<para>
+The condition is true if the regular expression match succeeds.
+The regular expression is not required to begin with a circumflex
+metacharacter, but if there is no circumflex, the expression is not anchored,
+and it may match anywhere in the subject, not just at the start. If you want
+the pattern to match at the end of the subject, you must include the <literal>$</literal>
+metacharacter at an appropriate point.
+All character handling is done in bytes and is not UTF-8 aware,
+but we might change this in a future Exim release.
+</para>
+<para>
+<indexterm role="concept">
+<primary>numerical variables (<varname>$1</varname> <varname>$2</varname> etc)</primary>
+<secondary>in <option>if</option> expansion</secondary>
+</indexterm>
+At the start of an <option>if</option> expansion the values of the numeric variable
+substitutions <varname>$1</varname> etc. are remembered. Obeying a <option>match</option> condition that
+succeeds causes them to be reset to the substrings of that condition and they
+will have these values during the expansion of the success string. At the end
+of the <option>if</option> expansion, the previous values are restored. After testing a
+combination of conditions using <option>or</option>, the subsequent values of the numeric
+variables are those of the condition that succeeded.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">match_address {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>match_address</option> expansion condition</primary>
+</indexterm>
+See <emphasis role="bold">match_local_part</emphasis>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">match_domain {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>match_domain</option> expansion condition</primary>
+</indexterm>
+See <emphasis role="bold">match_local_part</emphasis>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">match_ip {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>match_ip</option> expansion condition</primary>
+</indexterm>
+This condition matches an IP address to a list of IP address patterns. It must
+be followed by two argument strings. The first (after expansion) must be an IP
+address or an empty string. The second (not expanded) is a restricted host
+list that can match only an IP address, not a host name. For example:
+</para>
+<literallayout class="monospaced">
+${if match_ip{$sender_host_address}{1.2.3.4:5.6.7.8}{...}{...}}
+</literallayout>
+<para>
+The specific types of host list item that are permitted in the list are:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+An IP address, optionally with a CIDR mask.
+</para>
+</listitem>
+<listitem>
+<para>
+A single asterisk, which matches any IP address.
+</para>
+</listitem>
+<listitem>
+<para>
+An empty item, which matches only if the IP address is empty. This could be
+useful for testing for a locally submitted message or one from specific hosts
+in a single test such as
+</para>
+<literallayout class="monospaced">
+ ${if match_ip{$sender_host_address}{:4.3.2.1:...}{...}{...}}
+</literallayout>
+<para>
+where the first item in the list is the empty string.
+</para>
+</listitem>
+<listitem>
+<para>
+The item @[] matches any of the local host’s interface addresses.
+</para>
+</listitem>
+<listitem>
+<para>
+Single-key lookups are assumed to be like <quote>net-</quote> style lookups in host lists,
+even if <literal>net-</literal> is not specified. There is never any attempt to turn the IP
+address into a host name. The most common type of linear search for
+<emphasis role="bold">match_ip</emphasis> is likely to be <emphasis role="bold">iplsearch</emphasis>, in which the file can contain CIDR
+masks. For example:
+</para>
+<literallayout class="monospaced">
+ ${if match_ip{$sender_host_address}{iplsearch;/some/file}...
+</literallayout>
+<para>
+It is of course possible to use other kinds of lookup, and in such a case, you
+do need to specify the <literal>net-</literal> prefix if you want to specify a specific
+address mask, for example:
+</para>
+<literallayout class="monospaced">
+ ${if match_ip{$sender_host_address}{net24-dbm;/some/file}...
+</literallayout>
+<para>
+However, unless you are combining a <option>match_ip</option> condition with others, it is
+just as easy to use the fact that a lookup is itself a condition, and write:
+</para>
+<literallayout class="monospaced">
+ ${lookup{${mask:$sender_host_address/24}}dbm{/a/file}...
+</literallayout>
+</listitem>
+</itemizedlist>
+<para>
+Note that <<emphasis>string2</emphasis>> is not itself subject to string expansion, unless
+Exim was built with the EXPAND_LISTMATCH_RHS option.
+</para>
+<para>
+Consult section <xref linkend="SECThoslispatip"/> for further details of these patterns.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">match_local_part {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>domain list</primary>
+<secondary>in expansion condition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address list</primary>
+<secondary>in expansion condition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>list, in expansion condition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>match_local_part</option> expansion condition</primary>
+</indexterm>
+This condition, together with <option>match_address</option> and <option>match_domain</option>, make it
+possible to test domain, address, and local part lists within expansions. Each
+condition requires two arguments: an item and a list to match. A trivial
+example is:
+</para>
+<literallayout class="monospaced">
+${if match_domain{a.b.c}{x.y.z:a.b.c:p.q.r}{yes}{no}}
+</literallayout>
+<para>
+In each case, the second argument may contain any of the allowable items for a
+list of the appropriate type. Also, because the second argument
+is a standard form of list, it is possible to refer to a named list.
+Thus, you can use conditions like this:
+</para>
+<literallayout class="monospaced">
+${if match_domain{$domain}{+local_domains}{...
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary><literal>+caseful</literal></primary>
+</indexterm>
+For address lists, the matching starts off caselessly, but the <literal>+caseful</literal>
+item can be used, as in all address lists, to cause subsequent items to
+have their local parts matched casefully. Domains are always matched
+caselessly.
+</para>
+<para>
+Note that <<emphasis>string2</emphasis>> is not itself subject to string expansion, unless
+Exim was built with the EXPAND_LISTMATCH_RHS option.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: Host lists are <emphasis>not</emphasis> supported in this way. This is because
+hosts have two identities: a name and an IP address, and it is not clear
+how to specify cleanly how such a test would work. However, IP addresses can be
+matched using <option>match_ip</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">pam {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">:</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">:...}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>PAM authentication</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>with PAM</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Solaris</primary>
+<secondary>PAM support</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>PAM authentication test</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>pam</option> expansion condition</primary>
+</indexterm>
+<emphasis>Pluggable Authentication Modules</emphasis>
+(<emphasis role="bold"><ulink url="https://mirrors.edge.kernel.org/pub/linux/libs/pam/">https://mirrors.edge.kernel.org/pub/linux/libs/pam/</ulink></emphasis>) are a facility that is
+available in the latest releases of Solaris and in some GNU/Linux
+distributions. The Exim support, which is intended for use in conjunction with
+the SMTP AUTH command, is available only if Exim is compiled with
+</para>
+<literallayout class="monospaced">
+SUPPORT_PAM=yes
+</literallayout>
+<para>
+in <filename>Local/Makefile</filename>. You probably need to add <option>-lpam</option> to EXTRALIBS, and
+in some releases of GNU/Linux <option>-ldl</option> is also needed.
+</para>
+<para>
+The argument string is first expanded, and the result must be a
+colon-separated list of strings. Leading and trailing white space is ignored.
+The PAM module is initialized with the service name <quote>exim</quote> and the user name
+taken from the first item in the colon-separated data string (<<emphasis>string1</emphasis>>).
+The remaining items in the data string are passed over in response to requests
+from the authentication function. In the simple case there will only be one
+request, for a password, so the data consists of just two strings.
+</para>
+<para>
+There can be problems if any of the strings are permitted to contain colon
+characters. In the usual way, these have to be doubled to avoid being taken as
+separators. If the data is being inserted from a variable, the <option>sg</option> expansion
+item can be used to double any existing colons. For example, the configuration
+of a LOGIN authenticator might contain this setting:
+</para>
+<literallayout class="monospaced">
+server_condition = ${if pam{$auth1:${sg{$auth2}{:}{::}}}}
+</literallayout>
+<para>
+For a PLAIN authenticator you could use:
+</para>
+<literallayout class="monospaced">
+server_condition = ${if pam{$auth2:${sg{$auth3}{:}{::}}}}
+</literallayout>
+<para>
+In some operating systems, PAM authentication can be done only from a process
+running as root. Since Exim is running as the Exim user when receiving
+messages, this means that PAM cannot be used directly in those systems.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">pwcheck {</emphasis><<emphasis>string1</emphasis>><emphasis role="bold">:</emphasis><<emphasis>string2</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><emphasis>pwcheck</emphasis> daemon</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Cyrus</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary><emphasis>pwcheck</emphasis> authentication test</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>pwcheck</option> expansion condition</primary>
+</indexterm>
+This condition supports user authentication using the Cyrus <emphasis>pwcheck</emphasis> daemon.
+This is one way of making it possible for passwords to be checked by a process
+that is not running as root. <emphasis role="bold">Note</emphasis>: The use of <emphasis>pwcheck</emphasis> is now
+deprecated. Its replacement is <emphasis>saslauthd</emphasis> (see below).
+</para>
+<para>
+The pwcheck support is not included in Exim by default. You need to specify
+the location of the pwcheck daemon’s socket in <filename>Local/Makefile</filename> before
+building Exim. For example:
+</para>
+<literallayout class="monospaced">
+CYRUS_PWCHECK_SOCKET=/var/pwcheck/pwcheck
+</literallayout>
+<para>
+You do not need to install the full Cyrus software suite in order to use
+the pwcheck daemon. You can compile and install just the daemon alone
+from the Cyrus SASL library. Ensure that <emphasis>exim</emphasis> is the only user that has
+access to the <filename>/var/pwcheck</filename> directory.
+</para>
+<para>
+The <option>pwcheck</option> condition takes one argument, which must be the user name and
+password, separated by a colon. For example, in a LOGIN authenticator
+configuration, you might have this:
+</para>
+<literallayout class="monospaced">
+server_condition = ${if pwcheck{$auth1:$auth2}}
+</literallayout>
+<para>
+Again, for a PLAIN authenticator configuration, this would be:
+</para>
+<literallayout class="monospaced">
+server_condition = ${if pwcheck{$auth2:$auth3}}
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">queue_running</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>queue runner</primary>
+<secondary>detecting when delivering from</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>queue runner test</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>queue_running</option> expansion condition</primary>
+</indexterm>
+This condition, which has no data, is true during delivery attempts that are
+initiated by queue runner processes, and false otherwise.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">radius {</emphasis><<emphasis>authentication string</emphasis>><emphasis role="bold">}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>Radius</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>Radius authentication</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>radius</option> expansion condition</primary>
+</indexterm>
+Radius authentication (RFC 2865) is supported in a similar way to PAM. You must
+set RADIUS_CONFIG_FILE in <filename>Local/Makefile</filename> to specify the location of
+the Radius client configuration file in order to build Exim with Radius
+support.
+</para>
+<para>
+With just that one setting, Exim expects to be linked with the <option>radiusclient</option>
+library, using the original API. If you are using release 0.4.0 or later of
+this library, you need to set
+</para>
+<literallayout class="monospaced">
+RADIUS_LIB_TYPE=RADIUSCLIENTNEW
+</literallayout>
+<para>
+in <filename>Local/Makefile</filename> when building Exim. You can also link Exim with the
+<option>libradius</option> library that comes with FreeBSD. To do this, set
+</para>
+<literallayout class="monospaced">
+RADIUS_LIB_TYPE=RADLIB
+</literallayout>
+<para>
+in <filename>Local/Makefile</filename>, in addition to setting RADIUS_CONFIGURE_FILE.
+You may also have to supply a suitable setting in EXTRALIBS so that the
+Radius library can be found when Exim is linked.
+</para>
+<para>
+The string specified by RADIUS_CONFIG_FILE is expanded and passed to the
+Radius client library, which calls the Radius server. The condition is true if
+the authentication is successful. For example:
+</para>
+<literallayout class="monospaced">
+server_condition = ${if radius{<arguments>}}
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">saslauthd {{</emphasis><<emphasis>user</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>password</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>service</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>realm</emphasis>><emphasis role="bold">}}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><emphasis>saslauthd</emphasis> daemon</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Cyrus</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary><emphasis>saslauthd</emphasis> authentication test</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>saslauthd</option> expansion condition</primary>
+</indexterm>
+This condition supports user authentication using the Cyrus <emphasis>saslauthd</emphasis>
+daemon. This replaces the older <emphasis>pwcheck</emphasis> daemon, which is now deprecated.
+Using this daemon is one way of making it possible for passwords to be checked
+by a process that is not running as root.
+</para>
+<para>
+The saslauthd support is not included in Exim by default. You need to specify
+the location of the saslauthd daemon’s socket in <filename>Local/Makefile</filename> before
+building Exim. For example:
+</para>
+<literallayout class="monospaced">
+CYRUS_SASLAUTHD_SOCKET=/var/state/saslauthd/mux
+</literallayout>
+<para>
+You do not need to install the full Cyrus software suite in order to use
+the saslauthd daemon. You can compile and install just the daemon alone
+from the Cyrus SASL library.
+</para>
+<para>
+Up to four arguments can be supplied to the <option>saslauthd</option> condition, but only
+two are mandatory. For example:
+</para>
+<literallayout class="monospaced">
+server_condition = ${if saslauthd{{$auth1}{$auth2}}}
+</literallayout>
+<para>
+The service and the realm are optional (which is why the arguments are enclosed
+in their own set of braces). For details of the meaning of the service and
+realm, and how to run the daemon, consult the Cyrus documentation.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</section>
+<section id="SECID84">
+<title>Combining expansion conditions</title>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>combining conditions</secondary>
+</indexterm>
+Several conditions can be tested at once by combining them using the <option>and</option>
+and <option>or</option> combination conditions. Note that <option>and</option> and <option>or</option> are complete
+conditions on their own, and precede their lists of sub-conditions. Each
+sub-condition must be enclosed in braces within the overall braces that contain
+the list. No repetition of <option>if</option> is used.
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">or {{</emphasis><<emphasis>cond1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>cond2</emphasis>><emphasis role="bold">}...}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><quote>or</quote> expansion condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary><quote>or</quote> of conditions</secondary>
+</indexterm>
+The sub-conditions are evaluated from left to right. The condition is true if
+any one of the sub-conditions is true.
+For example,
+</para>
+<literallayout class="monospaced">
+${if or {{eq{$local_part}{spqr}}{eq{$domain}{testing.com}}}...
+</literallayout>
+<para>
+When a true sub-condition is found, the following ones are parsed but not
+evaluated. If there are several <quote>match</quote> sub-conditions the values of the
+numeric variables afterwards are taken from the first one that succeeds.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">and {{</emphasis><<emphasis>cond1</emphasis>><emphasis role="bold">}{</emphasis><<emphasis>cond2</emphasis>><emphasis role="bold">}...}</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><quote>and</quote> expansion condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary><quote>and</quote> of conditions</secondary>
+</indexterm>
+The sub-conditions are evaluated from left to right. The condition is true if
+all of the sub-conditions are true. If there are several <quote>match</quote>
+sub-conditions, the values of the numeric variables afterwards are taken from
+the last one. When a false sub-condition is found, the following ones are
+parsed but not evaluated.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+<indexterm role="concept" startref="IIDexpcond" class="endofrange"/>
+</para>
+</section>
+<section id="SECTexpvar">
+<title>Expansion variables</title>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>variables, list of</secondary>
+</indexterm>
+This section contains an alphabetical list of all the expansion variables. Some
+of them are available only when Exim is compiled with specific options such as
+support for TLS or the content scanning extension.
+</para>
+<variablelist>
+<varlistentry>
+<term><varname>$0</varname>, <varname>$1</varname>, etc</term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>numerical variables (<varname>$1</varname> <varname>$2</varname> etc)</primary>
+</indexterm>
+When a <option>match</option> expansion condition succeeds, these variables contain the
+captured substrings identified by the regular expression during subsequent
+processing of the success string of the containing <option>if</option> expansion item.
+In the expansion condition case
+they do not retain their values afterwards; in fact, their previous
+values are restored at the end of processing an <option>if</option> item. The numerical
+variables may also be set externally by some other matching process which
+precedes the expansion of the string. For example, the commands available in
+Exim filter files include an <option>if</option> command with its own regular expression
+matching condition.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$acl_arg1</varname>, <varname>$acl_arg2</varname>, etc</term>
+<listitem>
+<para>
+Within an acl condition, expansion condition or expansion item
+any arguments are copied to these variables,
+any unused variables being made empty.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$acl_c...</varname></term>
+<listitem>
+<para>
+Values can be placed in these variables by the <option>set</option> modifier in an ACL. They
+can be given any name that starts with <varname>$acl_c</varname> and is at least six characters
+long, but the sixth character must be either a digit or an underscore. For
+example: <varname>$acl_c5</varname>, <varname>$acl_c_mycount</varname>. The values of the <varname>$acl_c...</varname>
+variables persist throughout the lifetime of an SMTP connection. They can be
+used to pass information between ACLs and between different invocations of the
+same ACL. When a message is received, the values of these variables are saved
+with the message, and can be accessed by filters, routers, and transports
+during subsequent delivery.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$acl_m...</varname></term>
+<listitem>
+<para>
+These variables are like the <varname>$acl_c...</varname> variables, except that their values
+are reset after a message has been received. Thus, if several messages are
+received in one SMTP connection, <varname>$acl_m...</varname> values are not passed on from one
+message to the next, as <varname>$acl_c...</varname> values are. The <varname>$acl_m...</varname> variables are
+also reset by MAIL, RSET, EHLO, HELO, and after starting a TLS session. When a
+message is received, the values of these variables are saved with the message,
+and can be accessed by filters, routers, and transports during subsequent
+delivery.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$acl_narg</varname></term>
+<listitem>
+<para>
+Within an acl condition, expansion condition or expansion item
+this variable has the number of arguments.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$acl_verify_message</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$acl_verify_message</varname></primary>
+</indexterm>
+After an address verification has failed, this variable contains the failure
+message. It retains its value for use in subsequent modifiers. The message can
+be preserved by coding like this:
+</para>
+<literallayout class="monospaced">
+warn !verify = sender
+ set acl_m0 = $acl_verify_message
+</literallayout>
+<para>
+You can use <varname>$acl_verify_message</varname> during the expansion of the <option>message</option> or
+<option>log_message</option> modifiers, to include information about the verification
+failure.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$address_data</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$address_data</varname></primary>
+</indexterm>
+This variable is set by means of the <option>address_data</option> option in routers. The
+value then remains with the address while it is processed by subsequent routers
+and eventually a transport. If the transport is handling multiple addresses,
+the value from the first address is used. See chapter <xref linkend="CHAProutergeneric"/>
+for more details. <emphasis role="bold">Note</emphasis>: The contents of <varname>$address_data</varname> are visible in
+user filter files.
+</para>
+<para>
+If <varname>$address_data</varname> is set when the routers are called from an ACL to verify
+a recipient address, the final value is still in the variable for subsequent
+conditions and modifiers of the ACL statement. If routing the address caused it
+to be redirected to just one address, the child address is also routed as part
+of the verification, and in this case the final value of <varname>$address_data</varname> is
+from the child’s routing.
+</para>
+<para>
+If <varname>$address_data</varname> is set when the routers are called from an ACL to verify a
+sender address, the final value is also preserved, but this time in
+<varname>$sender_address_data</varname>, to distinguish it from data from a recipient
+address.
+</para>
+<para>
+In both cases (recipient and sender verification), the value does not persist
+after the end of the current ACL statement. If you want to preserve
+these values for longer, you can save them in ACL variables.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$address_file</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$address_file</varname></primary>
+</indexterm>
+When, as a result of aliasing, forwarding, or filtering, a message is directed
+to a specific file, this variable holds the name of the file when the transport
+is running. At other times, the variable is empty. For example, using the
+default configuration, if user <option>r2d2</option> has a <filename>.forward</filename> file containing
+</para>
+<literallayout class="monospaced">
+/home/r2d2/savemail
+</literallayout>
+<para>
+then when the <command>address_file</command> transport is running, <varname>$address_file</varname>
+contains the text string <literal>/home/r2d2/savemail</literal>.
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary>value of <varname>$address_file</varname></secondary>
+</indexterm>
+For Sieve filters, the value may be <quote>inbox</quote> or a relative folder name. It is
+then up to the transport configuration to generate an appropriate absolute path
+to the relevant file.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$address_pipe</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$address_pipe</varname></primary>
+</indexterm>
+When, as a result of aliasing or forwarding, a message is directed to a pipe,
+this variable holds the pipe command when the transport is running.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$auth1</varname> – <varname>$auth3</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$auth1</varname>, <varname>$auth2</varname>, etc</primary>
+</indexterm>
+These variables are used in SMTP authenticators (see chapters
+<xref linkend="CHAPplaintext"/>–<xref linkend="CHAPtlsauth"/>). Elsewhere, they are empty.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$authenticated_id</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>id</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$authenticated_id</varname></primary>
+</indexterm>
+When a server successfully authenticates a client it may be configured to
+preserve some of the authentication information in the variable
+<varname>$authenticated_id</varname> (see chapter <xref linkend="CHAPSMTPAUTH"/>). For example, a
+user/password authenticator configuration might preserve the user name for use
+in the routers. Note that this is not the same information that is saved in
+<varname>$sender_host_authenticated</varname>.
+</para>
+<para>
+When a message is submitted locally (that is, not over a TCP connection)
+the value of <varname>$authenticated_id</varname> is normally the login name of the calling
+process. However, a trusted user can override this by means of the <option>-oMai</option>
+command line option.
+This second case also sets up information used by the
+<varname>$authresults</varname> expansion item.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$authenticated_fail_id</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>fail</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$authenticated_fail_id</varname></primary>
+</indexterm>
+When an authentication attempt fails, the variable <varname>$authenticated_fail_id</varname>
+will contain the failed authentication id. If more than one authentication
+id is attempted, it will contain only the last one. The variable is
+available for processing in the ACL’s, generally the quit or notquit ACL.
+A message to a local recipient could still be accepted without requiring
+authentication, which means this variable could also be visible in all of
+the ACL’s as well.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$authenticated_sender</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>authenticated</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>sender</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>on MAIL command</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$authenticated_sender</varname></primary>
+</indexterm>
+When acting as a server, Exim takes note of the AUTH= parameter on an incoming
+SMTP MAIL command if it believes the sender is sufficiently trusted, as
+described in section <xref linkend="SECTauthparamail"/>. Unless the data is the string
+<quote><></quote>, it is set as the authenticated sender of the message, and the value is
+available during delivery in the <varname>$authenticated_sender</varname> variable. If the
+sender is not trusted, Exim accepts the syntax of AUTH=, but ignores the data.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$qualify_domain</varname></primary>
+</indexterm>
+When a message is submitted locally (that is, not over a TCP connection), the
+value of <varname>$authenticated_sender</varname> is an address constructed from the login
+name of the calling process and <varname>$qualify_domain</varname>, except that a trusted user
+can override this by means of the <option>-oMas</option> command line option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$authentication_failed</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>failure</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$authentication_failed</varname></primary>
+</indexterm>
+This variable is set to <quote>1</quote> in an Exim server if a client issues an AUTH
+command that does not succeed. Otherwise it is set to <quote>0</quote>. This makes it
+possible to distinguish between <quote>did not try to authenticate</quote>
+(<varname>$sender_host_authenticated</varname> is empty and <varname>$authentication_failed</varname> is set to
+<quote>0</quote>) and <quote>tried to authenticate but failed</quote> (<varname>$sender_host_authenticated</varname>
+is empty and <varname>$authentication_failed</varname> is set to <quote>1</quote>). Failure includes any
+negative response to an AUTH command, including (for example) an attempt to use
+an undefined mechanism.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$av_failed</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>content scanning</primary>
+<secondary>AV scanner failure</secondary>
+</indexterm>
+This variable is available when Exim is compiled with the content-scanning
+extension. It is set to <quote>0</quote> by default, but will be set to <quote>1</quote> if any
+problem occurs with the virus scanner (specified by <option>av_scanner</option>) during
+the ACL malware condition.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$body_linecount</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>message body</primary>
+<secondary>line count</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>body of message</primary>
+<secondary>line count</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$body_linecount</varname></primary>
+</indexterm>
+When a message is being received or delivered, this variable contains the
+number of lines in the message’s body. See also <varname>$message_linecount</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$body_zerocount</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>message body</primary>
+<secondary>binary zero count</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>body of message</primary>
+<secondary>binary zero count</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>binary zero</primary>
+<secondary>in message body</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$body_zerocount</varname></primary>
+</indexterm>
+When a message is being received or delivered, this variable contains the
+number of binary zero bytes (ASCII NULs) in the message’s body.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$bounce_recipient</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$bounce_recipient</varname></primary>
+</indexterm>
+This is set to the recipient address of a bounce message while Exim is creating
+it. It is useful if a customized bounce message text file is in use (see
+chapter <xref linkend="CHAPemsgcust"/>).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$bounce_return_size_limit</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$bounce_return_size_limit</varname></primary>
+</indexterm>
+This contains the value set in the <option>bounce_return_size_limit</option> option, rounded
+up to a multiple of 1000. It is useful when a customized error message text
+file is in use (see chapter <xref linkend="CHAPemsgcust"/>).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$caller_gid</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>gid (group id)</primary>
+<secondary>caller</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$caller_gid</varname></primary>
+</indexterm>
+The real group id under which the process that called Exim was running. This is
+not the same as the group id of the originator of a message (see
+<varname>$originator_gid</varname>). If Exim re-execs itself, this variable in the new
+incarnation normally contains the Exim gid.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$caller_uid</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>uid (user id)</primary>
+<secondary>caller</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$caller_uid</varname></primary>
+</indexterm>
+The real user id under which the process that called Exim was running. This is
+not the same as the user id of the originator of a message (see
+<varname>$originator_uid</varname>). If Exim re-execs itself, this variable in the new
+incarnation normally contains the Exim uid.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$callout_address</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$callout_address</varname></primary>
+</indexterm>
+After a callout for verification, spamd or malware daemon service, the
+address that was connected to.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$compile_number</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$compile_number</varname></primary>
+</indexterm>
+The building process for Exim keeps a count of the number
+of times it has been compiled. This serves to distinguish different
+compilations of the same version of Exim.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$config_dir</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$config_dir</varname></primary>
+</indexterm>
+The directory name of the main configuration file. That is, the content of
+<varname>$config_file</varname> with the last component stripped. The value does not
+contain the trailing slash. If <varname>$config_file</varname> does not contain a slash,
+<varname>$config_dir</varname> is ".".
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$config_file</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$config_file</varname></primary>
+</indexterm>
+The name of the main configuration file Exim is using.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$dkim_verify_status</varname></term>
+<listitem>
+<para>
+Results of DKIM verification.
+For details see section <xref linkend="SECDKIMVFY"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$dkim_cur_signer</varname></term>
+<term><varname>$dkim_verify_reason</varname></term>
+<term><varname>$dkim_domain</varname></term>
+<term><varname>$dkim_identity</varname></term>
+<term><varname>$dkim_selector</varname></term>
+<term><varname>$dkim_algo</varname></term>
+<term><varname>$dkim_canon_body</varname></term>
+<term><varname>$dkim_canon_headers</varname></term>
+<term><varname>$dkim_copiedheaders</varname></term>
+<term><varname>$dkim_bodylength</varname></term>
+<term><varname>$dkim_created</varname></term>
+<term><varname>$dkim_expires</varname></term>
+<term><varname>$dkim_headernames</varname></term>
+<term><varname>$dkim_key_testing</varname></term>
+<term><varname>$dkim_key_nosubdomains</varname></term>
+<term><varname>$dkim_key_srvtype</varname></term>
+<term><varname>$dkim_key_granularity</varname></term>
+<term><varname>$dkim_key_notes</varname></term>
+<term><varname>$dkim_key_length</varname></term>
+<listitem>
+<para>
+These variables are only available within the DKIM ACL.
+For details see section <xref linkend="SECDKIMVFY"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$dkim_signers</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$dkim_signers</varname></primary>
+</indexterm>
+When a message has been received this variable contains
+a colon-separated list of signer domains and identities for the message.
+For details see section <xref linkend="SECDKIMVFY"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$dmarc_domain_policy</varname></term>
+<term><varname>$dmarc_status</varname></term>
+<term><varname>$dmarc_status_text</varname></term>
+<term><varname>$dmarc_used_domains</varname></term>
+<listitem>
+<para>
+Results of DMARC verification.
+For details see section <xref linkend="SECDMARC"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$dnslist_domain</varname></term>
+<term><varname>$dnslist_matched</varname></term>
+<term><varname>$dnslist_text</varname></term>
+<term><varname>$dnslist_value</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$dnslist_domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$dnslist_matched</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$dnslist_text</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$dnslist_value</varname></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>black list (DNS)</primary>
+</indexterm>
+When a DNS (black) list lookup succeeds, these variables are set to contain
+the following data from the lookup: the list’s domain name, the key that was
+looked up, the contents of any associated TXT record, and the value from the
+main A record. See section <xref linkend="SECID204"/> for more details.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$domain</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+When an address is being routed, or delivered on its own, this variable
+contains the domain. Uppercase letters in the domain are converted into lower
+case for <varname>$domain</varname>.
+</para>
+<para>
+Global address rewriting happens when a message is received, so the value of
+<varname>$domain</varname> during routing and delivery is the value after rewriting. <varname>$domain</varname>
+is set during user filtering, but not during system filtering, because a
+message may have many recipients and the system filter is called just once.
+</para>
+<para>
+When more than one address is being delivered at once (for example, several
+RCPT commands in one SMTP delivery), <varname>$domain</varname> is set only if they all
+have the same domain. Transports can be restricted to handling only one domain
+at a time if the value of <varname>$domain</varname> is required at transport time – this is
+the default for local transports. For further details of the environment in
+which local transports are run, see chapter <xref linkend="CHAPenvironment"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>delay_warning_condition</option></primary>
+</indexterm>
+At the end of a delivery, if all deferred addresses have the same domain, it is
+set in <varname>$domain</varname> during the expansion of <option>delay_warning_condition</option>.
+</para>
+<para>
+The <varname>$domain</varname> variable is also used in some other circumstances:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+When an ACL is running for a RCPT command, <varname>$domain</varname> contains the domain of
+the recipient address. The domain of the <emphasis>sender</emphasis> address is in
+<varname>$sender_address_domain</varname> at both MAIL time and at RCPT time. <varname>$domain</varname> is not
+normally set during the running of the MAIL ACL. However, if the sender address
+is verified with a callout during the MAIL ACL, the sender domain is placed in
+<varname>$domain</varname> during the expansions of <option>hosts</option>, <option>interface</option>, and <option>port</option> in
+the <command>smtp</command> transport.
+</para>
+</listitem>
+<listitem>
+<para>
+When a rewrite item is being processed (see chapter <xref linkend="CHAPrewrite"/>),
+<varname>$domain</varname> contains the domain portion of the address that is being rewritten;
+it can be used in the expansion of the replacement address, for example, to
+rewrite domains by file lookup.
+</para>
+</listitem>
+<listitem>
+<para>
+With one important exception, whenever a domain list is being scanned,
+<varname>$domain</varname> contains the subject domain. <emphasis role="bold">Exception</emphasis>: When a domain list in
+a <option>sender_domains</option> condition in an ACL is being processed, the subject domain
+is in <varname>$sender_address_domain</varname> and not in <varname>$domain</varname>. It works this way so
+that, in a RCPT ACL, the sender domain list can be dependent on the
+recipient domain (which is what is in <varname>$domain</varname> at this time).
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>ETRN</primary>
+<secondary>value of <varname>$domain</varname></secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>smtp_etrn_command</option></primary>
+</indexterm>
+When the <option>smtp_etrn_command</option> option is being expanded, <varname>$domain</varname> contains
+the complete argument of the ETRN command (see section <xref linkend="SECTETRN"/>).
+</para>
+</listitem>
+</itemizedlist>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>tainted data</primary>
+</indexterm>
+If the origin of the data is an incoming message,
+the result of expanding this variable is tainted.
+When un untainted version is needed, one should be obtained from
+looking up the value in a local (therefore trusted) database.
+Often <varname>$domain_data</varname> is usable in this role.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$domain_data</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain_data</varname></primary>
+</indexterm>
+When the <option>domains</option> option on a router matches a domain by
+means of a lookup, the data read by the lookup is available during the running
+of the router as <varname>$domain_data</varname>. In addition, if the driver routes the
+address to a transport, the value is available in that transport. If the
+transport is handling multiple addresses, the value from the first address is
+used.
+</para>
+<para>
+<varname>$domain_data</varname> is also set when the <option>domains</option> condition in an ACL matches a
+domain by means of a lookup. The data read by the lookup is available during
+the rest of the ACL statement. In all other situations, this variable expands
+to nothing.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$exim_gid</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$exim_gid</varname></primary>
+</indexterm>
+This variable contains the numerical value of the Exim group id.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$exim_path</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$exim_path</varname></primary>
+</indexterm>
+This variable contains the path to the Exim binary.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$exim_uid</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$exim_uid</varname></primary>
+</indexterm>
+This variable contains the numerical value of the Exim user id.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$exim_version</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$exim_version</varname></primary>
+</indexterm>
+This variable contains the version string of the Exim build.
+The first character is a major version number, currently 4.
+Then after a dot, the next group of digits is a minor version number.
+There may be other characters following the minor version.
+This value may be overridden by the <option>exim_version</option> main config option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$header_</varname><<emphasis>name</emphasis>></term>
+<listitem>
+<para>
+This is not strictly an expansion variable. It is expansion syntax for
+inserting the message header line with the given name. Note that the name must
+be terminated by colon or white space, because it may contain a wide variety of
+characters. Note also that braces must <emphasis>not</emphasis> be used.
+See the full description in section <xref linkend="SECTexpansionitems"/> above.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$headers_added</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$headers_added</varname></primary>
+</indexterm>
+Within an ACL this variable contains the headers added so far by
+the ACL modifier add_header (section <xref linkend="SECTaddheadacl"/>).
+The headers are a newline-separated list.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$home</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$home</varname></primary>
+</indexterm>
+When the <option>check_local_user</option> option is set for a router, the user’s home
+directory is placed in <varname>$home</varname> when the check succeeds. In particular, this
+means it is set during the running of users’ filter files. A router may also
+explicitly set a home directory for use by a transport; this can be overridden
+by a setting on the transport itself.
+</para>
+<para>
+When running a filter test via the <option>-bf</option> option, <varname>$home</varname> is set to the value
+of the environment variable HOME, which is subject to the
+<option>keep_environment</option> and <option>add_environment</option> main config options.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$host</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+If a router assigns an address to a transport (any transport), and passes a
+list of hosts with the address, the value of <varname>$host</varname> when the transport starts
+to run is the name of the first host on the list. Note that this applies both
+to local and remote transports.
+</para>
+<para>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>filter</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>transport filter</secondary>
+</indexterm>
+For the <command>smtp</command> transport, if there is more than one host, the value of
+<varname>$host</varname> changes as the transport works its way through the list. In
+particular, when the <command>smtp</command> transport is expanding its options for encryption
+using TLS, or for specifying a transport filter (see chapter
+<xref linkend="CHAPtransportgeneric"/>), <varname>$host</varname> contains the name of the host to which it
+is connected.
+</para>
+<para>
+When used in the client part of an authenticator configuration (see chapter
+<xref linkend="CHAPSMTPAUTH"/>), <varname>$host</varname> contains the name of the server to which the
+client is connected.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$host_address</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$host_address</varname></primary>
+</indexterm>
+This variable is set to the remote host’s IP address whenever <varname>$host</varname> is set
+for a remote connection. It is also set to the IP address that is being checked
+when the <option>ignore_target_hosts</option> option is being processed.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$host_data</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$host_data</varname></primary>
+</indexterm>
+If a <option>hosts</option> condition in an ACL is satisfied by means of a lookup, the
+result of the lookup is made available in the <varname>$host_data</varname> variable. This
+allows you, for example, to do things like this:
+</para>
+<literallayout class="monospaced">
+deny hosts = net-lsearch;/some/file
+ message = $host_data
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$host_lookup_deferred</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>host name</primary>
+<secondary>lookup, failure of</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host_lookup_deferred</varname></primary>
+</indexterm>
+This variable normally contains <quote>0</quote>, as does <varname>$host_lookup_failed</varname>. When a
+message comes from a remote host and there is an attempt to look up the host’s
+name from its IP address, and the attempt is not successful, one of these
+variables is set to <quote>1</quote>.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If the lookup receives a definite negative response (for example, a DNS lookup
+succeeded, but no records were found), <varname>$host_lookup_failed</varname> is set to <quote>1</quote>.
+</para>
+</listitem>
+<listitem>
+<para>
+If there is any kind of problem during the lookup, such that Exim cannot
+tell whether or not the host name is defined (for example, a timeout for a DNS
+lookup), <varname>$host_lookup_deferred</varname> is set to <quote>1</quote>.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Looking up a host’s name from its IP address consists of more than just a
+single reverse lookup. Exim checks that a forward lookup of at least one of the
+names it receives from a reverse lookup yields the original IP address. If this
+is not the case, Exim does not accept the looked up name(s), and
+<varname>$host_lookup_failed</varname> is set to <quote>1</quote>. Thus, being able to find a name from an
+IP address (for example, the existence of a PTR record in the DNS) is not
+sufficient on its own for the success of a host name lookup. If the reverse
+lookup succeeds, but there is a lookup problem such as a timeout when checking
+the result, the name is not accepted, and <varname>$host_lookup_deferred</varname> is set to
+<quote>1</quote>. See also <varname>$sender_host_name</varname>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>expansion item</secondary>
+</indexterm>
+Performing these checks sets up information used by the
+<option>authresults</option> expansion item.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$host_lookup_failed</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$host_lookup_failed</varname></primary>
+</indexterm>
+See <varname>$host_lookup_deferred</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$host_port</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$host_port</varname></primary>
+</indexterm>
+This variable is set to the remote host’s TCP port whenever <varname>$host</varname> is set
+for an outbound connection.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$initial_cwd</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$initial_cwd</varname></primary>
+</indexterm>
+This variable contains the full path name of the initial working
+directory of the current Exim process. This may differ from the current
+working directory, as Exim changes this to "/" during early startup, and
+to <varname>$spool_directory</varname> later.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$inode</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$inode</varname></primary>
+</indexterm>
+The only time this variable is set is while expanding the <option>directory_file</option>
+option in the <command>appendfile</command> transport. The variable contains the inode number
+of the temporary file which is about to be renamed. It can be used to construct
+a unique name for the file.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$interface_address</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$interface_address</varname></primary>
+</indexterm>
+This is an obsolete name for <varname>$received_ip_address</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$interface_port</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$interface_port</varname></primary>
+</indexterm>
+This is an obsolete name for <varname>$received_port</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$item</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$item</varname></primary>
+</indexterm>
+This variable is used during the expansion of <emphasis role="bold">forall</emphasis> and <emphasis role="bold">forany</emphasis>
+conditions (see section <xref linkend="SECTexpcond"/>), and <emphasis role="bold">filter</emphasis>, <emphasis role="bold">map</emphasis>, and
+<emphasis role="bold">reduce</emphasis> items (see section <xref linkend="SECTexpcond"/>). In other circumstances, it is
+empty.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$ldap_dn</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$ldap_dn</varname></primary>
+</indexterm>
+This variable, which is available only when Exim is compiled with LDAP support,
+contains the DN from the last entry in the most recently successful LDAP
+lookup.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$load_average</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$load_average</varname></primary>
+</indexterm>
+This variable contains the system load average, multiplied by 1000 so that it
+is an integer. For example, if the load average is 0.21, the value of the
+variable is 210. The value is recomputed every time the variable is referenced.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$local_part</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+When an address is being routed, or delivered on its own, this
+variable contains the local part. When a number of addresses are being
+delivered together (for example, multiple RCPT commands in an SMTP
+session), <varname>$local_part</varname> is not set.
+</para>
+<para>
+Global address rewriting happens when a message is received, so the value of
+<varname>$local_part</varname> during routing and delivery is the value after rewriting.
+<varname>$local_part</varname> is set during user filtering, but not during system filtering,
+because a message may have many recipients and the system filter is called just
+once.
+</para>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>tainted data</primary>
+</indexterm>
+If the origin of the data is an incoming message,
+the result of expanding this variable is tainted.
+</para>
+<para revisionflag="changed">
+<emphasis role="bold">Warning</emphasis>: the content of this variable is usually provided by a potential
+attacker.
+Consider carefully the implications of using it unvalidated as a name
+for file access.
+This presents issues for users’ <filename>.forward</filename> and filter files.
+For traditional full user accounts, use <option>check_local_users</option> and the
+<varname>$local_part_data</varname> variable rather than this one.
+For virtual users, store a suitable pathname component in the database
+which is used for account name validation, and use that retrieved value
+rather than this variable.
+Often <varname>$local_part_data</varname> is usable in this role.
+If needed, use a router <option>address_data</option> or <option>set</option> option for
+the retrieved data.
+</para>
+<para>
+When a message is being delivered to a file, pipe, or autoreply transport as a
+result of aliasing or forwarding, <varname>$local_part</varname> is set to the local part of
+the parent address, not to the filename or command (see <varname>$address_file</varname> and
+<varname>$address_pipe</varname>).
+</para>
+<para>
+When an ACL is running for a RCPT command, <varname>$local_part</varname> contains the
+local part of the recipient address.
+</para>
+<para>
+When a rewrite item is being processed (see chapter <xref linkend="CHAPrewrite"/>),
+<varname>$local_part</varname> contains the local part of the address that is being rewritten;
+it can be used in the expansion of the replacement address, for example.
+</para>
+<para>
+In all cases, all quoting is removed from the local part. For example, for both
+the addresses
+</para>
+<literallayout class="monospaced">
+"abc:xyz"@test.example
+abc\:xyz@test.example
+</literallayout>
+<para>
+the value of <varname>$local_part</varname> is
+</para>
+<literallayout class="monospaced">
+abc:xyz
+</literallayout>
+<para>
+If you use <varname>$local_part</varname> to create another address, you should always wrap it
+inside a quoting operator. For example, in a <command>redirect</command> router you could
+have:
+</para>
+<literallayout class="monospaced">
+data = ${quote_local_part:$local_part}@new.domain.example
+</literallayout>
+<para>
+<emphasis role="bold">Note</emphasis>: The value of <varname>$local_part</varname> is normally lower cased. If you want
+to process local parts in a case-dependent manner in a router, you can set the
+<option>caseful_local_part</option> option (see chapter <xref linkend="CHAProutergeneric"/>).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$local_part_data</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part_data</varname></primary>
+</indexterm>
+When the <option>local_parts</option> option on a router matches a local part by means of a
+lookup, the data read by the lookup is available during the running of the
+router as <varname>$local_part_data</varname>. In addition, if the driver routes the address
+to a transport, the value is available in that transport. If the transport is
+handling multiple addresses, the value from the first address is used.
+</para>
+<para revisionflag="changed">
+The <option>check_local_user</option> router option also sets this variable.
+</para>
+<para>
+<varname>$local_part_data</varname> is also set when the <option>local_parts</option> condition in an ACL
+matches a local part by means of a lookup. The data read by the lookup is
+available during the rest of the ACL statement. In all other situations, this
+variable expands to nothing.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part_prefix</varname></primary>
+<secondary><varname>$local_part_prefix_v</varname></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>affix</primary>
+<secondary>variables</secondary>
+</indexterm>
+If a local part prefix or suffix has been recognized, it is not included in the
+value of <varname>$local_part</varname> during routing and subsequent delivery. The values of
+any prefix or suffix are in <varname>$local_part_prefix</varname> and
+<varname>$local_part_suffix</varname>, respectively.
+</para>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>tainted data</primary>
+</indexterm>
+If the specification did not include a wildcard then
+the affix variable value is not tainted.
+</para>
+<para revisionflag="changed">
+If the affix specification included a wildcard then the portion of
+the affix matched by the wildcard is in
+<varname>$local_part_prefix_v</varname> or <varname>$local_part_suffix_v</varname> as appropriate,
+and both the whole and varying values are tainted.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$local_scan_data</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_scan_data</varname></primary>
+</indexterm>
+This variable contains the text returned by the <function>local_scan()</function> function when
+a message is received. See chapter <xref linkend="CHAPlocalscan"/> for more details.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$local_user_gid</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_user_gid</varname></primary>
+</indexterm>
+See <varname>$local_user_uid</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$local_user_uid</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_user_uid</varname></primary>
+</indexterm>
+This variable and <varname>$local_user_gid</varname> are set to the uid and gid after the
+<option>check_local_user</option> router precondition succeeds. This means that their values
+are available for the remaining preconditions (<option>senders</option>, <option>require_files</option>,
+and <option>condition</option>), for the <option>address_data</option> expansion, and for any
+router-specific expansions. At all other times, the values in these variables
+are <literal>(uid_t)(-1)</literal> and <literal>(gid_t)(-1)</literal>, respectively.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$localhost_number</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$localhost_number</varname></primary>
+</indexterm>
+This contains the expanded value of the
+<option>localhost_number</option> option. The expansion happens after the main options have
+been read.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$log_inodes</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$log_inodes</varname></primary>
+</indexterm>
+The number of free inodes in the disk partition where Exim’s
+log files are being written. The value is recalculated whenever the variable is
+referenced. If the relevant file system does not have the concept of inodes,
+the value of is -1. See also the <option>check_log_inodes</option> option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$log_space</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$log_space</varname></primary>
+</indexterm>
+The amount of free space (as a number of kilobytes) in the disk
+partition where Exim’s log files are being written. The value is recalculated
+whenever the variable is referenced. If the operating system does not have the
+ability to find the amount of free space (only true for experimental systems),
+the space value is -1. See also the <option>check_log_space</option> option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$lookup_dnssec_authenticated</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$lookup_dnssec_authenticated</varname></primary>
+</indexterm>
+This variable is set after a DNS lookup done by
+a dnsdb lookup expansion, dnslookup router or smtp transport.
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>DNSSEC</secondary>
+</indexterm>
+It will be empty if <command>DNSSEC</command> was not requested,
+<quote>no</quote> if the result was not labelled as authenticated data
+and <quote>yes</quote> if it was.
+Results that are labelled as authoritative answer that match
+the <option>dns_trust_aa</option> configuration variable count also
+as authenticated data.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mailstore_basename</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mailstore_basename</varname></primary>
+</indexterm>
+This variable is set only when doing deliveries in <quote>mailstore</quote> format in the
+<command>appendfile</command> transport. During the expansion of the <option>mailstore_prefix</option>,
+<option>mailstore_suffix</option>, <option>message_prefix</option>, and <option>message_suffix</option> options, it
+contains the basename of the files that are being written, that is, the name
+without the <quote>.tmp</quote>, <quote>.env</quote>, or <quote>.msg</quote> suffix. At all other times, this
+variable is empty.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$malware_name</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$malware_name</varname></primary>
+</indexterm>
+This variable is available when Exim is compiled with the
+content-scanning extension. It is set to the name of the virus that was found
+when the ACL <option>malware</option> condition is true (see section <xref linkend="SECTscanvirus"/>).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$max_received_linelength</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$max_received_linelength</varname></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>maximum</primary>
+<secondary>line length</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>line length</primary>
+<secondary>maximum</secondary>
+</indexterm>
+This variable contains the number of bytes in the longest line that was
+received as part of the message, not counting the line termination
+character(s).
+It is not valid if the <option>spool_files_wireformat</option> option is used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$message_age</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>age of</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$message_age</varname></primary>
+</indexterm>
+This variable is set at the start of a delivery attempt to contain the number
+of seconds since the message was received. It does not change during a single
+delivery attempt.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$message_body</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>body of message</primary>
+<secondary>expansion variable</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message body</primary>
+<secondary>in expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>binary zero</primary>
+<secondary>in message body</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$message_body</varname></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>message_body_visible</option></primary>
+</indexterm>
+This variable contains the initial portion of a message’s body while it is
+being delivered, and is intended mainly for use in filter files. The maximum
+number of characters of the body that are put into the variable is set by the
+<option>message_body_visible</option> configuration option; the default is 500.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>message_body_newlines</option></primary>
+</indexterm>
+By default, newlines are converted into spaces in <varname>$message_body</varname>, to make it
+easier to search for phrases that might be split over a line break. However,
+this can be disabled by setting <option>message_body_newlines</option> to be true. Binary
+zeros are always converted into spaces.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$message_body_end</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>body of message</primary>
+<secondary>expansion variable</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message body</primary>
+<secondary>in expansion</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$message_body_end</varname></primary>
+</indexterm>
+This variable contains the final portion of a message’s
+body while it is being delivered. The format and maximum size are as for
+<varname>$message_body</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$message_body_size</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>body of message</primary>
+<secondary>size</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message body</primary>
+<secondary>size</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$message_body_size</varname></primary>
+</indexterm>
+When a message is being delivered, this variable contains the size of the body
+in bytes. The count starts from the character after the blank line that
+separates the body from the header. Newlines are included in the count. See
+also <varname>$message_size</varname>, <varname>$body_linecount</varname>, and <varname>$body_zerocount</varname>.
+</para>
+<para>
+If the spool file is wireformat
+(see the <option>spool_files_wireformat</option> main option)
+the CRLF line-terminators are included in the count.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$message_exim_id</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$message_exim_id</varname></primary>
+</indexterm>
+When a message is being received or delivered, this variable contains the
+unique message id that is generated and used by Exim to identify the message.
+An id is not created for a message until after its header has been successfully
+received. <emphasis role="bold">Note</emphasis>: This is <emphasis>not</emphasis> the contents of the <emphasis>Message-ID:</emphasis> header
+line; it is the local id that Exim assigns to the message, for example:
+<literal>1BXTIK-0001yO-VA</literal>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$message_headers</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$message_headers</varname></primary>
+</indexterm>
+This variable contains a concatenation of all the header lines when a message
+is being processed, except for lines added by routers or transports. The header
+lines are separated by newline characters. Their contents are decoded in the
+same way as a header line that is inserted by <option>bheader</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$message_headers_raw</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$message_headers_raw</varname></primary>
+</indexterm>
+This variable is like <varname>$message_headers</varname> except that no processing of the
+contents of header lines is done.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$message_id</varname></term>
+<listitem>
+<para>
+This is an old name for <varname>$message_exim_id</varname>. It is now deprecated.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$message_linecount</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$message_linecount</varname></primary>
+</indexterm>
+This variable contains the total number of lines in the header and body of the
+message. Compare <varname>$body_linecount</varname>, which is the count for the body only.
+During the DATA and content-scanning ACLs, <varname>$message_linecount</varname> contains the
+number of lines received. Before delivery happens (that is, before filters,
+routers, and transports run) the count is increased to include the
+<emphasis>Received:</emphasis> header line that Exim standardly adds, and also any other header
+lines that are added by ACLs. The blank line that separates the message header
+from the body is not counted.
+</para>
+<para>
+As with the special case of <varname>$message_size</varname>, during the expansion of the
+appendfile transport’s maildir_tag option in maildir format, the value of
+<varname>$message_linecount</varname> is the precise size of the number of newlines in the
+file that has been written (minus one for the blank line between the
+header and the body).
+</para>
+<para>
+Here is an example of the use of this variable in a DATA ACL:
+</para>
+<literallayout class="monospaced">
+deny condition = \
+ ${if <{250}{${eval:$message_linecount - $body_linecount}}}
+ message = Too many lines in message header
+</literallayout>
+<para>
+In the MAIL and RCPT ACLs, the value is zero because at that stage the
+message has not yet been received.
+</para>
+<para>
+This variable is not valid if the <option>spool_files_wireformat</option> option is used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$message_size</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>size</primary>
+<secondary>of message</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>size</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$message_size</varname></primary>
+</indexterm>
+When a message is being processed, this variable contains its size in bytes. In
+most cases, the size includes those headers that were received with the
+message, but not those (such as <emphasis>Envelope-to:</emphasis>) that are added to individual
+deliveries as they are written. However, there is one special case: during the
+expansion of the <option>maildir_tag</option> option in the <command>appendfile</command> transport while
+doing a delivery in maildir format, the value of <varname>$message_size</varname> is the
+precise size of the file that has been written. See also
+<varname>$message_body_size</varname>, <varname>$body_linecount</varname>, and <varname>$body_zerocount</varname>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>RCPT</primary>
+<secondary>value of <varname>$message_size</varname></secondary>
+</indexterm>
+While running a per message ACL (mail/rcpt/predata), <varname>$message_size</varname>
+contains the size supplied on the MAIL command, or -1 if no size was given. The
+value may not, of course, be truthful.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_</varname><emphasis>xxx</emphasis></term>
+<listitem>
+<para>
+A number of variables whose names start with <varname>$mime</varname> are
+available when Exim is compiled with the content-scanning extension. For
+details, see section <xref linkend="SECTscanmimepart"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$n0</varname> – <varname>$n9</varname></term>
+<listitem>
+<para>
+These variables are counters that can be incremented by means
+of the <option>add</option> command in filter files.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$original_domain</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$original_domain</varname></primary>
+</indexterm>
+When a top-level address is being processed for delivery, this contains the
+same value as <varname>$domain</varname>. However, if a <quote>child</quote> address (for example,
+generated by an alias, forward, or filter file) is being processed, this
+variable contains the domain of the original address (lower cased). This
+differs from <varname>$parent_domain</varname> only when there is more than one level of
+aliasing or forwarding. When more than one address is being delivered in a
+single transport run, <varname>$original_domain</varname> is not set.
+</para>
+<para>
+If a new address is created by means of a <option>deliver</option> command in a system
+filter, it is set up with an artificial <quote>parent</quote> address. This has the local
+part <emphasis>system-filter</emphasis> and the default qualify domain.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$original_local_part</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$original_local_part</varname></primary>
+</indexterm>
+When a top-level address is being processed for delivery, this contains the
+same value as <varname>$local_part</varname>, unless a prefix or suffix was removed from the
+local part, because <varname>$original_local_part</varname> always contains the full local
+part. When a <quote>child</quote> address (for example, generated by an alias, forward, or
+filter file) is being processed, this variable contains the full local part of
+the original address.
+</para>
+<para>
+If the router that did the redirection processed the local part
+case-insensitively, the value in <varname>$original_local_part</varname> is in lower case.
+This variable differs from <varname>$parent_local_part</varname> only when there is more than
+one level of aliasing or forwarding. When more than one address is being
+delivered in a single transport run, <varname>$original_local_part</varname> is not set.
+</para>
+<para>
+If a new address is created by means of a <option>deliver</option> command in a system
+filter, it is set up with an artificial <quote>parent</quote> address. This has the local
+part <emphasis>system-filter</emphasis> and the default qualify domain.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$originator_gid</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>gid (group id)</primary>
+<secondary>of originating user</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>gid</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$caller_gid</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$originator_gid</varname></primary>
+</indexterm>
+This variable contains the value of <varname>$caller_gid</varname> that was set when the
+message was received. For messages received via the command line, this is the
+gid of the sending user. For messages received by SMTP over TCP/IP, this is
+normally the gid of the Exim user.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$originator_uid</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>uid (user id)</primary>
+<secondary>of originating user</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>uid</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$caller_uid</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$originator_uid</varname></primary>
+</indexterm>
+The value of <varname>$caller_uid</varname> that was set when the message was received. For
+messages received via the command line, this is the uid of the sending user.
+For messages received by SMTP over TCP/IP, this is normally the uid of the Exim
+user.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$parent_domain</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$parent_domain</varname></primary>
+</indexterm>
+This variable is similar to <varname>$original_domain</varname> (see
+above), except that it refers to the immediately preceding parent address.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$parent_local_part</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$parent_local_part</varname></primary>
+</indexterm>
+This variable is similar to <varname>$original_local_part</varname>
+(see above), except that it refers to the immediately preceding parent address.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$pid</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>pid (process id)</primary>
+<secondary>of current process</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$pid</varname></primary>
+</indexterm>
+This variable contains the current process id.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$pipe_addresses</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>transport filter</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>filter</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$pipe_addresses</varname></primary>
+</indexterm>
+This is not an expansion variable, but is mentioned here because the string
+<literal>$pipe_addresses</literal> is handled specially in the command specification for the
+<command>pipe</command> transport (chapter <xref linkend="CHAPpipetransport"/>) and in transport filters
+(described under <option>transport_filter</option> in chapter <xref linkend="CHAPtransportgeneric"/>).
+It cannot be used in general expansion strings, and provokes an <quote>unknown
+variable</quote> error if encountered.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$primary_hostname</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$primary_hostname</varname></primary>
+</indexterm>
+This variable contains the value set by <option>primary_hostname</option> in the
+configuration file, or read by the <function>uname()</function> function. If <function>uname()</function> returns
+a single-component name, Exim calls <function>gethostbyname()</function> (or
+<function>getipnodebyname()</function> where available) in an attempt to acquire a fully
+qualified host name. See also <varname>$smtp_active_hostname</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$proxy_external_address</varname></term>
+<term><varname>$proxy_external_port</varname></term>
+<term><varname>$proxy_local_address</varname></term>
+<term><varname>$proxy_local_port</varname></term>
+<term><varname>$proxy_session</varname></term>
+<listitem>
+<para>
+These variables are only available when built with Proxy Protocol
+or SOCKS5 support.
+For details see chapter <xref linkend="SECTproxyInbound"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$prdr_requested</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>PRDR</primary>
+<secondary>variable for</secondary>
+</indexterm>
+This variable is set to <quote>yes</quote> if PRDR was requested by the client for the
+current message, otherwise <quote>no</quote>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$prvscheck_address</varname></term>
+<listitem>
+<para>
+This variable is used in conjunction with the <option>prvscheck</option> expansion item,
+which is described in sections <xref linkend="SECTexpansionitems"/> and
+<xref linkend="SECTverifyPRVS"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$prvscheck_keynum</varname></term>
+<listitem>
+<para>
+This variable is used in conjunction with the <option>prvscheck</option> expansion item,
+which is described in sections <xref linkend="SECTexpansionitems"/> and
+<xref linkend="SECTverifyPRVS"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$prvscheck_result</varname></term>
+<listitem>
+<para>
+This variable is used in conjunction with the <option>prvscheck</option> expansion item,
+which is described in sections <xref linkend="SECTexpansionitems"/> and
+<xref linkend="SECTverifyPRVS"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$qualify_domain</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$qualify_domain</varname></primary>
+</indexterm>
+The value set for the <option>qualify_domain</option> option in the configuration file.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$qualify_recipient</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$qualify_recipient</varname></primary>
+</indexterm>
+The value set for the <option>qualify_recipient</option> option in the configuration file,
+or if not set, the value of <varname>$qualify_domain</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$queue_name</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$queue_name</varname></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>named queues</primary>
+<secondary>variable</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>queues</primary>
+<secondary>named</secondary>
+</indexterm>
+The name of the spool queue in use; empty for the default queue.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$queue_size</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$queue_size</varname></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>size of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>spool</primary>
+<secondary>number of messages</secondary>
+</indexterm>
+This variable contains the number of messages queued.
+It is evaluated on demand, but no more often than once every minute.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$r_...</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$r_...</varname></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>variables</secondary>
+</indexterm>
+Values can be placed in these variables by the <option>set</option> option of a router.
+They can be given any name that starts with <varname>$r_</varname>.
+The values persist for the address being handled through subsequent routers
+and the eventual transport.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$rcpt_count</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$rcpt_count</varname></primary>
+</indexterm>
+When a message is being received by SMTP, this variable contains the number of
+RCPT commands received for the current message. If this variable is used in a
+RCPT ACL, its value includes the current command.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$rcpt_defer_count</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$rcpt_defer_count</varname></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>4<emphasis>xx</emphasis> responses</primary>
+<secondary>count of</secondary>
+</indexterm>
+When a message is being received by SMTP, this variable contains the number of
+RCPT commands in the current message that have previously been rejected with a
+temporary (4<emphasis>xx</emphasis>) response.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$rcpt_fail_count</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$rcpt_fail_count</varname></primary>
+</indexterm>
+When a message is being received by SMTP, this variable contains the number of
+RCPT commands in the current message that have previously been rejected with a
+permanent (5<emphasis>xx</emphasis>) response.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$received_count</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$received_count</varname></primary>
+</indexterm>
+This variable contains the number of <emphasis>Received:</emphasis> header lines in the message,
+including the one added by Exim (so its value is always greater than zero). It
+is available in the DATA ACL, the non-SMTP ACL, and while routing and
+delivering.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$received_for</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$received_for</varname></primary>
+</indexterm>
+If there is only a single recipient address in an incoming message, this
+variable contains that address when the <emphasis>Received:</emphasis> header line is being
+built. The value is copied after recipient rewriting has happened, but before
+the <function>local_scan()</function> function is run.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$received_ip_address</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$received_ip_address</varname></primary>
+</indexterm>
+As soon as an Exim server starts processing an incoming TCP/IP connection, this
+variable is set to the address of the local IP interface, and <varname>$received_port</varname>
+is set to the local port number. (The remote IP address and port are in
+<varname>$sender_host_address</varname> and <varname>$sender_host_port</varname>.) When testing with <option>-bh</option>,
+the port value is -1 unless it has been set using the <option>-oMi</option> command line
+option.
+</para>
+<para>
+As well as being useful in ACLs (including the <quote>connect</quote> ACL), these variable
+could be used, for example, to make the filename for a TLS certificate depend
+on which interface and/or port is being used for the incoming connection. The
+values of <varname>$received_ip_address</varname> and <varname>$received_port</varname> are saved with any
+messages that are received, thus making these variables available at delivery
+time.
+For outbound connections see <varname>$sending_ip_address</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$received_port</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$received_port</varname></primary>
+</indexterm>
+See <varname>$received_ip_address</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$received_protocol</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$received_protocol</varname></primary>
+</indexterm>
+When a message is being processed, this variable contains the name of the
+protocol by which it was received. Most of the names used by Exim are defined
+by RFCs 821, 2821, and 3848. They start with <quote>smtp</quote> (the client used HELO) or
+<quote>esmtp</quote> (the client used EHLO). This can be followed by <quote>s</quote> for secure
+(encrypted) and/or <quote>a</quote> for authenticated. Thus, for example, if the protocol
+is set to <quote>esmtpsa</quote>, the message was received over an encrypted SMTP
+connection and the client was successfully authenticated.
+</para>
+<para>
+Exim uses the protocol name <quote>smtps</quote> for the case when encryption is
+automatically set up on connection without the use of STARTTLS (see
+<option>tls_on_connect_ports</option>), and the client uses HELO to initiate the
+encrypted SMTP session. The name <quote>smtps</quote> is also used for the rare situation
+where the client initially uses EHLO, sets up an encrypted connection using
+STARTTLS, and then uses HELO afterwards.
+</para>
+<para>
+The <option>-oMr</option> option provides a way of specifying a custom protocol name for
+messages that are injected locally by trusted callers. This is commonly used to
+identify messages that are being re-injected after some kind of scanning.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$received_time</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$received_time</varname></primary>
+</indexterm>
+This variable contains the date and time when the current message was received,
+as a number of seconds since the start of the Unix epoch.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$recipient_data</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$recipient_data</varname></primary>
+</indexterm>
+This variable is set after an indexing lookup success in an ACL <option>recipients</option>
+condition. It contains the data from the lookup, and the value remains set
+until the next <option>recipients</option> test. Thus, you can do things like this:
+</para>
+<literallayout>
+<literal>require recipients = cdb*@;/some/file</literal>
+<literal>deny </literal><emphasis>some further test involving</emphasis> <literal>$recipient_data</literal>
+</literallayout>
+<para>
+<emphasis role="bold">Warning</emphasis>: This variable is set only when a lookup is used as an indexing
+method in the address list, using the semicolon syntax as in the example above.
+The variable is not set for a lookup that is used as part of the string
+expansion that all such lists undergo before being interpreted.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$recipient_verify_failure</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$recipient_verify_failure</varname></primary>
+</indexterm>
+In an ACL, when a recipient verification fails, this variable contains
+information about the failure. It is set to one of the following words:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<quote>qualify</quote>: The address was unqualified (no domain), and the message
+was neither local nor came from an exempted host.
+</para>
+</listitem>
+<listitem>
+<para>
+<quote>route</quote>: Routing failed.
+</para>
+</listitem>
+<listitem>
+<para>
+<quote>mail</quote>: Routing succeeded, and a callout was attempted; rejection occurred at
+or before the MAIL command (that is, on initial connection, HELO, or
+MAIL).
+</para>
+</listitem>
+<listitem>
+<para>
+<quote>recipient</quote>: The RCPT command in a callout was rejected.
+</para>
+</listitem>
+<listitem>
+<para>
+<quote>postmaster</quote>: The postmaster check in a callout was rejected.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The main use of this variable is expected to be to distinguish between
+rejections of MAIL and rejections of RCPT.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$recipients</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$recipients</varname></primary>
+</indexterm>
+This variable contains a list of envelope recipients for a message. A comma and
+a space separate the addresses in the replacement text. However, the variable
+is not generally available, to prevent exposure of Bcc recipients in
+unprivileged users’ filter files. You can use <varname>$recipients</varname> only in these
+cases:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+In a system filter file.
+</para>
+</listitem>
+<listitem>
+<para>
+In the ACLs associated with the DATA command and with non-SMTP messages, that
+is, the ACLs defined by <option>acl_smtp_predata</option>, <option>acl_smtp_data</option>,
+<option>acl_smtp_mime</option>, <option>acl_not_smtp_start</option>, <option>acl_not_smtp</option>, and
+<option>acl_not_smtp_mime</option>.
+</para>
+</listitem>
+<listitem>
+<para>
+From within a <function>local_scan()</function> function.
+</para>
+</listitem>
+</orderedlist>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$recipients_count</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$recipients_count</varname></primary>
+</indexterm>
+When a message is being processed, this variable contains the number of
+envelope recipients that came with the message. Duplicates are not excluded
+from the count. While a message is being received over SMTP, the number
+increases for each accepted recipient. It can be referenced in an ACL.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$regex_match_string</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$regex_match_string</varname></primary>
+</indexterm>
+This variable is set to contain the matching regular expression after a
+<option>regex</option> ACL condition has matched (see section <xref linkend="SECTscanregex"/>).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$regex1</varname>, <varname>$regex2</varname>, etc</term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>regex submatch variables (<varname>$1regex</varname> <varname>$2regex</varname> etc)</primary>
+</indexterm>
+When a <option>regex</option> or <option>mime_regex</option> ACL condition succeeds,
+these variables contain the
+captured substrings identified by the regular expression.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$reply_address</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$reply_address</varname></primary>
+</indexterm>
+When a message is being processed, this variable contains the contents of the
+<emphasis>Reply-To:</emphasis> header line if one exists and it is not empty, or otherwise the
+contents of the <emphasis>From:</emphasis> header line. Apart from the removal of leading
+white space, the value is not processed in any way. In particular, no RFC 2047
+decoding or character code translation takes place.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$return_path</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$return_path</varname></primary>
+</indexterm>
+When a message is being delivered, this variable contains the return path –
+the sender field that will be sent as part of the envelope. It is not enclosed
+in <> characters. At the start of routing an address, <varname>$return_path</varname> has the
+same value as <varname>$sender_address</varname>, but if, for example, an incoming message to a
+mailing list has been expanded by a router which specifies a different address
+for bounce messages, <varname>$return_path</varname> subsequently contains the new bounce
+address, whereas <varname>$sender_address</varname> always contains the original sender address
+that was received with the message. In other words, <varname>$sender_address</varname> contains
+the incoming envelope sender, and <varname>$return_path</varname> contains the outgoing
+envelope sender.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$return_size_limit</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$return_size_limit</varname></primary>
+</indexterm>
+This is an obsolete name for <varname>$bounce_return_size_limit</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$router_name</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>name</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>name</primary>
+<secondary>of router</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$router_name</varname></primary>
+</indexterm>
+During the running of a router this variable contains its name.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$runrc</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>return code</primary>
+<secondary>from <option>run</option> expansion</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$runrc</varname></primary>
+</indexterm>
+This variable contains the return code from a command that is run by the
+<option>${run...}</option> expansion item. <emphasis role="bold">Warning</emphasis>: In a router or transport, you cannot
+assume the order in which option values are expanded, except for those
+preconditions whose order of testing is documented. Therefore, you cannot
+reliably expect to set <varname>$runrc</varname> by the expansion of one option, and use it in
+another.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$self_hostname</varname></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>self</option></primary>
+<secondary>value of host name</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$self_hostname</varname></primary>
+</indexterm>
+When an address is routed to a supposedly remote host that turns out to be the
+local host, what happens is controlled by the <option>self</option> generic router option.
+One of its values causes the address to be passed to another router. When this
+happens, <varname>$self_hostname</varname> is set to the name of the local host that the
+original router encountered. In other circumstances its contents are null.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_address</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_address</varname></primary>
+</indexterm>
+When a message is being processed, this variable contains the sender’s address
+that was received in the message’s envelope. The case of letters in the address
+is retained, in both the local part and the domain. For bounce messages, the
+value of this variable is the empty string. See also <varname>$return_path</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_address_data</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$address_data</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$sender_address_data</varname></primary>
+</indexterm>
+If <varname>$address_data</varname> is set when the routers are called from an ACL to verify a
+sender address, the final value is preserved in <varname>$sender_address_data</varname>, to
+distinguish it from data from a recipient address. The value does not persist
+after the end of the current ACL statement. If you want to preserve it for
+longer, you can save it in an ACL variable.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_address_domain</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_address_domain</varname></primary>
+</indexterm>
+The domain portion of <varname>$sender_address</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_address_local_part</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_address_local_part</varname></primary>
+</indexterm>
+The local part portion of <varname>$sender_address</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_data</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_data</varname></primary>
+</indexterm>
+This variable is set after a lookup success in an ACL <option>senders</option> condition or
+in a router <option>senders</option> option. It contains the data from the lookup, and the
+value remains set until the next <option>senders</option> test. Thus, you can do things like
+this:
+</para>
+<literallayout>
+<literal>require senders = cdb*@;/some/file</literal>
+<literal>deny </literal><emphasis>some further test involving</emphasis> <literal>$sender_data</literal>
+</literallayout>
+<para>
+<emphasis role="bold">Warning</emphasis>: This variable is set only when a lookup is used as an indexing
+method in the address list, using the semicolon syntax as in the example above.
+The variable is not set for a lookup that is used as part of the string
+expansion that all such lists undergo before being interpreted.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_fullhost</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_fullhost</varname></primary>
+</indexterm>
+When a message is received from a remote host, this variable contains the host
+name and IP address in a single string. It ends with the IP address in square
+brackets, followed by a colon and a port number if the logging of ports is
+enabled. The format of the rest of the string depends on whether the host
+issued a HELO or EHLO SMTP command, and whether the host name was verified by
+looking up its IP address. (Looking up the IP address can be forced by the
+<option>host_lookup</option> option, independent of verification.) A plain host name at the
+start of the string is a verified host name; if this is not present,
+verification either failed or was not requested. A host name in parentheses is
+the argument of a HELO or EHLO command. This is omitted if it is identical to
+the verified host name or to the host’s IP address in square brackets.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_helo_dnssec</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_helo_dnssec</varname></primary>
+</indexterm>
+This boolean variable is true if a successful HELO verification was
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>DNSSEC</secondary>
+</indexterm>
+done using DNS information the resolver library stated was authenticated data.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_helo_name</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_helo_name</varname></primary>
+</indexterm>
+When a message is received from a remote host that has issued a HELO or EHLO
+command, the argument of that command is placed in this variable. It is also
+set if HELO or EHLO is used when a message is received using SMTP locally via
+the <option>-bs</option> or <option>-bS</option> options.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_host_address</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_host_address</varname></primary>
+</indexterm>
+When a message is received from a remote host using SMTP,
+this variable contains that
+host’s IP address. For locally non-SMTP submitted messages, it is empty.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_host_authenticated</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_host_authenticated</varname></primary>
+</indexterm>
+This variable contains the name (not the public name) of the authenticator
+driver that successfully authenticated the client from which the message was
+received. It is empty if there was no successful authentication. See also
+<varname>$authenticated_id</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_host_dnssec</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_host_dnssec</varname></primary>
+</indexterm>
+If an attempt to populate <varname>$sender_host_name</varname> has been made
+(by reference, <option>hosts_lookup</option> or
+otherwise) then this boolean will have been set true if, and only if, the
+resolver library states that both
+the reverse and forward DNS were authenticated data. At all
+other times, this variable is false.
+</para>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>DNSSEC</secondary>
+</indexterm>
+It is likely that you will need to coerce DNSSEC support on in the resolver
+library, by setting:
+</para>
+<literallayout class="monospaced">
+dns_dnssec_ok = 1
+</literallayout>
+<para revisionflag="changed">
+In addition, on Linux with glibc 2.31 or newer the resolver library will
+default to stripping out a successful validation status.
+This will break a previously working Exim installation.
+Provided that you do trust the resolver (ie, is on localhost) you can tell
+glibc to pass through any successful validation with a new option in
+<filename>/etc/resolv.conf</filename>:
+</para>
+<literallayout class="monospaced" revisionflag="changed">
+options trust-ad
+</literallayout>
+<para>
+Exim does not perform DNSSEC validation itself, instead leaving that to a
+validating resolver (e.g. unbound, or bind with suitable configuration).
+</para>
+<para>
+If you have changed <option>host_lookup_order</option> so that <literal>bydns</literal> is not the first
+mechanism in the list, then this variable will be false.
+</para>
+<para>
+This requires that your system resolver library support EDNS0 (and that
+DNSSEC flags exist in the system headers). If the resolver silently drops
+all EDNS0 options, then this will have no effect. OpenBSD’s asr resolver
+is known to currently ignore EDNS0, documented in CAVEATS of asr_run(3).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_host_name</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_host_name</varname></primary>
+</indexterm>
+When a message is received from a remote host, this variable contains the
+host’s name as obtained by looking up its IP address. For messages received by
+other means, this variable is empty.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$host_lookup_failed</varname></primary>
+</indexterm>
+If the host name has not previously been looked up, a reference to
+<varname>$sender_host_name</varname> triggers a lookup (for messages from remote hosts).
+A looked up name is accepted only if it leads back to the original IP address
+via a forward lookup. If either the reverse or the forward lookup fails to find
+any data, or if the forward lookup does not yield the original IP address,
+<varname>$sender_host_name</varname> remains empty, and <varname>$host_lookup_failed</varname> is set to <quote>1</quote>.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$host_lookup_deferred</varname></primary>
+</indexterm>
+However, if either of the lookups cannot be completed (for example, there is a
+DNS timeout), <varname>$host_lookup_deferred</varname> is set to <quote>1</quote>, and
+<varname>$host_lookup_failed</varname> remains set to <quote>0</quote>.
+</para>
+<para>
+Once <varname>$host_lookup_failed</varname> is set to <quote>1</quote>, Exim does not try to look up the
+host name again if there is a subsequent reference to <varname>$sender_host_name</varname>
+in the same Exim process, but it does try again if <varname>$host_lookup_deferred</varname>
+is set to <quote>1</quote>.
+</para>
+<para>
+Exim does not automatically look up every calling host’s name. If you want
+maximum efficiency, you should arrange your configuration so that it avoids
+these lookups altogether. The lookup happens only if one or more of the
+following are true:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+A string containing <varname>$sender_host_name</varname> is expanded.
+</para>
+</listitem>
+<listitem>
+<para>
+The calling host matches the list in <option>host_lookup</option>. In the default
+configuration, this option is set to *, so it must be changed if lookups are
+to be avoided. (In the code, the default for <option>host_lookup</option> is unset.)
+</para>
+</listitem>
+<listitem>
+<para>
+Exim needs the host name in order to test an item in a host list. The items
+that require this are described in sections <xref linkend="SECThoslispatnam"/> and
+<xref linkend="SECThoslispatnamsk"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+The calling host matches <option>helo_try_verify_hosts</option> or <option>helo_verify_hosts</option>.
+In this case, the host name is required to compare with the name quoted in any
+EHLO or HELO commands that the client issues.
+</para>
+</listitem>
+<listitem>
+<para>
+The remote host issues a EHLO or HELO command that quotes one of the
+domains in <option>helo_lookup_domains</option>. The default value of this option is
+</para>
+<literallayout class="monospaced">
+ helo_lookup_domains = @ : @[]
+</literallayout>
+<para>
+which causes a lookup if a remote host (incorrectly) gives the server’s name or
+IP address in an EHLO or HELO command.
+</para>
+</listitem>
+</itemizedlist>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_host_port</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_host_port</varname></primary>
+</indexterm>
+When a message is received from a remote host, this variable contains the port
+number that was used on the remote host.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_ident</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_ident</varname></primary>
+</indexterm>
+When a message is received from a remote host, this variable contains the
+identification received in response to an RFC 1413 request. When a message has
+been received locally, this variable contains the login name of the user that
+called Exim.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_rate_</varname><emphasis>xxx</emphasis></term>
+<listitem>
+<para>
+A number of variables whose names begin <varname>$sender_rate_</varname> are set as part of the
+<option>ratelimit</option> ACL condition. Details are given in section
+<xref linkend="SECTratelimiting"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_rcvhost</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>reverse lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>reverse DNS lookup</primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$sender_rcvhost</varname></primary>
+</indexterm>
+This is provided specifically for use in <emphasis>Received:</emphasis> headers. It starts with
+either the verified host name (as obtained from a reverse DNS lookup) or, if
+there is no verified host name, the IP address in square brackets. After that
+there may be text in parentheses. When the first item is a verified host name,
+the first thing in the parentheses is the IP address in square brackets,
+followed by a colon and a port number if port logging is enabled. When the
+first item is an IP address, the port is recorded as <quote>port=<emphasis>xxxx</emphasis></quote> inside
+the parentheses.
+</para>
+<para>
+There may also be items of the form <quote>helo=<emphasis>xxxx</emphasis></quote> if HELO or EHLO
+was used and its argument was not identical to the real host name or IP
+address, and <quote>ident=<emphasis>xxxx</emphasis></quote> if an RFC 1413 ident string is available. If
+all three items are present in the parentheses, a newline and tab are inserted
+into the string, to improve the formatting of the <emphasis>Received:</emphasis> header.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sender_verify_failure</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_verify_failure</varname></primary>
+</indexterm>
+In an ACL, when a sender verification fails, this variable contains information
+about the failure. The details are the same as for
+<varname>$recipient_verify_failure</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sending_ip_address</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sending_ip_address</varname></primary>
+</indexterm>
+This variable is set whenever an outgoing SMTP connection to another host has
+been set up. It contains the IP address of the local interface that is being
+used. This is useful if a host that has more than one IP address wants to take
+on different personalities depending on which one is being used. For incoming
+connections, see <varname>$received_ip_address</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sending_port</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$sending_port</varname></primary>
+</indexterm>
+This variable is set whenever an outgoing SMTP connection to another host has
+been set up. It contains the local port that is being used. For incoming
+connections, see <varname>$received_port</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$smtp_active_hostname</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$smtp_active_hostname</varname></primary>
+</indexterm>
+During an incoming SMTP session, this variable contains the value of the active
+host name, as specified by the <option>smtp_active_hostname</option> option. The value of
+<varname>$smtp_active_hostname</varname> is saved with any message that is received, so its
+value can be consulted during routing and delivery.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$smtp_command</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$smtp_command</varname></primary>
+</indexterm>
+During the processing of an incoming SMTP command, this variable contains the
+entire command. This makes it possible to distinguish between HELO and EHLO in
+the HELO ACL, and also to distinguish between commands such as these:
+</para>
+<literallayout class="monospaced">
+MAIL FROM:<>
+MAIL FROM: <>
+</literallayout>
+<para>
+For a MAIL command, extra parameters such as SIZE can be inspected. For a RCPT
+command, the address in <varname>$smtp_command</varname> is the original address before any
+rewriting, whereas the values in <varname>$local_part</varname> and <varname>$domain</varname> are taken from
+the address after SMTP-time rewriting.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$smtp_command_argument</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>command, argument for</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$smtp_command_argument</varname></primary>
+</indexterm>
+While an ACL is running to check an SMTP command, this variable contains the
+argument, that is, the text that follows the command name, with leading white
+space removed. Following the introduction of <varname>$smtp_command</varname>, this variable is
+somewhat redundant, but is retained for backwards compatibility.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$smtp_command_history</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>command history</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$smtp_command_history</varname></primary>
+</indexterm>
+A comma-separated list (with no whitespace) of the most-recent SMTP commands
+received, in time-order left to right. Only a limited number of commands
+are remembered.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$smtp_count_at_connection_start</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$smtp_count_at_connection_start</varname></primary>
+</indexterm>
+This variable is set greater than zero only in processes spawned by the Exim
+daemon for handling incoming SMTP connections. The name is deliberately long,
+in order to emphasize what the contents are. When the daemon accepts a new
+connection, it increments this variable. A copy of the variable is passed to
+the child process that handles the connection, but its value is fixed, and
+never changes. It is only an approximation of how many incoming connections
+there actually are, because many other connections may come and go while a
+single connection is being processed. When a child process terminates, the
+daemon decrements its copy of the variable.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$sn0</varname> – <varname>$sn9</varname></term>
+<listitem>
+<para>
+These variables are copies of the values of the <varname>$n0</varname> – <varname>$n9</varname> accumulators
+that were current at the end of the system filter file. This allows a system
+filter file to set values that can be tested in users’ filter files. For
+example, a system filter could set a value indicating how likely it is that a
+message is junk mail.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$spam_</varname><emphasis>xxx</emphasis></term>
+<listitem>
+<para>
+A number of variables whose names start with <varname>$spam</varname> are available when Exim
+is compiled with the content-scanning extension. For details, see section
+<xref linkend="SECTscanspamass"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$spf_header_comment</varname></term>
+<term><varname>$spf_received</varname></term>
+<term><varname>$spf_result</varname></term>
+<term><varname>$spf_result_guessed</varname></term>
+<term><varname>$spf_smtp_comment</varname></term>
+<listitem>
+<para>
+These variables are only available if Exim is built with SPF support.
+For details see section <xref linkend="SECSPF"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$spool_directory</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$spool_directory</varname></primary>
+</indexterm>
+The name of Exim’s spool directory.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$spool_inodes</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$spool_inodes</varname></primary>
+</indexterm>
+The number of free inodes in the disk partition where Exim’s spool files are
+being written. The value is recalculated whenever the variable is referenced.
+If the relevant file system does not have the concept of inodes, the value of
+is -1. See also the <option>check_spool_inodes</option> option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$spool_space</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$spool_space</varname></primary>
+</indexterm>
+The amount of free space (as a number of kilobytes) in the disk partition where
+Exim’s spool files are being written. The value is recalculated whenever the
+variable is referenced. If the operating system does not have the ability to
+find the amount of free space (only true for experimental systems), the space
+value is -1. For example, to check in an ACL that there is at least 50
+megabytes free on the spool, you could write:
+</para>
+<literallayout class="monospaced">
+condition = ${if > {$spool_space}{50000}}
+</literallayout>
+<para>
+See also the <option>check_spool_space</option> option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$thisaddress</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$thisaddress</varname></primary>
+</indexterm>
+This variable is set only during the processing of the <option>foranyaddress</option>
+command in a filter file. Its use is explained in the description of that
+command, which can be found in the separate document entitled <emphasis>Exim’s
+interfaces to mail filtering</emphasis>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_in_bits</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_bits</varname></primary>
+</indexterm>
+Contains an approximation of the TLS cipher’s bit-strength
+on the inbound connection; the meaning of
+this depends upon the TLS implementation used.
+If TLS has not been negotiated, the value will be 0.
+The value of this is automatically fed into the Cyrus SASL authenticator
+when acting as a server, to specify the "external SSF" (a SASL term).
+</para>
+<para>
+The deprecated <varname>$tls_bits</varname> variable refers to the inbound side
+except when used in the context of an outbound SMTP delivery, when it refers to
+the outbound.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_out_bits</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_out_bits</varname></primary>
+</indexterm>
+Contains an approximation of the TLS cipher’s bit-strength
+on an outbound SMTP connection; the meaning of
+this depends upon the TLS implementation used.
+If TLS has not been negotiated, the value will be 0.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_in_ourcert</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_ourcert</varname></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>variables</secondary>
+</indexterm>
+This variable refers to the certificate presented to the peer of an
+inbound connection when the message was received.
+It is only useful as the argument of a
+<option>certextract</option> expansion item, <option>md5</option>, <option>sha1</option> or <option>sha256</option> operator,
+or a <option>def</option> condition.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: Under versions of OpenSSL preceding 1.1.1,
+when a list of more than one
+file is used for <option>tls_certificate</option>, this variable is not reliable.
+The macro "_TLS_BAD_MULTICERT_IN_OURCERT" will be defined for those versions.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_in_peercert</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_peercert</varname></primary>
+</indexterm>
+This variable refers to the certificate presented by the peer of an
+inbound connection when the message was received.
+It is only useful as the argument of a
+<option>certextract</option> expansion item, <option>md5</option>, <option>sha1</option> or <option>sha256</option> operator,
+or a <option>def</option> condition.
+If certificate verification fails it may refer to a failing chain element
+which is not the leaf.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_out_ourcert</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_out_ourcert</varname></primary>
+</indexterm>
+This variable refers to the certificate presented to the peer of an
+outbound connection. It is only useful as the argument of a
+<option>certextract</option> expansion item, <option>md5</option>, <option>sha1</option> or <option>sha256</option> operator,
+or a <option>def</option> condition.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_out_peercert</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_out_peercert</varname></primary>
+</indexterm>
+This variable refers to the certificate presented by the peer of an
+outbound connection. It is only useful as the argument of a
+<option>certextract</option> expansion item, <option>md5</option>, <option>sha1</option> or <option>sha256</option> operator,
+or a <option>def</option> condition.
+If certificate verification fails it may refer to a failing chain element
+which is not the leaf.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_in_certificate_verified</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_certificate_verified</varname></primary>
+</indexterm>
+This variable is set to <quote>1</quote> if a TLS certificate was verified when the
+message was received, and <quote>0</quote> otherwise.
+</para>
+<para>
+The deprecated <varname>$tls_certificate_verified</varname> variable refers to the inbound side
+except when used in the context of an outbound SMTP delivery, when it refers to
+the outbound.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_out_certificate_verified</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_out_certificate_verified</varname></primary>
+</indexterm>
+This variable is set to <quote>1</quote> if a TLS certificate was verified when an
+outbound SMTP connection was made,
+and <quote>0</quote> otherwise.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_in_cipher</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_cipher</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tls_cipher</varname></primary>
+</indexterm>
+When a message is received from a remote host over an encrypted SMTP
+connection, this variable is set to the cipher suite that was negotiated, for
+example DES-CBC3-SHA. In other circumstances, in particular, for message
+received over unencrypted connections, the variable is empty. Testing
+<varname>$tls_in_cipher</varname> for emptiness is one way of distinguishing between encrypted and
+non-encrypted connections during ACL processing.
+</para>
+<para>
+The deprecated <varname>$tls_cipher</varname> variable is the same as <varname>$tls_in_cipher</varname> during message reception,
+but in the context of an outward SMTP delivery taking place via the <command>smtp</command> transport
+becomes the same as <varname>$tls_out_cipher</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_in_cipher_std</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_cipher_std</varname></primary>
+</indexterm>
+As above, but returning the RFC standard name for the cipher suite.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_out_cipher</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_out_cipher</varname></primary>
+</indexterm>
+This variable is
+cleared before any outgoing SMTP connection is made,
+and then set to the outgoing cipher suite if one is negotiated. See chapter
+<xref linkend="CHAPTLS"/> for details of TLS support and chapter <xref linkend="CHAPsmtptrans"/> for
+details of the <command>smtp</command> transport.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_out_cipher_std</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_out_cipher_std</varname></primary>
+</indexterm>
+As above, but returning the RFC standard name for the cipher suite.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_out_dane</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_out_dane</varname></primary>
+</indexterm>
+DANE active status. See section <xref linkend="SECDANE"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_in_ocsp</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_ocsp</varname></primary>
+</indexterm>
+When a message is received from a remote client connection
+the result of any OCSP request from the client is encoded in this variable:
+</para>
+<literallayout class="monospaced">
+0 OCSP proof was not requested (default value)
+1 No response to request
+2 Response not verified
+3 Verification failed
+4 Verification succeeded
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_out_ocsp</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_out_ocsp</varname></primary>
+</indexterm>
+When a message is sent to a remote host connection
+the result of any OCSP request made is encoded in this variable.
+See <varname>$tls_in_ocsp</varname> for values.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_in_peerdn</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_peerdn</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tls_peerdn</varname></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>extracting fields</secondary>
+</indexterm>
+When a message is received from a remote host over an encrypted SMTP
+connection, and Exim is configured to request a certificate from the client,
+the value of the Distinguished Name of the certificate is made available in the
+<varname>$tls_in_peerdn</varname> during subsequent processing.
+If certificate verification fails it may refer to a failing chain element
+which is not the leaf.
+</para>
+<para>
+The deprecated <varname>$tls_peerdn</varname> variable refers to the inbound side
+except when used in the context of an outbound SMTP delivery, when it refers to
+the outbound.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_out_peerdn</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_out_peerdn</varname></primary>
+</indexterm>
+When a message is being delivered to a remote host over an encrypted SMTP
+connection, and Exim is configured to request a certificate from the server,
+the value of the Distinguished Name of the certificate is made available in the
+<varname>$tls_out_peerdn</varname> during subsequent processing.
+If certificate verification fails it may refer to a failing chain element
+which is not the leaf.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_in_sni</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_sni</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tls_sni</varname></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>Server Name Indication</secondary>
+</indexterm>
+When a TLS session is being established, if the client sends the Server
+Name Indication extension, the value will be placed in this variable.
+If the variable appears in <option>tls_certificate</option> then this option and
+some others, described in <xref linkend="SECTtlssni"/>,
+will be re-expanded early in the TLS session, to permit
+a different certificate to be presented (and optionally a different key to be
+used) to the client, based upon the value of the SNI extension.
+</para>
+<para>
+The deprecated <varname>$tls_sni</varname> variable refers to the inbound side
+except when used in the context of an outbound SMTP delivery, when it refers to
+the outbound.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_out_sni</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_out_sni</varname></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>Server Name Indication</secondary>
+</indexterm>
+During outbound
+SMTP deliveries, this variable reflects the value of the <option>tls_sni</option> option on
+the transport.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_out_tlsa_usage</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_out_tlsa_usage</varname></primary>
+</indexterm>
+Bitfield of TLSA record types found. See section <xref linkend="SECDANE"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_in_ver</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_ver</varname></primary>
+</indexterm>
+When a message is received from a remote host over an encrypted SMTP connection
+this variable is set to the protocol version, eg <emphasis>TLS1.2</emphasis>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tls_out_ver</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_out_ver</varname></primary>
+</indexterm>
+When a message is being delivered to a remote host over an encrypted SMTP connection
+this variable is set to the protocol version.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tod_bsdinbox</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tod_bsdinbox</varname></primary>
+</indexterm>
+The time of day and the date, in the format required for BSD-style mailbox
+files, for example: Thu Oct 17 17:14:09 1995.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tod_epoch</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tod_epoch</varname></primary>
+</indexterm>
+The time and date as a number of seconds since the start of the Unix epoch.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tod_epoch_l</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tod_epoch_l</varname></primary>
+</indexterm>
+The time and date as a number of microseconds since the start of the Unix epoch.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tod_full</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tod_full</varname></primary>
+</indexterm>
+A full version of the time and date, for example: Wed, 16 Oct 1995 09:51:40
++0100. The timezone is always given as a numerical offset from UTC, with
+positive values used for timezones that are ahead (east) of UTC, and negative
+values for those that are behind (west).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tod_log</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tod_log</varname></primary>
+</indexterm>
+The time and date in the format used for writing Exim’s log files, for example:
+1995-10-12 15:32:29, but without a timezone.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tod_logfile</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tod_logfile</varname></primary>
+</indexterm>
+This variable contains the date in the format yyyymmdd. This is the format that
+is used for datestamping log files when <option>log_file_path</option> contains the <literal>%D</literal>
+flag.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tod_zone</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tod_zone</varname></primary>
+</indexterm>
+This variable contains the numerical value of the local timezone, for example:
+-0500.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$tod_zulu</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tod_zulu</varname></primary>
+</indexterm>
+This variable contains the UTC date and time in <quote>Zulu</quote> format, as specified
+by ISO 8601, for example: 20030221154023Z.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$transport_name</varname></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>name</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>name</primary>
+<secondary>of transport</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$transport_name</varname></primary>
+</indexterm>
+During the running of a transport, this variable contains its name.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$value</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$value</varname></primary>
+</indexterm>
+This variable contains the result of an expansion lookup, extraction operation,
+or external command, as described above. It is also used during a
+<emphasis role="bold">reduce</emphasis> expansion.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$verify_mode</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$verify_mode</varname></primary>
+</indexterm>
+While a router or transport is being run in verify mode or for cutthrough delivery,
+contains "S" for sender-verification or "R" for recipient-verification.
+Otherwise, empty.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$version_number</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$version_number</varname></primary>
+</indexterm>
+The version number of Exim. Same as <varname>$exim_version</varname>, may be overridden
+by the <option>exim_version</option> main config option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$warn_message_delay</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$warn_message_delay</varname></primary>
+</indexterm>
+This variable is set only during the creation of a message warning about a
+delivery delay. Details of its use are explained in section <xref linkend="SECTcustwarn"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$warn_message_recipients</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$warn_message_recipients</varname></primary>
+</indexterm>
+This variable is set only during the creation of a message warning about a
+delivery delay. Details of its use are explained in section <xref linkend="SECTcustwarn"/>.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+<indexterm role="concept" startref="IIDstrexp" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPperl">
+<title>Embedded Perl</title>
+<para>
+<indexterm role="concept" id="IIDperl" class="startofrange">
+<primary>Perl</primary>
+<secondary>calling from Exim</secondary>
+</indexterm>
+Exim can be built to include an embedded Perl interpreter. When this is done,
+Perl subroutines can be called as part of the string expansion process. To make
+use of the Perl support, you need version 5.004 or later of Perl installed on
+your system. To include the embedded interpreter in the Exim binary, include
+the line
+</para>
+<literallayout class="monospaced">
+EXIM_PERL = perl.o
+</literallayout>
+<para>
+in your <filename>Local/Makefile</filename> and then build Exim in the normal way.
+</para>
+<section id="SECID85">
+<title>Setting up so Perl can be used</title>
+<para>
+<indexterm role="option">
+<primary><option>perl_startup</option></primary>
+</indexterm>
+Access to Perl subroutines is via a global configuration option called
+<option>perl_startup</option> and an expansion string operator <option>${perl ...}</option>. If there is
+no <option>perl_startup</option> option in the Exim configuration file then no Perl
+interpreter is started and there is almost no overhead for Exim (since none of
+the Perl library will be paged in unless used). If there is a <option>perl_startup</option>
+option then the associated value is taken to be Perl code which is executed in
+a newly created Perl interpreter.
+</para>
+<para>
+The value of <option>perl_startup</option> is not expanded in the Exim sense, so you do not
+need backslashes before any characters to escape special meanings. The option
+should usually be something like
+</para>
+<literallayout class="monospaced">
+perl_startup = do '/etc/exim.pl'
+</literallayout>
+<para>
+where <filename>/etc/exim.pl</filename> is Perl code which defines any subroutines you want to
+use from Exim. Exim can be configured either to start up a Perl interpreter as
+soon as it is entered, or to wait until the first time it is needed. Starting
+the interpreter at the beginning ensures that it is done while Exim still has
+its setuid privilege, but can impose an unnecessary overhead if Perl is not in
+fact used in a particular run. Also, note that this does not mean that Exim is
+necessarily running as root when Perl is called at a later time. By default,
+the interpreter is started only when it is needed, but this can be changed in
+two ways:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>perl_at_start</option></primary>
+</indexterm>
+Setting <option>perl_at_start</option> (a boolean option) in the configuration requests
+a startup when Exim is entered.
+</para>
+</listitem>
+<listitem>
+<para>
+The command line option <option>-ps</option> also requests a startup when Exim is entered,
+overriding the setting of <option>perl_at_start</option>.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+There is also a command line option <option>-pd</option> (for delay) which suppresses the
+initial startup, even if <option>perl_at_start</option> is set.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>perl_taintmode</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Perl</primary>
+<secondary>taintmode</secondary>
+</indexterm>
+To provide more security executing Perl code via the embedded Perl
+interpreter, the <option>perl_taintmode</option> option can be set. This enables the
+taint mode of the Perl interpreter. You are encouraged to set this
+option to a true value. To avoid breaking existing installations, it
+defaults to false.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID86">
+<title>Calling Perl subroutines</title>
+<para>
+When the configuration file includes a <option>perl_startup</option> option you can make use
+of the string expansion item to call the Perl subroutines that are defined
+by the <option>perl_startup</option> code. The operator is used in any of the following
+forms:
+</para>
+<literallayout class="monospaced">
+${perl{foo}}
+${perl{foo}{argument}}
+${perl{foo}{argument1}{argument2} ... }
+</literallayout>
+<para>
+which calls the subroutine <option>foo</option> with the given arguments. A maximum of eight
+arguments may be passed. Passing more than this results in an expansion failure
+with an error message of the form
+</para>
+<literallayout class="monospaced">
+Too many arguments passed to Perl subroutine "foo" (max is 8)
+</literallayout>
+<para>
+The return value of the Perl subroutine is evaluated in a scalar context before
+it is passed back to Exim to be inserted into the expanded string. If the
+return value is <emphasis>undef</emphasis>, the expansion is forced to fail in the same way as
+an explicit <quote>fail</quote> on an <option>if</option> or <option>lookup</option> item. If the subroutine aborts
+by obeying Perl’s <option>die</option> function, the expansion fails with the error message
+that was passed to <option>die</option>.
+</para>
+</section>
+<section id="SECID87">
+<title>Calling Exim functions from Perl</title>
+<para>
+Within any Perl code called from Exim, the function <emphasis>Exim::expand_string()</emphasis>
+is available to call back into Exim’s string expansion function. For example,
+the Perl code
+</para>
+<literallayout class="monospaced">
+my $lp = Exim::expand_string('$local_part');
+</literallayout>
+<para>
+makes the current Exim <varname>$local_part</varname> available in the Perl variable <varname>$lp</varname>.
+Note those are single quotes and not double quotes to protect against
+<varname>$local_part</varname> being interpolated as a Perl variable.
+</para>
+<para>
+If the string expansion is forced to fail by a <quote>fail</quote> item, the result of
+<emphasis>Exim::expand_string()</emphasis> is <option>undef</option>. If there is a syntax error in the
+expansion string, the Perl call from the original expansion string fails with
+an appropriate error message, in the same way as if <option>die</option> were used.
+</para>
+<para>
+<indexterm role="concept">
+<primary>debugging</primary>
+<secondary>from embedded Perl</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>writing from embedded Perl</secondary>
+</indexterm>
+Two other Exim functions are available for use from within Perl code.
+<emphasis>Exim::debug_write()</emphasis> writes a string to the standard error stream if Exim’s
+debugging is enabled. If you want a newline at the end, you must supply it.
+<emphasis>Exim::log_write()</emphasis> writes a string to Exim’s main log, adding a leading
+timestamp. In this case, you should not supply a terminating newline.
+</para>
+</section>
+<section id="SECID88">
+<title>Use of standard output and error by Perl</title>
+<para>
+<indexterm role="concept">
+<primary>Perl</primary>
+<secondary>standard output and error</secondary>
+</indexterm>
+You should not write to the standard error or output streams from within your
+Perl code, as it is not defined how these are set up. In versions of Exim
+before 4.50, it is possible for the standard output or error to refer to the
+SMTP connection during message reception via the daemon. Writing to this stream
+is certain to cause chaos. From Exim 4.50 onwards, the standard output and
+error streams are connected to <filename>/dev/null</filename> in the daemon. The chaos is
+avoided, but the output is lost.
+</para>
+<para>
+<indexterm role="concept">
+<primary>Perl</primary>
+<secondary>use of <option>warn</option></secondary>
+</indexterm>
+The Perl <option>warn</option> statement writes to the standard error stream by default.
+Calls to <option>warn</option> may be embedded in Perl modules that you use, but over which
+you have no control. When Exim starts up the Perl interpreter, it arranges for
+output from the <option>warn</option> statement to be written to the Exim main log. You can
+change this by including appropriate Perl magic somewhere in your Perl code.
+For example, to discard <option>warn</option> output completely, you need this:
+</para>
+<literallayout class="monospaced">
+$SIG{__WARN__} = sub { };
+</literallayout>
+<para>
+Whenever a <option>warn</option> is obeyed, the anonymous subroutine is called. In this
+example, the code for the subroutine is empty, so it does nothing, but you can
+include any Perl code that you like. The text of the <option>warn</option> message is passed
+as the first subroutine argument.
+<indexterm role="concept" startref="IIDperl" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPinterfaces">
+<title>Starting the daemon and the use of network interfaces</title>
+<titleabbrev>Starting the daemon</titleabbrev>
+<para>
+<indexterm role="concept">
+<primary>daemon</primary>
+<secondary>starting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>interface</primary>
+<secondary>listening</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>network interface</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>interface</primary>
+<secondary>network</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>IP address</primary>
+<secondary>for listening</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>daemon</primary>
+<secondary>listening IP addresses</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP/IP</primary>
+<secondary>setting listening interfaces</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP/IP</primary>
+<secondary>setting listening ports</secondary>
+</indexterm>
+A host that is connected to a TCP/IP network may have one or more physical
+hardware network interfaces. Each of these interfaces may be configured as one
+or more <quote>logical</quote> interfaces, which are the entities that a program actually
+works with. Each of these logical interfaces is associated with an IP address.
+In addition, TCP/IP software supports <quote>loopback</quote> interfaces (127.0.0.1 in
+IPv4 and ::1 in IPv6), which do not use any physical hardware. Exim requires
+knowledge about the host’s interfaces for use in three different circumstances:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+When a listening daemon is started, Exim needs to know which interfaces
+and ports to listen on.
+</para>
+</listitem>
+<listitem>
+<para>
+When Exim is routing an address, it needs to know which IP addresses
+are associated with local interfaces. This is required for the correct
+processing of MX lists by removing the local host and others with the
+same or higher priority values. Also, Exim needs to detect cases
+when an address is routed to an IP address that in fact belongs to the
+local host. Unless the <option>self</option> router option or the <option>allow_localhost</option>
+option of the smtp transport is set (as appropriate), this is treated
+as an error situation.
+</para>
+</listitem>
+<listitem>
+<para>
+When Exim connects to a remote host, it may need to know which interface to use
+for the outgoing connection.
+</para>
+</listitem>
+</orderedlist>
+<para>
+Exim’s default behaviour is likely to be appropriate in the vast majority
+of cases. If your host has only one interface, and you want all its IP
+addresses to be treated in the same way, and you are using only the
+standard SMTP port, you should not need to take any special action. The
+rest of this chapter does not apply to you.
+</para>
+<para>
+In a more complicated situation you may want to listen only on certain
+interfaces, or on different ports, and for this reason there are a number of
+options that can be used to influence Exim’s behaviour. The rest of this
+chapter describes how they operate.
+</para>
+<para>
+When a message is received over TCP/IP, the interface and port that were
+actually used are set in <varname>$received_ip_address</varname> and <varname>$received_port</varname>.
+</para>
+<section id="SECID89">
+<title>Starting a listening daemon</title>
+<para>
+When a listening daemon is started (by means of the <option>-bd</option> command line
+option), the interfaces and ports on which it listens are controlled by the
+following options:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<option>daemon_smtp_ports</option> contains a list of default ports
+or service names.
+(For backward compatibility, this option can also be specified in the singular.)
+</para>
+</listitem>
+<listitem>
+<para>
+<option>local_interfaces</option> contains list of interface IP addresses on which to
+listen. Each item may optionally also specify a port.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The default list separator in both cases is a colon, but this can be changed as
+described in section <xref linkend="SECTlistsepchange"/>. When IPv6 addresses are involved,
+it is usually best to change the separator to avoid having to double all the
+colons. For example:
+</para>
+<literallayout class="monospaced">
+local_interfaces = <; 127.0.0.1 ; \
+ 192.168.23.65 ; \
+ ::1 ; \
+ 3ffe:ffff:836f::fe86:a061
+</literallayout>
+<para>
+There are two different formats for specifying a port along with an IP address
+in <option>local_interfaces</option>:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+The port is added onto the address with a dot separator. For example, to listen
+on port 1234 on two different IP addresses:
+</para>
+<literallayout class="monospaced">
+local_interfaces = <; 192.168.23.65.1234 ; \
+ 3ffe:ffff:836f::fe86:a061.1234
+</literallayout>
+</listitem>
+<listitem>
+<para>
+The IP address is enclosed in square brackets, and the port is added
+with a colon separator, for example:
+</para>
+<literallayout class="monospaced">
+local_interfaces = <; [192.168.23.65]:1234 ; \
+ [3ffe:ffff:836f::fe86:a061]:1234
+</literallayout>
+</listitem>
+</orderedlist>
+<para>
+When a port is not specified, the value of <option>daemon_smtp_ports</option> is used. The
+default setting contains just one port:
+</para>
+<literallayout class="monospaced">
+daemon_smtp_ports = smtp
+</literallayout>
+<para>
+If more than one port is listed, each interface that does not have its own port
+specified listens on all of them. Ports that are listed in
+<option>daemon_smtp_ports</option> can be identified either by name (defined in
+<filename>/etc/services</filename>) or by number. However, when ports are given with individual
+IP addresses in <option>local_interfaces</option>, only numbers (not names) can be used.
+</para>
+</section>
+<section id="SECID90">
+<title>Special IP listening addresses</title>
+<para>
+The addresses 0.0.0.0 and ::0 are treated specially. They are interpreted
+as <quote>all IPv4 interfaces</quote> and <quote>all IPv6 interfaces</quote>, respectively. In each
+case, Exim tells the TCP/IP stack to <quote>listen on all IPv<emphasis>x</emphasis> interfaces</quote>
+instead of setting up separate listening sockets for each interface. The
+default value of <option>local_interfaces</option> is
+</para>
+<literallayout class="monospaced">
+local_interfaces = 0.0.0.0
+</literallayout>
+<para>
+when Exim is built without IPv6 support; otherwise it is:
+</para>
+<literallayout class="monospaced">
+local_interfaces = <; ::0 ; 0.0.0.0
+</literallayout>
+<para>
+Thus, by default, Exim listens on all available interfaces, on the SMTP port.
+</para>
+</section>
+<section id="SECID91">
+<title>Overriding local_interfaces and daemon_smtp_ports</title>
+<para>
+The <option>-oX</option> command line option can be used to override the values of
+<option>daemon_smtp_ports</option> and/or <option>local_interfaces</option> for a particular daemon
+instance. Another way of doing this would be to use macros and the <option>-D</option>
+option. However, <option>-oX</option> can be used by any admin user, whereas modification of
+the runtime configuration by <option>-D</option> is allowed only when the caller is root or
+exim.
+</para>
+<para>
+The value of <option>-oX</option> is a list of items. The default colon separator can be
+changed in the usual way (<xref linkend="SECTlistsepchange"/>) if required.
+If there are any items that do not
+contain dots or colons (that is, are not IP addresses), the value of
+<option>daemon_smtp_ports</option> is replaced by the list of those items. If there are any
+items that do contain dots or colons, the value of <option>local_interfaces</option> is
+replaced by those items. Thus, for example,
+</para>
+<literallayout class="monospaced">
+-oX 1225
+</literallayout>
+<para>
+overrides <option>daemon_smtp_ports</option>, but leaves <option>local_interfaces</option> unchanged,
+whereas
+</para>
+<literallayout class="monospaced">
+-oX 192.168.34.5.1125
+</literallayout>
+<para>
+overrides <option>local_interfaces</option>, leaving <option>daemon_smtp_ports</option> unchanged.
+(However, since <option>local_interfaces</option> now contains no items without ports, the
+value of <option>daemon_smtp_ports</option> is no longer relevant in this example.)
+</para>
+</section>
+<section id="SECTsupobssmt">
+<title>Support for the submissions (aka SSMTP or SMTPS) protocol</title>
+<para>
+<indexterm role="concept">
+<primary>submissions protocol</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>ssmtp protocol</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>smtps protocol</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>ssmtp protocol</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>smtps protocol</secondary>
+</indexterm>
+Exim supports the use of TLS-on-connect, used by mail clients in the
+<quote>submissions</quote> protocol, historically also known as SMTPS or SSMTP.
+For some years, IETF Standards Track documents only blessed the
+STARTTLS-based Submission service (port 587) while common practice was to support
+the same feature set on port 465, but using TLS-on-connect.
+If your installation needs to provide service to mail clients
+(Mail User Agents, MUAs) then you should provide service on both the 587 and
+the 465 TCP ports.
+</para>
+<para>
+If the <option>tls_on_connect_ports</option> option is set to a list of port numbers or
+service names, connections to those ports must first establish TLS, before
+proceeding to the application layer use of the SMTP protocol.
+</para>
+<para>
+The common use of this option is expected to be
+</para>
+<literallayout class="monospaced">
+tls_on_connect_ports = 465
+</literallayout>
+<para>
+per RFC 8314.
+There is also a command line option <option>-tls-on-connect</option>, which forces all ports
+to behave in this way when a daemon is started.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: Setting <option>tls_on_connect_ports</option> does not of itself cause the
+daemon to listen on those ports. You must still specify them in
+<option>daemon_smtp_ports</option>, <option>local_interfaces</option>, or the <option>-oX</option> option. (This is
+because <option>tls_on_connect_ports</option> applies to <option>inetd</option> connections as well as to
+connections via the daemon.)
+</para>
+</section>
+<section id="SECID92">
+<title>IPv6 address scopes</title>
+<para>
+<indexterm role="concept">
+<primary>IPv6</primary>
+<secondary>address scopes</secondary>
+</indexterm>
+IPv6 addresses have <quote>scopes</quote>, and a host with multiple hardware interfaces
+can, in principle, have the same link-local IPv6 address on different
+interfaces. Thus, additional information is needed, over and above the IP
+address, to distinguish individual interfaces. A convention of using a
+percent sign followed by something (often the interface name) has been
+adopted in some cases, leading to addresses like this:
+</para>
+<literallayout class="monospaced">
+fe80::202:b3ff:fe03:45c1%eth0
+</literallayout>
+<para>
+To accommodate this usage, a percent sign followed by an arbitrary string is
+allowed at the end of an IPv6 address. By default, Exim calls <function>getaddrinfo()</function>
+to convert a textual IPv6 address for actual use. This function recognizes the
+percent convention in operating systems that support it, and it processes the
+address appropriately. Unfortunately, some older libraries have problems with
+<function>getaddrinfo()</function>. If
+</para>
+<literallayout class="monospaced">
+IPV6_USE_INET_PTON=yes
+</literallayout>
+<para>
+is set in <filename>Local/Makefile</filename> (or an OS-dependent Makefile) when Exim is built,
+Exim uses <emphasis>inet_pton()</emphasis> to convert a textual IPv6 address for actual use,
+instead of <function>getaddrinfo()</function>. (Before version 4.14, it always used this
+function.) Of course, this means that the additional functionality of
+<function>getaddrinfo()</function> – recognizing scoped addresses – is lost.
+</para>
+</section>
+<section id="SECID93">
+<title>Disabling IPv6</title>
+<para>
+<indexterm role="concept">
+<primary>IPv6</primary>
+<secondary>disabling</secondary>
+</indexterm>
+Sometimes it happens that an Exim binary that was compiled with IPv6 support is
+run on a host whose kernel does not support IPv6. The binary will fall back to
+using IPv4, but it may waste resources looking up AAAA records, and trying to
+connect to IPv6 addresses, causing delays to mail delivery. If you set the
+<indexterm role="option">
+<primary><option>disable_ipv6</option></primary>
+</indexterm>
+<option>disable_ipv6</option> option true, even if the Exim binary has IPv6 support, no IPv6
+activities take place. AAAA records are never looked up, and any IPv6 addresses
+that are listed in <option>local_interfaces</option>, data for the <command>manualroute</command> router,
+etc. are ignored. If IP literals are enabled, the <command>ipliteral</command> router declines
+to handle IPv6 literal addresses.
+</para>
+<para>
+On the other hand, when IPv6 is in use, there may be times when you want to
+disable it for certain hosts or domains. You can use the <option>dns_ipv4_lookup</option>
+option to globally suppress the lookup of AAAA records for specified domains,
+and you can use the <option>ignore_target_hosts</option> generic router option to ignore
+IPv6 addresses in an individual router.
+</para>
+</section>
+<section id="SECID94">
+<title>Examples of starting a listening daemon</title>
+<para>
+The default case in an IPv6 environment is
+</para>
+<literallayout class="monospaced">
+daemon_smtp_ports = smtp
+local_interfaces = <; ::0 ; 0.0.0.0
+</literallayout>
+<para>
+This specifies listening on the smtp port on all IPv6 and IPv4 interfaces.
+Either one or two sockets may be used, depending on the characteristics of
+the TCP/IP stack. (This is complicated and messy; for more information,
+read the comments in the <filename>daemon.c</filename> source file.)
+</para>
+<para>
+To specify listening on ports 25 and 26 on all interfaces:
+</para>
+<literallayout class="monospaced">
+daemon_smtp_ports = 25 : 26
+</literallayout>
+<para>
+(leaving <option>local_interfaces</option> at the default setting) or, more explicitly:
+</para>
+<literallayout class="monospaced">
+local_interfaces = <; ::0.25 ; ::0.26 \
+ 0.0.0.0.25 ; 0.0.0.0.26
+</literallayout>
+<para>
+To listen on the default port on all IPv4 interfaces, and on port 26 on the
+IPv4 loopback address only:
+</para>
+<literallayout class="monospaced">
+local_interfaces = 0.0.0.0 : 127.0.0.1.26
+</literallayout>
+<para>
+To specify listening on the default port on specific interfaces only:
+</para>
+<literallayout class="monospaced">
+local_interfaces = 10.0.0.67 : 192.168.34.67
+</literallayout>
+<para>
+<emphasis role="bold">Warning</emphasis>: Such a setting excludes listening on the loopback interfaces.
+</para>
+</section>
+<section id="SECTreclocipadd">
+<title>Recognizing the local host</title>
+<para>
+The <option>local_interfaces</option> option is also used when Exim needs to determine
+whether or not an IP address refers to the local host. That is, the IP
+addresses of all the interfaces on which a daemon is listening are always
+treated as local.
+</para>
+<para>
+For this usage, port numbers in <option>local_interfaces</option> are ignored. If either of
+the items 0.0.0.0 or ::0 are encountered, Exim gets a complete list of
+available interfaces from the operating system, and extracts the relevant
+(that is, IPv4 or IPv6) addresses to use for checking.
+</para>
+<para>
+Some systems set up large numbers of virtual interfaces in order to provide
+many virtual web servers. In this situation, you may want to listen for
+email on only a few of the available interfaces, but nevertheless treat all
+interfaces as local when routing. You can do this by setting
+<option>extra_local_interfaces</option> to a list of IP addresses, possibly including the
+<quote>all</quote> wildcard values. These addresses are recognized as local, but are not
+used for listening. Consider this example:
+</para>
+<literallayout class="monospaced">
+local_interfaces = <; 127.0.0.1 ; ::1 ; \
+ 192.168.53.235 ; \
+ 3ffe:2101:12:1:a00:20ff:fe86:a061
+
+extra_local_interfaces = <; ::0 ; 0.0.0.0
+</literallayout>
+<para>
+The daemon listens on the loopback interfaces and just one IPv4 and one IPv6
+address, but all available interface addresses are treated as local when
+Exim is routing.
+</para>
+<para>
+In some environments the local host name may be in an MX list, but with an IP
+address that is not assigned to any local interface. In other cases it may be
+desirable to treat other host names as if they referred to the local host. Both
+these cases can be handled by setting the <option>hosts_treat_as_local</option> option.
+This contains host names rather than IP addresses. When a host is referenced
+during routing, either via an MX record or directly, it is treated as the local
+host if its name matches <option>hosts_treat_as_local</option>, or if any of its IP
+addresses match <option>local_interfaces</option> or <option>extra_local_interfaces</option>.
+</para>
+</section>
+<section id="SECID95">
+<title>Delivering to a remote host</title>
+<para>
+Delivery to a remote host is handled by the smtp transport. By default, it
+allows the system’s TCP/IP functions to choose which interface to use (if
+there is more than one) when connecting to a remote host. However, the
+<option>interface</option> option can be set to specify which interface is used. See the
+description of the smtp transport in chapter <xref linkend="CHAPsmtptrans"/> for more
+details.
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPmainconfig">
+<title>Main configuration</title>
+<para>
+<indexterm role="concept" id="IIDconfima" class="startofrange">
+<primary>configuration file</primary>
+<secondary>main section</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDmaiconf" class="startofrange">
+<primary>main configuration</primary>
+</indexterm>
+The first part of the runtime configuration file contains three types of item:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Macro definitions: These lines start with an upper case letter. See section
+<xref linkend="SECTmacrodefs"/> for details of macro processing.
+</para>
+</listitem>
+<listitem>
+<para>
+Named list definitions: These lines start with one of the words <quote>domainlist</quote>,
+<quote>hostlist</quote>, <quote>addresslist</quote>, or <quote>localpartlist</quote>. Their use is described in
+section <xref linkend="SECTnamedlists"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+Main configuration settings: Each setting occupies one line of the file
+(with possible continuations). If any setting is preceded by the word
+<quote>hide</quote>, the <option>-bP</option> command line option displays its value to admin users
+only. See section <xref linkend="SECTcos"/> for a description of the syntax of these option
+settings.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+This chapter specifies all the main configuration options, along with their
+types and default values. For ease of finding a particular option, they appear
+in alphabetical order in section <xref linkend="SECTalomo"/> below. However, because there
+are now so many options, they are first listed briefly in functional groups, as
+an aid to finding the name of the option you are looking for. Some options are
+listed in more than one group.
+</para>
+<section id="SECID96">
+<title>Miscellaneous</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>bi_command</option></entry>
+<entry>to run for <option>-bi</option> command line option</entry>
+</row>
+<row>
+<entry><option>debug_store</option></entry>
+<entry>do extra internal checks</entry>
+</row>
+<row>
+<entry><option>disable_ipv6</option></entry>
+<entry>do no IPv6 processing</entry>
+</row>
+<row>
+<entry><option>keep_malformed</option></entry>
+<entry>for broken files – should not happen</entry>
+</row>
+<row>
+<entry><option>localhost_number</option></entry>
+<entry>for unique message ids in clusters</entry>
+</row>
+<row>
+<entry><option>message_body_newlines</option></entry>
+<entry>retain newlines in <varname>$message_body</varname></entry>
+</row>
+<row>
+<entry><option>message_body_visible</option></entry>
+<entry>how much to show in <varname>$message_body</varname></entry>
+</row>
+<row>
+<entry><option>mua_wrapper</option></entry>
+<entry>run in <quote>MUA wrapper</quote> mode</entry>
+</row>
+<row>
+<entry><option>print_topbitchars</option></entry>
+<entry>top-bit characters are printing</entry>
+</row>
+<row>
+<entry><option>spool_wireformat</option></entry>
+<entry>use wire-format spool data files when possible</entry>
+</row>
+<row>
+<entry><option>timezone</option></entry>
+<entry>force time zone</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID97">
+<title>Exim parameters</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>exim_group</option></entry>
+<entry>override compiled-in value</entry>
+</row>
+<row>
+<entry><option>exim_path</option></entry>
+<entry>override compiled-in value</entry>
+</row>
+<row>
+<entry><option>exim_user</option></entry>
+<entry>override compiled-in value</entry>
+</row>
+<row>
+<entry><option>primary_hostname</option></entry>
+<entry>default from <function>uname()</function></entry>
+</row>
+<row>
+<entry><option>split_spool_directory</option></entry>
+<entry>use multiple directories</entry>
+</row>
+<row>
+<entry><option>spool_directory</option></entry>
+<entry>override compiled-in value</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID98">
+<title>Privilege controls</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>admin_groups</option></entry>
+<entry>groups that are Exim admin users</entry>
+</row>
+<row>
+<entry><option>commandline_checks_require_admin</option></entry>
+<entry>require admin for various checks</entry>
+</row>
+<row>
+<entry><option>deliver_drop_privilege</option></entry>
+<entry>drop root for delivery processes</entry>
+</row>
+<row>
+<entry><option>local_from_check</option></entry>
+<entry>insert <emphasis>Sender:</emphasis> if necessary</entry>
+</row>
+<row>
+<entry><option>local_from_prefix</option></entry>
+<entry>for testing <emphasis>From:</emphasis> for local sender</entry>
+</row>
+<row>
+<entry><option>local_from_suffix</option></entry>
+<entry>for testing <emphasis>From:</emphasis> for local sender</entry>
+</row>
+<row>
+<entry><option>local_sender_retain</option></entry>
+<entry>keep <emphasis>Sender:</emphasis> from untrusted user</entry>
+</row>
+<row>
+<entry><option>never_users</option></entry>
+<entry>do not run deliveries as these</entry>
+</row>
+<row>
+<entry><option>prod_requires_admin</option></entry>
+<entry>forced delivery requires admin user</entry>
+</row>
+<row>
+<entry><option>queue_list_requires_admin</option></entry>
+<entry>queue listing requires admin user</entry>
+</row>
+<row>
+<entry><option>trusted_groups</option></entry>
+<entry>groups that are trusted</entry>
+</row>
+<row>
+<entry><option>trusted_users</option></entry>
+<entry>users that are trusted</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID99">
+<title>Logging</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>event_action</option></entry>
+<entry>custom logging</entry>
+</row>
+<row>
+<entry><option>hosts_connection_nolog</option></entry>
+<entry>exemption from connect logging</entry>
+</row>
+<row>
+<entry><option>log_file_path</option></entry>
+<entry>override compiled-in value</entry>
+</row>
+<row>
+<entry><option>log_selector</option></entry>
+<entry>set/unset optional logging</entry>
+</row>
+<row>
+<entry><option>log_timezone</option></entry>
+<entry>add timezone to log lines</entry>
+</row>
+<row>
+<entry><option>message_logs</option></entry>
+<entry>create per-message logs</entry>
+</row>
+<row>
+<entry><option>preserve_message_logs</option></entry>
+<entry>after message completion</entry>
+</row>
+<row>
+<entry><option>process_log_path</option></entry>
+<entry>for SIGUSR1 and <emphasis>exiwhat</emphasis></entry>
+</row>
+<row>
+<entry><option>slow_lookup_log</option></entry>
+<entry>control logging of slow DNS lookups</entry>
+</row>
+<row>
+<entry><option>syslog_duplication</option></entry>
+<entry>controls duplicate log lines on syslog</entry>
+</row>
+<row>
+<entry><option>syslog_facility</option></entry>
+<entry>set syslog <quote>facility</quote> field</entry>
+</row>
+<row>
+<entry><option>syslog_pid</option></entry>
+<entry>pid in syslog lines</entry>
+</row>
+<row>
+<entry><option>syslog_processname</option></entry>
+<entry>set syslog <quote>ident</quote> field</entry>
+</row>
+<row>
+<entry><option>syslog_timestamp</option></entry>
+<entry>timestamp syslog lines</entry>
+</row>
+<row>
+<entry><option>write_rejectlog</option></entry>
+<entry>control use of message log</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID100">
+<title>Frozen messages</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>auto_thaw</option></entry>
+<entry>sets time for retrying frozen messages</entry>
+</row>
+<row>
+<entry><option>freeze_tell</option></entry>
+<entry>send message when freezing</entry>
+</row>
+<row>
+<entry><option>move_frozen_messages</option></entry>
+<entry>to another directory</entry>
+</row>
+<row>
+<entry><option>timeout_frozen_after</option></entry>
+<entry>keep frozen messages only so long</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID101">
+<title>Data lookups</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>ibase_servers</option></entry>
+<entry>InterBase servers</entry>
+</row>
+<row>
+<entry><option>ldap_ca_cert_dir</option></entry>
+<entry>dir of CA certs to verify LDAP server’s</entry>
+</row>
+<row>
+<entry><option>ldap_ca_cert_file</option></entry>
+<entry>file of CA certs to verify LDAP server’s</entry>
+</row>
+<row>
+<entry><option>ldap_cert_file</option></entry>
+<entry>client cert file for LDAP</entry>
+</row>
+<row>
+<entry><option>ldap_cert_key</option></entry>
+<entry>client key file for LDAP</entry>
+</row>
+<row>
+<entry><option>ldap_cipher_suite</option></entry>
+<entry>TLS negotiation preference control</entry>
+</row>
+<row>
+<entry><option>ldap_default_servers</option></entry>
+<entry>used if no server in query</entry>
+</row>
+<row>
+<entry><option>ldap_require_cert</option></entry>
+<entry>action to take without LDAP server cert</entry>
+</row>
+<row>
+<entry><option>ldap_start_tls</option></entry>
+<entry>require TLS within LDAP</entry>
+</row>
+<row>
+<entry><option>ldap_version</option></entry>
+<entry>set protocol version</entry>
+</row>
+<row>
+<entry><option>lookup_open_max</option></entry>
+<entry>lookup files held open</entry>
+</row>
+<row>
+<entry><option>mysql_servers</option></entry>
+<entry>default MySQL servers</entry>
+</row>
+<row>
+<entry><option>oracle_servers</option></entry>
+<entry>Oracle servers</entry>
+</row>
+<row>
+<entry><option>pgsql_servers</option></entry>
+<entry>default PostgreSQL servers</entry>
+</row>
+<row>
+<entry><option>sqlite_lock_timeout</option></entry>
+<entry>as it says</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID102">
+<title>Message ids</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>message_id_header_domain</option></entry>
+<entry>used to build <emphasis>Message-ID:</emphasis> header</entry>
+</row>
+<row>
+<entry><option>message_id_header_text</option></entry>
+<entry>ditto</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID103">
+<title>Embedded Perl Startup</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>perl_at_start</option></entry>
+<entry>always start the interpreter</entry>
+</row>
+<row>
+<entry><option>perl_startup</option></entry>
+<entry>code to obey when starting Perl</entry>
+</row>
+<row>
+<entry><option>perl_taintmode</option></entry>
+<entry>enable taint mode in Perl</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID104">
+<title>Daemon</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>daemon_smtp_ports</option></entry>
+<entry>default ports</entry>
+</row>
+<row>
+<entry><option>daemon_startup_retries</option></entry>
+<entry>number of times to retry</entry>
+</row>
+<row>
+<entry><option>daemon_startup_sleep</option></entry>
+<entry>time to sleep between tries</entry>
+</row>
+<row>
+<entry><option>extra_local_interfaces</option></entry>
+<entry>not necessarily listened on</entry>
+</row>
+<row>
+<entry><option>local_interfaces</option></entry>
+<entry>on which to listen, with optional ports</entry>
+</row>
+<row>
+<entry><option>notifier_socket</option></entry>
+<entry>override compiled-in value</entry>
+</row>
+<row>
+<entry><option>pid_file_path</option></entry>
+<entry>override compiled-in value</entry>
+</row>
+<row>
+<entry><option>queue_run_max</option></entry>
+<entry>maximum simultaneous queue runners</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID105">
+<title>Resource control</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>check_log_inodes</option></entry>
+<entry>before accepting a message</entry>
+</row>
+<row>
+<entry><option>check_log_space</option></entry>
+<entry>before accepting a message</entry>
+</row>
+<row>
+<entry><option>check_spool_inodes</option></entry>
+<entry>before accepting a message</entry>
+</row>
+<row>
+<entry><option>check_spool_space</option></entry>
+<entry>before accepting a message</entry>
+</row>
+<row>
+<entry><option>deliver_queue_load_max</option></entry>
+<entry>no queue deliveries if load high</entry>
+</row>
+<row>
+<entry><option>queue_only_load</option></entry>
+<entry>queue incoming if load high</entry>
+</row>
+<row>
+<entry><option>queue_only_load_latch</option></entry>
+<entry>don’t re-evaluate load for each message</entry>
+</row>
+<row>
+<entry><option>queue_run_max</option></entry>
+<entry>maximum simultaneous queue runners</entry>
+</row>
+<row>
+<entry><option>remote_max_parallel</option></entry>
+<entry>parallel SMTP delivery per message</entry>
+</row>
+<row>
+<entry><option>smtp_accept_max</option></entry>
+<entry>simultaneous incoming connections</entry>
+</row>
+<row>
+<entry><option>smtp_accept_max_nonmail</option></entry>
+<entry>non-mail commands</entry>
+</row>
+<row>
+<entry><option>smtp_accept_max_nonmail_hosts</option></entry>
+<entry>hosts to which the limit applies</entry>
+</row>
+<row>
+<entry><option>smtp_accept_max_per_connection</option></entry>
+<entry>messages per connection</entry>
+</row>
+<row>
+<entry><option>smtp_accept_max_per_host</option></entry>
+<entry>connections from one host</entry>
+</row>
+<row>
+<entry><option>smtp_accept_queue</option></entry>
+<entry>queue mail if more connections</entry>
+</row>
+<row>
+<entry><option>smtp_accept_queue_per_connection</option></entry>
+<entry>queue if more messages per connection</entry>
+</row>
+<row>
+<entry><option>smtp_accept_reserve</option></entry>
+<entry>only reserve hosts if more connections</entry>
+</row>
+<row>
+<entry><option>smtp_check_spool_space</option></entry>
+<entry>from SIZE on MAIL command</entry>
+</row>
+<row>
+<entry><option>smtp_connect_backlog</option></entry>
+<entry>passed to TCP/IP stack</entry>
+</row>
+<row>
+<entry><option>smtp_load_reserve</option></entry>
+<entry>SMTP from reserved hosts if load high</entry>
+</row>
+<row>
+<entry><option>smtp_reserve_hosts</option></entry>
+<entry>these are the reserve hosts</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID106">
+<title>Policy controls</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>acl_not_smtp</option></entry>
+<entry>ACL for non-SMTP messages</entry>
+</row>
+<row>
+<entry><option>acl_not_smtp_mime</option></entry>
+<entry>ACL for non-SMTP MIME parts</entry>
+</row>
+<row>
+<entry><option>acl_not_smtp_start</option></entry>
+<entry>ACL for start of non-SMTP message</entry>
+</row>
+<row>
+<entry><option>acl_smtp_auth</option></entry>
+<entry>ACL for AUTH</entry>
+</row>
+<row>
+<entry><option>acl_smtp_connect</option></entry>
+<entry>ACL for connection</entry>
+</row>
+<row>
+<entry><option>acl_smtp_data</option></entry>
+<entry>ACL for DATA</entry>
+</row>
+<row>
+<entry><option>acl_smtp_data_prdr</option></entry>
+<entry>ACL for DATA, per-recipient</entry>
+</row>
+<row>
+<entry><option>acl_smtp_dkim</option></entry>
+<entry>ACL for DKIM verification</entry>
+</row>
+<row>
+<entry><option>acl_smtp_etrn</option></entry>
+<entry>ACL for ETRN</entry>
+</row>
+<row>
+<entry><option>acl_smtp_expn</option></entry>
+<entry>ACL for EXPN</entry>
+</row>
+<row>
+<entry><option>acl_smtp_helo</option></entry>
+<entry>ACL for EHLO or HELO</entry>
+</row>
+<row>
+<entry><option>acl_smtp_mail</option></entry>
+<entry>ACL for MAIL</entry>
+</row>
+<row>
+<entry><option>acl_smtp_mailauth</option></entry>
+<entry>ACL for AUTH on MAIL command</entry>
+</row>
+<row>
+<entry><option>acl_smtp_mime</option></entry>
+<entry>ACL for MIME parts</entry>
+</row>
+<row>
+<entry><option>acl_smtp_notquit</option></entry>
+<entry>ACL for non-QUIT terminations</entry>
+</row>
+<row>
+<entry><option>acl_smtp_predata</option></entry>
+<entry>ACL for start of data</entry>
+</row>
+<row>
+<entry><option>acl_smtp_quit</option></entry>
+<entry>ACL for QUIT</entry>
+</row>
+<row>
+<entry><option>acl_smtp_rcpt</option></entry>
+<entry>ACL for RCPT</entry>
+</row>
+<row>
+<entry><option>acl_smtp_starttls</option></entry>
+<entry>ACL for STARTTLS</entry>
+</row>
+<row>
+<entry><option>acl_smtp_vrfy</option></entry>
+<entry>ACL for VRFY</entry>
+</row>
+<row>
+<entry><option>av_scanner</option></entry>
+<entry>specify virus scanner</entry>
+</row>
+<row>
+<entry><option>check_rfc2047_length</option></entry>
+<entry>check length of RFC 2047 <quote>encoded words</quote></entry>
+</row>
+<row>
+<entry><option>dns_cname_loops</option></entry>
+<entry>follow CNAMEs returned by resolver</entry>
+</row>
+<row>
+<entry><option>dns_csa_search_limit</option></entry>
+<entry>control CSA parent search depth</entry>
+</row>
+<row>
+<entry><option>dns_csa_use_reverse</option></entry>
+<entry>en/disable CSA IP reverse search</entry>
+</row>
+<row>
+<entry><option>header_maxsize</option></entry>
+<entry>total size of message header</entry>
+</row>
+<row>
+<entry><option>header_line_maxsize</option></entry>
+<entry>individual header line limit</entry>
+</row>
+<row>
+<entry><option>helo_accept_junk_hosts</option></entry>
+<entry>allow syntactic junk from these hosts</entry>
+</row>
+<row>
+<entry><option>helo_allow_chars</option></entry>
+<entry>allow illegal chars in HELO names</entry>
+</row>
+<row>
+<entry><option>helo_lookup_domains</option></entry>
+<entry>lookup hostname for these HELO names</entry>
+</row>
+<row>
+<entry><option>helo_try_verify_hosts</option></entry>
+<entry>HELO soft-checked for these hosts</entry>
+</row>
+<row>
+<entry><option>helo_verify_hosts</option></entry>
+<entry>HELO hard-checked for these hosts</entry>
+</row>
+<row>
+<entry><option>host_lookup</option></entry>
+<entry>host name looked up for these hosts</entry>
+</row>
+<row>
+<entry><option>host_lookup_order</option></entry>
+<entry>order of DNS and local name lookups</entry>
+</row>
+<row>
+<entry><option>hosts_proxy</option></entry>
+<entry>use proxy protocol for these hosts</entry>
+</row>
+<row>
+<entry><option>host_reject_connection</option></entry>
+<entry>reject connection from these hosts</entry>
+</row>
+<row>
+<entry><option>hosts_treat_as_local</option></entry>
+<entry>useful in some cluster configurations</entry>
+</row>
+<row>
+<entry><option>local_scan_timeout</option></entry>
+<entry>timeout for <function>local_scan()</function></entry>
+</row>
+<row>
+<entry><option>message_size_limit</option></entry>
+<entry>for all messages</entry>
+</row>
+<row>
+<entry><option>percent_hack_domains</option></entry>
+<entry>recognize %-hack for these domains</entry>
+</row>
+<row>
+<entry><option>spamd_address</option></entry>
+<entry>set interface to SpamAssassin</entry>
+</row>
+<row>
+<entry><option>strict_acl_vars</option></entry>
+<entry>object to unset ACL variables</entry>
+</row>
+<row>
+<entry><option>spf_smtp_comment_template</option></entry>
+<entry>template for <varname>$spf_smtp_comment</varname></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID107">
+<title>Callout cache</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>callout_domain_negative_expire</option></entry>
+<entry>timeout for negative domain cache item</entry>
+</row>
+<row>
+<entry><option>callout_domain_positive_expire</option></entry>
+<entry>timeout for positive domain cache item</entry>
+</row>
+<row>
+<entry><option>callout_negative_expire</option></entry>
+<entry>timeout for negative address cache item</entry>
+</row>
+<row>
+<entry><option>callout_positive_expire</option></entry>
+<entry>timeout for positive address cache item</entry>
+</row>
+<row>
+<entry><option>callout_random_local_part</option></entry>
+<entry>string to use for <quote>random</quote> testing</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID108">
+<title>TLS</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>gnutls_compat_mode</option></entry>
+<entry>use GnuTLS compatibility mode</entry>
+</row>
+<row>
+<entry><option>gnutls_allow_auto_pkcs11</option></entry>
+<entry>allow GnuTLS to autoload PKCS11 modules</entry>
+</row>
+<row>
+<entry><option>openssl_options</option></entry>
+<entry>adjust OpenSSL compatibility options</entry>
+</row>
+<row>
+<entry><option>tls_advertise_hosts</option></entry>
+<entry>advertise TLS to these hosts</entry>
+</row>
+<row>
+<entry><option>tls_certificate</option></entry>
+<entry>location of server certificate</entry>
+</row>
+<row>
+<entry><option>tls_crl</option></entry>
+<entry>certificate revocation list</entry>
+</row>
+<row>
+<entry><option>tls_dh_max_bits</option></entry>
+<entry>clamp D-H bit count suggestion</entry>
+</row>
+<row>
+<entry><option>tls_dhparam</option></entry>
+<entry>DH parameters for server</entry>
+</row>
+<row>
+<entry><option>tls_eccurve</option></entry>
+<entry>EC curve selection for server</entry>
+</row>
+<row>
+<entry><option>tls_ocsp_file</option></entry>
+<entry>location of server certificate status proof</entry>
+</row>
+<row>
+<entry><option>tls_on_connect_ports</option></entry>
+<entry>specify SSMTP (SMTPS) ports</entry>
+</row>
+<row>
+<entry><option>tls_privatekey</option></entry>
+<entry>location of server private key</entry>
+</row>
+<row>
+<entry><option>tls_remember_esmtp</option></entry>
+<entry>don’t reset after starting TLS</entry>
+</row>
+<row>
+<entry><option>tls_require_ciphers</option></entry>
+<entry>specify acceptable ciphers</entry>
+</row>
+<row>
+<entry><option>tls_try_verify_hosts</option></entry>
+<entry>try to verify client certificate</entry>
+</row>
+<row>
+<entry><option>tls_verify_certificates</option></entry>
+<entry>expected client certificates</entry>
+</row>
+<row>
+<entry><option>tls_verify_hosts</option></entry>
+<entry>insist on client certificate verify</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID109">
+<title>Local user handling</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>finduser_retries</option></entry>
+<entry>useful in NIS environments</entry>
+</row>
+<row>
+<entry><option>gecos_name</option></entry>
+<entry>used when creating <emphasis>Sender:</emphasis></entry>
+</row>
+<row>
+<entry><option>gecos_pattern</option></entry>
+<entry>ditto</entry>
+</row>
+<row>
+<entry><option>max_username_length</option></entry>
+<entry>for systems that truncate</entry>
+</row>
+<row>
+<entry><option>unknown_login</option></entry>
+<entry>used when no login name found</entry>
+</row>
+<row>
+<entry><option>unknown_username</option></entry>
+<entry>ditto</entry>
+</row>
+<row>
+<entry><option>uucp_from_pattern</option></entry>
+<entry>for recognizing <quote>From </quote> lines</entry>
+</row>
+<row>
+<entry><option>uucp_from_sender</option></entry>
+<entry>ditto</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID110">
+<title>All incoming messages (SMTP and non-SMTP)</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>header_maxsize</option></entry>
+<entry>total size of message header</entry>
+</row>
+<row>
+<entry><option>header_line_maxsize</option></entry>
+<entry>individual header line limit</entry>
+</row>
+<row>
+<entry><option>message_size_limit</option></entry>
+<entry>applies to all messages</entry>
+</row>
+<row>
+<entry><option>percent_hack_domains</option></entry>
+<entry>recognize %-hack for these domains</entry>
+</row>
+<row>
+<entry><option>received_header_text</option></entry>
+<entry>expanded to make <emphasis>Received:</emphasis></entry>
+</row>
+<row>
+<entry><option>received_headers_max</option></entry>
+<entry>for mail loop detection</entry>
+</row>
+<row>
+<entry><option>recipients_max</option></entry>
+<entry>limit per message</entry>
+</row>
+<row>
+<entry><option>recipients_max_reject</option></entry>
+<entry>permanently reject excess recipients</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID111">
+<title>Non-SMTP incoming messages</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>receive_timeout</option></entry>
+<entry>for non-SMTP messages</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID112">
+<title>Incoming SMTP messages</title>
+<para>
+See also the <emphasis>Policy controls</emphasis> section above.
+</para>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>dkim_verify_hashes</option></entry>
+<entry>DKIM hash methods accepted for signatures</entry>
+</row>
+<row>
+<entry><option>dkim_verify_keytypes</option></entry>
+<entry>DKIM key types accepted for signatures</entry>
+</row>
+<row>
+<entry><option>dkim_verify_min_keysizes</option></entry>
+<entry>DKIM key sizes accepted for signatures</entry>
+</row>
+<row>
+<entry><option>dkim_verify_signers</option></entry>
+<entry>DKIM domains for which DKIM ACL is run</entry>
+</row>
+<row>
+<entry><option>dmarc_forensic_sender</option></entry>
+<entry>DMARC sender for report messages</entry>
+</row>
+<row>
+<entry><option>dmarc_history_file</option></entry>
+<entry>DMARC results log</entry>
+</row>
+<row>
+<entry><option>dmarc_tld_file</option></entry>
+<entry>DMARC toplevel domains file</entry>
+</row>
+<row>
+<entry><option>host_lookup</option></entry>
+<entry>host name looked up for these hosts</entry>
+</row>
+<row>
+<entry><option>host_lookup_order</option></entry>
+<entry>order of DNS and local name lookups</entry>
+</row>
+<row>
+<entry><option>recipient_unqualified_hosts</option></entry>
+<entry>may send unqualified recipients</entry>
+</row>
+<row>
+<entry><option>rfc1413_hosts</option></entry>
+<entry>make ident calls to these hosts</entry>
+</row>
+<row>
+<entry><option>rfc1413_query_timeout</option></entry>
+<entry>zero disables ident calls</entry>
+</row>
+<row>
+<entry><option>sender_unqualified_hosts</option></entry>
+<entry>may send unqualified senders</entry>
+</row>
+<row>
+<entry><option>smtp_accept_keepalive</option></entry>
+<entry>some TCP/IP magic</entry>
+</row>
+<row>
+<entry><option>smtp_accept_max</option></entry>
+<entry>simultaneous incoming connections</entry>
+</row>
+<row>
+<entry><option>smtp_accept_max_nonmail</option></entry>
+<entry>non-mail commands</entry>
+</row>
+<row>
+<entry><option>smtp_accept_max_nonmail_hosts</option></entry>
+<entry>hosts to which the limit applies</entry>
+</row>
+<row>
+<entry><option>smtp_accept_max_per_connection</option></entry>
+<entry>messages per connection</entry>
+</row>
+<row>
+<entry><option>smtp_accept_max_per_host</option></entry>
+<entry>connections from one host</entry>
+</row>
+<row>
+<entry><option>smtp_accept_queue</option></entry>
+<entry>queue mail if more connections</entry>
+</row>
+<row>
+<entry><option>smtp_accept_queue_per_connection</option></entry>
+<entry>queue if more messages per connection</entry>
+</row>
+<row>
+<entry><option>smtp_accept_reserve</option></entry>
+<entry>only reserve hosts if more connections</entry>
+</row>
+<row>
+<entry><option>smtp_active_hostname</option></entry>
+<entry>host name to use in messages</entry>
+</row>
+<row>
+<entry><option>smtp_banner</option></entry>
+<entry>text for welcome banner</entry>
+</row>
+<row>
+<entry><option>smtp_check_spool_space</option></entry>
+<entry>from SIZE on MAIL command</entry>
+</row>
+<row>
+<entry><option>smtp_connect_backlog</option></entry>
+<entry>passed to TCP/IP stack</entry>
+</row>
+<row>
+<entry><option>smtp_enforce_sync</option></entry>
+<entry>of SMTP command/responses</entry>
+</row>
+<row>
+<entry><option>smtp_etrn_command</option></entry>
+<entry>what to run for ETRN</entry>
+</row>
+<row>
+<entry><option>smtp_etrn_serialize</option></entry>
+<entry>only one at once</entry>
+</row>
+<row>
+<entry><option>smtp_load_reserve</option></entry>
+<entry>only reserve hosts if this load</entry>
+</row>
+<row>
+<entry><option>smtp_max_unknown_commands</option></entry>
+<entry>before dropping connection</entry>
+</row>
+<row>
+<entry><option>smtp_ratelimit_hosts</option></entry>
+<entry>apply ratelimiting to these hosts</entry>
+</row>
+<row>
+<entry><option>smtp_ratelimit_mail</option></entry>
+<entry>ratelimit for MAIL commands</entry>
+</row>
+<row>
+<entry><option>smtp_ratelimit_rcpt</option></entry>
+<entry>ratelimit for RCPT commands</entry>
+</row>
+<row>
+<entry><option>smtp_receive_timeout</option></entry>
+<entry>per command or data line</entry>
+</row>
+<row>
+<entry><option>smtp_reserve_hosts</option></entry>
+<entry>these are the reserve hosts</entry>
+</row>
+<row>
+<entry><option>smtp_return_error_details</option></entry>
+<entry>give detail on rejections</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID113">
+<title>SMTP extensions</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>accept_8bitmime</option></entry>
+<entry>advertise 8BITMIME</entry>
+</row>
+<row>
+<entry><option>auth_advertise_hosts</option></entry>
+<entry>advertise AUTH to these hosts</entry>
+</row>
+<row>
+<entry><option>chunking_advertise_hosts</option></entry>
+<entry>advertise CHUNKING to these hosts</entry>
+</row>
+<row>
+<entry><option>dsn_advertise_hosts</option></entry>
+<entry>advertise DSN extensions to these hosts</entry>
+</row>
+<row>
+<entry><option>ignore_fromline_hosts</option></entry>
+<entry>allow <quote>From </quote> from these hosts</entry>
+</row>
+<row>
+<entry><option>ignore_fromline_local</option></entry>
+<entry>allow <quote>From </quote> from local SMTP</entry>
+</row>
+<row>
+<entry><option>pipelining_advertise_hosts</option></entry>
+<entry>advertise pipelining to these hosts</entry>
+</row>
+<row>
+<entry><option>pipelining_connect_advertise_hosts</option></entry>
+<entry>advertise pipelining to these hosts</entry>
+</row>
+<row>
+<entry><option>prdr_enable</option></entry>
+<entry>advertise PRDR to all hosts</entry>
+</row>
+<row>
+<entry><option>smtputf8_advertise_hosts</option></entry>
+<entry>advertise SMTPUTF8 to these hosts</entry>
+</row>
+<row>
+<entry><option>tls_advertise_hosts</option></entry>
+<entry>advertise TLS to these hosts</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID114">
+<title>Processing messages</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>allow_domain_literals</option></entry>
+<entry>recognize domain literal syntax</entry>
+</row>
+<row>
+<entry><option>allow_mx_to_ip</option></entry>
+<entry>allow MX to point to IP address</entry>
+</row>
+<row>
+<entry><option>allow_utf8_domains</option></entry>
+<entry>in addresses</entry>
+</row>
+<row>
+<entry><option>check_rfc2047_length</option></entry>
+<entry>check length of RFC 2047 <quote>encoded words</quote></entry>
+</row>
+<row>
+<entry><option>delivery_date_remove</option></entry>
+<entry>from incoming messages</entry>
+</row>
+<row>
+<entry><option>envelope_to_remove</option></entry>
+<entry>from incoming messages</entry>
+</row>
+<row>
+<entry><option>extract_addresses_remove_arguments</option></entry>
+<entry>affects <option>-t</option> processing</entry>
+</row>
+<row>
+<entry><option>headers_charset</option></entry>
+<entry>default for translations</entry>
+</row>
+<row>
+<entry><option>qualify_domain</option></entry>
+<entry>default for senders</entry>
+</row>
+<row>
+<entry><option>qualify_recipient</option></entry>
+<entry>default for recipients</entry>
+</row>
+<row>
+<entry><option>return_path_remove</option></entry>
+<entry>from incoming messages</entry>
+</row>
+<row>
+<entry><option>strip_excess_angle_brackets</option></entry>
+<entry>in addresses</entry>
+</row>
+<row>
+<entry><option>strip_trailing_dot</option></entry>
+<entry>at end of addresses</entry>
+</row>
+<row>
+<entry><option>untrusted_set_sender</option></entry>
+<entry>untrusted can set envelope sender</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID115">
+<title>System filter</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>system_filter</option></entry>
+<entry>locate system filter</entry>
+</row>
+<row>
+<entry><option>system_filter_directory_transport</option></entry>
+<entry>transport for delivery to a directory</entry>
+</row>
+<row>
+<entry><option>system_filter_file_transport</option></entry>
+<entry>transport for delivery to a file</entry>
+</row>
+<row>
+<entry><option>system_filter_group</option></entry>
+<entry>group for filter running</entry>
+</row>
+<row>
+<entry><option>system_filter_pipe_transport</option></entry>
+<entry>transport for delivery to a pipe</entry>
+</row>
+<row>
+<entry><option>system_filter_reply_transport</option></entry>
+<entry>transport for autoreply delivery</entry>
+</row>
+<row>
+<entry><option>system_filter_user</option></entry>
+<entry>user for filter running</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID116">
+<title>Routing and delivery</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>disable_ipv6</option></entry>
+<entry>do no IPv6 processing</entry>
+</row>
+<row>
+<entry><option>dns_again_means_nonexist</option></entry>
+<entry>for broken domains</entry>
+</row>
+<row>
+<entry><option>dns_check_names_pattern</option></entry>
+<entry>pre-DNS syntax check</entry>
+</row>
+<row>
+<entry><option>dns_dnssec_ok</option></entry>
+<entry>parameter for resolver</entry>
+</row>
+<row>
+<entry><option>dns_ipv4_lookup</option></entry>
+<entry>only v4 lookup for these domains</entry>
+</row>
+<row>
+<entry><option>dns_retrans</option></entry>
+<entry>parameter for resolver</entry>
+</row>
+<row>
+<entry><option>dns_retry</option></entry>
+<entry>parameter for resolver</entry>
+</row>
+<row>
+<entry><option>dns_trust_aa</option></entry>
+<entry>DNS zones trusted as authentic</entry>
+</row>
+<row>
+<entry><option>dns_use_edns0</option></entry>
+<entry>parameter for resolver</entry>
+</row>
+<row>
+<entry><option>hold_domains</option></entry>
+<entry>hold delivery for these domains</entry>
+</row>
+<row>
+<entry><option>local_interfaces</option></entry>
+<entry>for routing checks</entry>
+</row>
+<row>
+<entry><option>queue_domains</option></entry>
+<entry>no immediate delivery for these</entry>
+</row>
+<row>
+<entry><option>queue_only</option></entry>
+<entry>no immediate delivery at all</entry>
+</row>
+<row>
+<entry><option>queue_only_file</option></entry>
+<entry>no immediate delivery if file exists</entry>
+</row>
+<row>
+<entry><option>queue_only_load</option></entry>
+<entry>no immediate delivery if load is high</entry>
+</row>
+<row>
+<entry><option>queue_only_load_latch</option></entry>
+<entry>don’t re-evaluate load for each message</entry>
+</row>
+<row>
+<entry><option>queue_only_override</option></entry>
+<entry>allow command line to override</entry>
+</row>
+<row>
+<entry><option>queue_run_in_order</option></entry>
+<entry>order of arrival</entry>
+</row>
+<row>
+<entry><option>queue_run_max</option></entry>
+<entry>of simultaneous queue runners</entry>
+</row>
+<row>
+<entry><option>queue_smtp_domains</option></entry>
+<entry>no immediate SMTP delivery for these</entry>
+</row>
+<row>
+<entry><option>remote_max_parallel</option></entry>
+<entry>parallel SMTP delivery per message</entry>
+</row>
+<row>
+<entry><option>remote_sort_domains</option></entry>
+<entry>order of remote deliveries</entry>
+</row>
+<row>
+<entry><option>retry_data_expire</option></entry>
+<entry>timeout for retry data</entry>
+</row>
+<row>
+<entry><option>retry_interval_max</option></entry>
+<entry>safety net for retry rules</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECID117">
+<title>Bounce and warning messages</title>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><option>bounce_message_file</option></entry>
+<entry>content of bounce</entry>
+</row>
+<row>
+<entry><option>bounce_message_text</option></entry>
+<entry>content of bounce</entry>
+</row>
+<row>
+<entry><option>bounce_return_body</option></entry>
+<entry>include body if returning message</entry>
+</row>
+<row>
+<entry><option>bounce_return_linesize_limit</option></entry>
+<entry>limit on returned message line length</entry>
+</row>
+<row>
+<entry><option>bounce_return_message</option></entry>
+<entry>include original message in bounce</entry>
+</row>
+<row>
+<entry><option>bounce_return_size_limit</option></entry>
+<entry>limit on returned message</entry>
+</row>
+<row>
+<entry><option>bounce_sender_authentication</option></entry>
+<entry>send authenticated sender with bounce</entry>
+</row>
+<row>
+<entry><option>dsn_from</option></entry>
+<entry>set <emphasis>From:</emphasis> contents in bounces</entry>
+</row>
+<row>
+<entry><option>errors_copy</option></entry>
+<entry>copy bounce messages</entry>
+</row>
+<row>
+<entry><option>errors_reply_to</option></entry>
+<entry><emphasis>Reply-to:</emphasis> in bounces</entry>
+</row>
+<row>
+<entry><option>delay_warning</option></entry>
+<entry>time schedule</entry>
+</row>
+<row>
+<entry><option>delay_warning_condition</option></entry>
+<entry>condition for warning messages</entry>
+</row>
+<row>
+<entry><option>ignore_bounce_errors_after</option></entry>
+<entry>discard undeliverable bounces</entry>
+</row>
+<row>
+<entry><option>smtp_return_error_details</option></entry>
+<entry>give detail on rejections</entry>
+</row>
+<row>
+<entry><option>warn_message_file</option></entry>
+<entry>content of warning message</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+</section>
+<section id="SECTalomo">
+<title>Alphabetical list of main options</title>
+<para>
+Those options that undergo string expansion before use are marked with
+†.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>accept_8bitmime</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>accept_8bitmime</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>8BITMIME</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>8-bit characters</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>selectors</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>8BITMIME</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>8BITMIME</secondary>
+</indexterm>
+This option causes Exim to send 8BITMIME in its response to an SMTP
+EHLO command, and to accept the BODY= parameter on MAIL commands.
+However, though Exim is 8-bit clean, it is not a protocol converter, and it
+takes no steps to do anything special with messages received by this route.
+</para>
+<para>
+Historically Exim kept this option off by default, but the maintainers
+feel that in today’s Internet, this causes more problems than it solves.
+It now defaults to true.
+A more detailed analysis of the issues is provided by Dan Bernstein:
+</para>
+<literallayout>
+<emphasis role="bold"><ulink url="https://cr.yp.to/smtp/8bitmime.html">https://cr.yp.to/smtp/8bitmime.html</ulink></emphasis>
+</literallayout>
+<para>
+To log received 8BITMIME status use
+</para>
+<literallayout class="monospaced">
+log_selector = +8bitmime
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>acl_not_smtp</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_not_smtp</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>for non-SMTP messages</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>non-SMTP messages</primary>
+<secondary>ACLs for</secondary>
+</indexterm>
+This option defines the ACL that is run when a non-SMTP message has been
+read and is on the point of being accepted. See chapter <xref linkend="CHAPACL"/> for
+further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_not_smtp_mime</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_not_smtp_mime</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option defines the ACL that is run for individual MIME parts of non-SMTP
+messages. It operates in exactly the same way as <option>acl_smtp_mime</option> operates for
+SMTP messages.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_not_smtp_start</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_not_smtp_start</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>at start of non-SMTP message</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>non-SMTP messages</primary>
+<secondary>ACLs for</secondary>
+</indexterm>
+This option defines the ACL that is run before Exim starts reading a
+non-SMTP message. See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_auth</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_auth</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>setting up for SMTP commands</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+This option defines the ACL that is run when an SMTP AUTH command is
+received. See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_connect</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_connect</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>on SMTP connection</secondary>
+</indexterm>
+This option defines the ACL that is run when an SMTP connection is received.
+See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_data</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_data</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DATA</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+This option defines the ACL that is run after an SMTP DATA command has been
+processed and the message itself has been received, but before the final
+acknowledgment is sent. See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_data_prdr</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_data_prdr</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>accept</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>PRDR</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DATA</primary>
+<secondary>PRDR ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>PRDR-related</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>per-user data processing</secondary>
+</indexterm>
+This option defines the ACL that,
+if the PRDR feature has been negotiated,
+is run for each recipient after an SMTP DATA command has been
+processed and the message itself has been received, but before the
+acknowledgment is sent. See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_dkim</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_dkim</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DKIM</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+This option defines the ACL that is run for each DKIM signature
+(by default, or as specified in the dkim_verify_signers option)
+of a received message.
+See section <xref linkend="SECDKIMVFY"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_etrn</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_etrn</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>ETRN</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+This option defines the ACL that is run when an SMTP ETRN command is
+received. See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_expn</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_expn</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>EXPN</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+This option defines the ACL that is run when an SMTP EXPN command is
+received. See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_helo</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_helo</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>EHLO</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>HELO</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+This option defines the ACL that is run when an SMTP EHLO or HELO
+command is received. See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_mail</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_mail</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>MAIL</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+This option defines the ACL that is run when an SMTP MAIL command is
+received. See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_mailauth</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_mailauth</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>on MAIL command</secondary>
+</indexterm>
+This option defines the ACL that is run when there is an AUTH parameter on
+a MAIL command. See chapter <xref linkend="CHAPACL"/> for details of ACLs, and chapter
+<xref linkend="CHAPSMTPAUTH"/> for details of authentication.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_mime</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_mime</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>MIME content scanning</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+This option is available when Exim is built with the content-scanning
+extension. It defines the ACL that is run for each MIME part in a message. See
+section <xref linkend="SECTscanmimepart"/> for details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_notquit</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_notquit</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>not-QUIT, ACL for</primary>
+</indexterm>
+This option defines the ACL that is run when an SMTP session
+ends without a QUIT command being received.
+See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_predata</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_predata</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option defines the ACL that is run when an SMTP DATA command is
+received, before the message itself is received. See chapter <xref linkend="CHAPACL"/> for
+further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_quit</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_quit</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>QUIT, ACL for</primary>
+</indexterm>
+This option defines the ACL that is run when an SMTP QUIT command is
+received. See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_rcpt</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_rcpt</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>RCPT</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+This option defines the ACL that is run when an SMTP RCPT command is
+received. See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_starttls</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_starttls</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>STARTTLS, ACL for</primary>
+</indexterm>
+This option defines the ACL that is run when an SMTP STARTTLS command is
+received. See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>acl_smtp_vrfy</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>acl_smtp_vrfy</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>VRFY</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+This option defines the ACL that is run when an SMTP VRFY command is
+received. See chapter <xref linkend="CHAPACL"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>add_environment</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>add_environment</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>empty</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>environment</primary>
+<secondary>set values</secondary>
+</indexterm>
+This option adds individual environment variables that the
+currently linked libraries and programs in child processes may use.
+Each list element should be of the form <quote>name=value</quote>.
+</para>
+<para>
+See <xref linkend="SECTpipeenv"/> for the environment of <command>pipe</command> transports.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>admin_groups</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>admin_groups</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>admin user</primary>
+</indexterm>
+This option is expanded just once, at the start of Exim’s processing. If the
+current group or any of the supplementary groups of an Exim caller is in this
+colon-separated list, the caller has admin privileges. If all your system
+programmers are in a specific group, for example, you can give them all Exim
+admin privileges by putting that group in <option>admin_groups</option>. However, this does
+not permit them to read Exim’s spool files (whose group owner is the Exim gid).
+To permit this, you have to add individuals to the Exim group.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>allow_domain_literals</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>allow_domain_literals</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>domain literal</primary>
+</indexterm>
+If this option is set, the RFC 2822 domain literal format is permitted in
+email addresses. The option is not set by default, because the domain literal
+format is not normally required these days, and few people know about it. It
+has, however, been exploited by mail abusers.
+</para>
+<para>
+Unfortunately, it seems that some DNS black list maintainers are using this
+format to report black listing to postmasters. If you want to accept messages
+addressed to your hosts by IP address, you need to set
+<option>allow_domain_literals</option> true, and also to add <literal>@[]</literal> to the list of local
+domains (defined in the named domain list <option>local_domains</option> in the default
+configuration). This <quote>magic string</quote> matches the domain literal form of all
+the local host’s IP addresses.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>allow_mx_to_ip</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>allow_mx_to_ip</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>MX record</primary>
+<secondary>pointing to IP address</secondary>
+</indexterm>
+It appears that more and more DNS zone administrators are breaking the rules
+and putting domain names that look like IP addresses on the right hand side of
+MX records. Exim follows the rules and rejects this, giving an error message
+that explains the misconfiguration. However, some other MTAs support this
+practice, so to avoid <quote>Why can’t Exim do this?</quote> complaints,
+<option>allow_mx_to_ip</option> exists, in order to enable this heinous activity. It is not
+recommended, except when you have no other choice.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>allow_utf8_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>allow_utf8_domains</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>domain</primary>
+<secondary>UTF-8 characters in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>UTF-8</primary>
+<secondary>in domain name</secondary>
+</indexterm>
+Lots of discussion is going on about internationalized domain names. One
+camp is strongly in favour of just using UTF-8 characters, and it seems
+that at least two other MTAs permit this.
+This option allows Exim users to experiment if they wish.
+</para>
+<para>
+If it is set true, Exim’s domain parsing function allows valid
+UTF-8 multicharacters to appear in domain name components, in addition to
+letters, digits, and hyphens.
+</para>
+<para>
+If Exim is built with internationalization support
+and the SMTPUTF8 ESMTP option is in use (see chapter <xref linkend="CHAPi18n"/>)
+this option can be left as default.
+Without that,
+if you want to look up such domain names in the DNS, you must also
+adjust the value of <option>dns_check_names_pattern</option> to match the extended form. A
+suitable setting is:
+</para>
+<literallayout class="monospaced">
+dns_check_names_pattern = (?i)^(?>(?(1)\.|())[a-z0-9\xc0-\xff]\
+ (?>[-a-z0-9\x80-\xff]*[a-z0-9\x80-\xbf])?)+$
+</literallayout>
+<para>
+Alternatively, you can just disable this feature by setting
+</para>
+<literallayout class="monospaced">
+dns_check_names_pattern =
+</literallayout>
+<para>
+That is, set the option to an empty string so that no check is done.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>auth_advertise_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>auth_advertise_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>advertising</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>advertising</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>AUTH</secondary>
+</indexterm>
+If any server authentication mechanisms are configured, Exim advertises them in
+response to an EHLO command only if the calling host matches this list.
+Otherwise, Exim does not advertise AUTH.
+Exim does not accept AUTH commands from clients to which it has not
+advertised the availability of AUTH. The advertising of individual
+authentication mechanisms can be controlled by the use of the
+<option>server_advertise_condition</option> generic authenticator option on the individual
+authenticators. See chapter <xref linkend="CHAPSMTPAUTH"/> for further details.
+</para>
+<para>
+Certain mail clients (for example, Netscape) require the user to provide a name
+and password for authentication if AUTH is advertised, even though it may
+not be needed (the host may accept messages from hosts on its local LAN without
+authentication, for example). The <option>auth_advertise_hosts</option> option can be used
+to make these clients more friendly by excluding them from the set of hosts to
+which Exim advertises AUTH.
+</para>
+<para>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>advertising when encrypted</secondary>
+</indexterm>
+If you want to advertise the availability of AUTH only when the connection
+is encrypted using TLS, you can make use of the fact that the value of this
+option is expanded, with a setting like this:
+</para>
+<literallayout class="monospaced">
+auth_advertise_hosts = ${if eq{$tls_in_cipher}{}{}{*}}
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_cipher</varname></primary>
+</indexterm>
+If <varname>$tls_in_cipher</varname> is empty, the session is not encrypted, and the result of
+the expansion is empty, thus matching no hosts. Otherwise, the result of the
+expansion is *, which matches all hosts.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>auto_thaw</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>auto_thaw</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>0s</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>thawing messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>unfreezing messages</primary>
+</indexterm>
+If this option is set to a time greater than zero, a queue runner will try a
+new delivery attempt on any frozen message, other than a bounce message, if
+this much time has passed since it was frozen. This may result in the message
+being re-frozen if nothing has changed since the last attempt. It is a way of
+saying <quote>keep on trying, even though there are big problems</quote>.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: This is an old option, which predates <option>timeout_frozen_after</option> and
+<option>ignore_bounce_errors_after</option>. It is retained for compatibility, but it is not
+thought to be very useful any more, and its use should probably be avoided.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>av_scanner</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>av_scanner</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option is available if Exim is built with the content-scanning extension.
+It specifies which anti-virus scanner to use. The default value is:
+</para>
+<literallayout class="monospaced">
+sophie:/var/run/sophie
+</literallayout>
+<para>
+If the value of <option>av_scanner</option> starts with a dollar character, it is expanded
+before use. See section <xref linkend="SECTscanvirus"/> for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>bi_command</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>bi_command</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="option">
+<primary><option>-bi</option></primary>
+</indexterm>
+This option supplies the name of a command that is run when Exim is called with
+the <option>-bi</option> option (see chapter <xref linkend="CHAPcommandline"/>). The string value is
+just the command name, it is not a complete command line. If an argument is
+required, it must come from the <option>-oA</option> command line option.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>bounce_message_file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>bounce_message_file</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>customizing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>customizing</primary>
+<secondary>bounce message</secondary>
+</indexterm>
+This option defines a template file containing paragraphs of text to be used
+for constructing bounce messages. Details of the file’s contents are given in
+chapter <xref linkend="CHAPemsgcust"/>.
+</para>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>bounce_message_file</primary>
+<secondary>tainted data</secondary>
+</indexterm>
+The option is expanded to give the file path, which must be
+absolute and untainted.
+</para>
+<para>
+See also <option>warn_message_file</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>bounce_message_text</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>bounce_message_text</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+When this option is set, its contents are included in the default bounce
+message immediately after <quote>This message was created automatically by mail
+delivery software.</quote> It is not used if <option>bounce_message_file</option> is set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>bounce_return_body</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>bounce_return_body</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>including body</secondary>
+</indexterm>
+This option controls whether the body of an incoming message is included in a
+bounce message when <option>bounce_return_message</option> is true. The default setting
+causes the entire message, both header and body, to be returned (subject to the
+value of <option>bounce_return_size_limit</option>). If this option is false, only the
+message header is included. In the case of a non-SMTP message containing an
+error that is detected during reception, only those header lines preceding the
+point at which the error was detected are returned.
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>including original</secondary>
+</indexterm>
+</para>
+<para>
+<indexterm role="option">
+<primary><option>bounce_return_linesize_limit</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>bounce_return_linesize_limit</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>998</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>size</primary>
+<secondary>of bounce lines, limit</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>line length limit</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>bounce message line length</secondary>
+</indexterm>
+This option sets a limit in bytes on the line length of messages
+that are returned to senders due to delivery problems,
+when <option>bounce_return_message</option> is true.
+The default value corresponds to RFC limits.
+If the message being returned has lines longer than this value it is
+treated as if the <option>bounce_return_size_limit</option> (below) restriction was exceeded.
+</para>
+<para>
+The option also applies to bounces returned when an error is detected
+during reception of a message.
+In this case lines from the original are truncated.
+</para>
+<para>
+The option does not apply to messages generated by an <command>autoreply</command> transport.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>bounce_return_message</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>bounce_return_message</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is set false, none of the original message is included in
+bounce messages generated by Exim. See also <option>bounce_return_size_limit</option> and
+<option>bounce_return_body</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>bounce_return_size_limit</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>bounce_return_size_limit</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>100K</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>size</primary>
+<secondary>of bounce, limit</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>size limit</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>bounce message size</secondary>
+</indexterm>
+This option sets a limit in bytes on the size of messages that are returned to
+senders as part of bounce messages when <option>bounce_return_message</option> is true. The
+limit should be less than the value of the global <option>message_size_limit</option> and of
+any <option>message_size_limit</option> settings on transports, to allow for the bounce text
+that Exim generates. If this option is set to zero there is no limit.
+</para>
+<para>
+When the body of any message that is to be included in a bounce message is
+greater than the limit, it is truncated, and a comment pointing this out is
+added at the top. The actual cutoff may be greater than the value given, owing
+to the use of buffering for transferring the message in chunks (typically 8K in
+size). The idea is to save bandwidth on those undeliverable 15-megabyte
+messages.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>bounce_sender_authentication</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>bounce_sender_authentication</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>sender authentication</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>bounce message</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>on bounce message</secondary>
+</indexterm>
+This option provides an authenticated sender address that is sent with any
+bounce messages generated by Exim that are sent over an authenticated SMTP
+connection. A typical setting might be:
+</para>
+<literallayout class="monospaced">
+bounce_sender_authentication = mailer-daemon@my.domain.example
+</literallayout>
+<para>
+which would cause bounce messages to be sent using the SMTP command:
+</para>
+<literallayout class="monospaced">
+MAIL FROM:<> AUTH=mailer-daemon@my.domain.example
+</literallayout>
+<para>
+The value of <option>bounce_sender_authentication</option> must always be a complete email
+address.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>callout_domain_negative_expire</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>callout_domain_negative_expire</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>3h</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>caching</primary>
+<secondary>callout timeouts</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary>caching timeouts</secondary>
+</indexterm>
+This option specifies the expiry time for negative callout cache data for a
+domain. See section <xref linkend="SECTcallver"/> for details of callout verification, and
+section <xref linkend="SECTcallvercache"/> for details of the caching.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>callout_domain_positive_expire</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>callout_domain_positive_expire</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>7d</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies the expiry time for positive callout cache data for a
+domain. See section <xref linkend="SECTcallver"/> for details of callout verification, and
+section <xref linkend="SECTcallvercache"/> for details of the caching.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>callout_negative_expire</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>callout_negative_expire</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>2h</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies the expiry time for negative callout cache data for an
+address. See section <xref linkend="SECTcallver"/> for details of callout verification, and
+section <xref linkend="SECTcallvercache"/> for details of the caching.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>callout_positive_expire</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>callout_positive_expire</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>24h</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies the expiry time for positive callout cache data for an
+address. See section <xref linkend="SECTcallver"/> for details of callout verification, and
+section <xref linkend="SECTcallvercache"/> for details of the caching.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>callout_random_local_part</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>callout_random_local_part</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option defines the <quote>random</quote> local part that can be used as part of
+callout verification. The default value is
+</para>
+<literallayout class="monospaced">
+$primary_hostname-$tod_epoch-testing
+</literallayout>
+<para>
+See section <xref linkend="CALLaddparcall"/> for details of how this value is used.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_log_inodes</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_log_inodes</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>100</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>check_spool_space</option> below.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_log_space</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_log_space</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>10M</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>check_spool_space</option> below.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_rfc2047_length</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>RFC 2047</primary>
+<secondary>disabling length check</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>check_rfc2047_length</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_rfc2047_length</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+RFC 2047 defines a way of encoding non-ASCII characters in headers using a
+system of <quote>encoded words</quote>. The RFC specifies a maximum length for an encoded
+word; strings to be encoded that exceed this length are supposed to use
+multiple encoded words. By default, Exim does not recognize encoded words that
+exceed the maximum length. However, it seems that some software, in violation
+of the RFC, generates overlong encoded words. If <option>check_rfc2047_length</option> is
+set false, Exim recognizes encoded words of any length.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_spool_inodes</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_spool_inodes</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>100</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>check_spool_space</option> below.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_spool_space</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_spool_space</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>10M</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>checking disk space</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>disk space, checking</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>spool directory</primary>
+<secondary>checking space</secondary>
+</indexterm>
+The four <option>check_...</option> options allow for checking of disk resources before a
+message is accepted.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$log_inodes</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$log_space</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$spool_inodes</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$spool_space</varname></primary>
+</indexterm>
+When any of these options are nonzero, they apply to all incoming messages. If you
+want to apply different checks to different kinds of message, you can do so by
+testing the variables <varname>$log_inodes</varname>, <varname>$log_space</varname>, <varname>$spool_inodes</varname>, and
+<varname>$spool_space</varname> in an ACL with appropriate additional conditions.
+</para>
+<para>
+<option>check_spool_space</option> and <option>check_spool_inodes</option> check the spool partition if
+either value is greater than zero, for example:
+</para>
+<literallayout class="monospaced">
+check_spool_space = 100M
+check_spool_inodes = 100
+</literallayout>
+<para>
+The spool partition is the one that contains the directory defined by
+SPOOL_DIRECTORY in <filename>Local/Makefile</filename>. It is used for holding messages in
+transit.
+</para>
+<para>
+<option>check_log_space</option> and <option>check_log_inodes</option> check the partition in which log
+files are written if either is greater than zero. These should be set only if
+<option>log_file_path</option> and <option>spool_directory</option> refer to different partitions.
+</para>
+<para>
+If there is less space or fewer inodes than requested, Exim refuses to accept
+incoming mail. In the case of SMTP input this is done by giving a 452 temporary
+error response to the MAIL command. If ESMTP is in use and there was a
+SIZE parameter on the MAIL command, its value is added to the
+<option>check_spool_space</option> value, and the check is performed even if
+<option>check_spool_space</option> is zero, unless <option>no_smtp_check_spool_space</option> is set.
+</para>
+<para>
+The values for <option>check_spool_space</option> and <option>check_log_space</option> are held as a
+number of kilobytes (though specified in bytes).
+If a non-multiple of 1024 is specified, it is rounded up.
+</para>
+<para>
+For non-SMTP input and for batched SMTP input, the test is done at start-up; on
+failure a message is written to stderr and Exim exits with a non-zero code, as
+it obviously cannot send an error message of any kind.
+</para>
+<para>
+There is a slight performance penalty for these checks.
+Versions of Exim preceding 4.88 had these disabled by default;
+high-rate installations confident they will never run out of resources
+may wish to deliberately disable them.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>chunking_advertise_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>chunking_advertise_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>CHUNKING</primary>
+<secondary>advertisement</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>RFC 3030</primary>
+<secondary>CHUNKING</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>CHUNKING</secondary>
+</indexterm>
+The CHUNKING extension (RFC3030) will be advertised in the EHLO message to
+these hosts.
+Hosts may use the BDAT command as an alternate to DATA.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>commandline_checks_require_admin</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>commandline_checks_require_admin</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis><literal>false</literal></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+This option restricts various basic checking features to require an
+administrative user.
+This affects most of the <option>-b*</option> options, such as <option>-be</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>debug_store</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>debug_store</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis><literal>false</literal></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>debugging</primary>
+<secondary>memory corruption</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>memory</primary>
+<secondary>debugging</secondary>
+</indexterm>
+This option, when true, enables extra checking in Exim’s internal memory
+management. For use when a memory corruption issue is being investigated,
+it should normally be left as default.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>daemon_smtp_ports</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>daemon_smtp_ports</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis><literal>smtp</literal></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>port</primary>
+<secondary>for daemon</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP/IP</primary>
+<secondary>setting listening ports</secondary>
+</indexterm>
+This option specifies one or more default SMTP ports on which the Exim daemon
+listens. See chapter <xref linkend="CHAPinterfaces"/> for details of how it is used. For
+backward compatibility, <option>daemon_smtp_port</option> (singular) is a synonym.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>daemon_startup_retries</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>daemon_startup_retries</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>9</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>daemon startup, retrying</primary>
+</indexterm>
+This option, along with <option>daemon_startup_sleep</option>, controls the retrying done by
+the daemon at startup when it cannot immediately bind a listening socket
+(typically because the socket is already in use): <option>daemon_startup_retries</option>
+defines the number of retries after the first failure, and
+<option>daemon_startup_sleep</option> defines the length of time to wait between retries.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>daemon_startup_sleep</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>daemon_startup_sleep</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>30s</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>daemon_startup_retries</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>delay_warning</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>delay_warning</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time list</emphasis></entry>
+<entry>Default: <emphasis>24h</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>warning of delay</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>delay warning, specifying</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>delay warning</secondary>
+</indexterm>
+When a message is delayed, Exim sends a warning message to the sender at
+intervals specified by this option. The data is a colon-separated list of times
+after which to send warning messages. If the value of the option is an empty
+string or a zero time, no warnings are sent. Up to 10 times may be given. If a
+message has been in the queue for longer than the last time, the last interval
+between the times is used to compute subsequent warning times. For example,
+with
+</para>
+<literallayout class="monospaced">
+delay_warning = 4h:8h:24h
+</literallayout>
+<para>
+the first message is sent after 4 hours, the second after 8 hours, and
+the third one after 24 hours. After that, messages are sent every 16 hours,
+because that is the interval between the last two times on the list. If you set
+just one time, it specifies the repeat interval. For example, with:
+</para>
+<literallayout class="monospaced">
+delay_warning = 6h
+</literallayout>
+<para>
+messages are repeated every six hours. To stop warnings after a given time, set
+a very large time at the end of the list. For example:
+</para>
+<literallayout class="monospaced">
+delay_warning = 2h:12h:99d
+</literallayout>
+<para>
+Note that the option is only evaluated at the time a delivery attempt fails,
+which depends on retry and queue-runner configuration.
+Typically retries will be configured more frequently than warning messages.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>delay_warning_condition</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>delay_warning_condition</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+The string is expanded at the time a warning message might be sent. If all the
+deferred addresses have the same domain, it is set in <varname>$domain</varname> during the
+expansion. Otherwise <varname>$domain</varname> is empty. If the result of the expansion is a
+forced failure, an empty string, or a string matching any of <quote>0</quote>, <quote>no</quote> or
+<quote>false</quote> (the comparison being done caselessly) then the warning message is
+not sent. The default is:
+</para>
+<literallayout class="monospaced">
+delay_warning_condition = ${if or {\
+ { !eq{$h_list-id:$h_list-post:$h_list-subscribe:}{} }\
+ { match{$h_precedence:}{(?i)bulk|list|junk} }\
+ { match{$h_auto-submitted:}{(?i)auto-generated|auto-replied} }\
+ } {no}{yes}}
+</literallayout>
+<para>
+This suppresses the sending of warnings for messages that contain <emphasis>List-ID:</emphasis>,
+<emphasis>List-Post:</emphasis>, or <emphasis>List-Subscribe:</emphasis> headers, or have <quote>bulk</quote>, <quote>list</quote> or
+<quote>junk</quote> in a <emphasis>Precedence:</emphasis> header, or have <quote>auto-generated</quote> or
+<quote>auto-replied</quote> in an <emphasis>Auto-Submitted:</emphasis> header.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>deliver_drop_privilege</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>deliver_drop_privilege</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>unprivileged delivery</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>unprivileged</secondary>
+</indexterm>
+If this option is set true, Exim drops its root privilege at the start of a
+delivery process, and runs as the Exim user throughout. This severely restricts
+the kinds of local delivery that are possible, but is viable in certain types
+of configuration. There is a discussion about the use of root privilege in
+chapter <xref linkend="CHAPsecurity"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>deliver_queue_load_max</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>deliver_queue_load_max</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>fixed-point</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>load average</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue runner</primary>
+<secondary>abandoning</secondary>
+</indexterm>
+When this option is set, a queue run is abandoned if the system load average
+becomes greater than the value of the option. The option has no effect on
+ancient operating systems on which Exim cannot determine the load average.
+See also <option>queue_only_load</option> and <option>smtp_load_reserve</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>delivery_date_remove</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>delivery_date_remove</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Delivery-date:</emphasis> header line</primary>
+</indexterm>
+Exim’s transports have an option for adding a <emphasis>Delivery-date:</emphasis> header to a
+message when it is delivered, in exactly the same way as <emphasis>Return-path:</emphasis> is
+handled. <emphasis>Delivery-date:</emphasis> records the actual time of delivery. Such headers
+should not be present in incoming messages, and this option causes them to be
+removed at the time the message is received, to avoid any problems that might
+occur when a delivered message is subsequently sent on to some other recipient.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>disable_fsync</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>disable_fsync</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><function>fsync()</function>, disabling</primary>
+</indexterm>
+This option is available only if Exim was built with the compile-time option
+ENABLE_DISABLE_FSYNC. When this is not set, a reference to <option>disable_fsync</option> in
+a runtime configuration generates an <quote>unknown option</quote> error. You should not
+build Exim with ENABLE_DISABLE_FSYNC or set <option>disable_fsync</option> unless you
+really, really, really understand what you are doing. <emphasis>No pre-compiled
+distributions of Exim should ever make this option available.</emphasis>
+</para>
+<para>
+When <option>disable_fsync</option> is set true, Exim no longer calls <function>fsync()</function> to force
+updated files’ data to be written to disc before continuing. Unexpected events
+such as crashes and power outages may cause data to be lost or scrambled.
+Here be Dragons. <emphasis role="bold">Beware.</emphasis>
+</para>
+<para>
+<indexterm role="option">
+<primary><option>disable_ipv6</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>disable_ipv6</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>IPv6</primary>
+<secondary>disabling</secondary>
+</indexterm>
+If this option is set true, even if the Exim binary has IPv6 support, no IPv6
+activities take place. AAAA records are never looked up, and any IPv6 addresses
+that are listed in <option>local_interfaces</option>, data for the <option>manualroute</option> router,
+etc. are ignored. If IP literals are enabled, the <command>ipliteral</command> router declines
+to handle IPv6 literal addresses.
+</para>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>dkim_verify_hashes</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all" revisionflag="changed">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_verify_hashes</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>sha256 : sha512</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>DKIM</primary>
+<secondary>selecting signature algorithms</secondary>
+</indexterm>
+This option gives a list of hash types which are acceptable in signatures,
+</para>
+<para>
+and an order of processing.
+Signatures with algorithms not in the list will be ignored.
+</para>
+<para>
+Acceptable values include:
+</para>
+<literallayout class="monospaced">
+sha1
+sha256
+sha512
+</literallayout>
+<para>
+Note that the acceptance of sha1 violates RFC 8301.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dkim_verify_keytypes</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_verify_keytypes</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>ed25519 : rsa</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option gives a list of key types which are acceptable in signatures,
+and an order of processing.
+Signatures with algorithms not in the list will be ignored.
+</para>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>dkim_verify_min_keysizes</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all" revisionflag="changed">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_verify_min_keysizes</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>rsa=1024 ed25519=250</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para revisionflag="changed">
+This option gives a list of key sizes which are acceptable in signatures.
+The list is keyed by the algorithm type for the key; the values are in bits.
+Signatures with keys smaller than given by this option will fail verification.
+</para>
+<para revisionflag="changed">
+The default enforces the RFC 8301 minimum key size for RSA signatures.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dkim_verify_minimal</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_verify_minimal</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If set to true, verification of signatures will terminate after the
+first success.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dkim_verify_signers</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_verify_signers</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>$dkim_signers</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DKIM</primary>
+<secondary>controlling calls to the ACL</secondary>
+</indexterm>
+This option gives a list of DKIM domains for which the DKIM ACL is run.
+It is expanded after the message is received; by default it runs
+the ACL once for each signature in the message.
+See section <xref linkend="SECDKIMVFY"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dmarc_forensic_sender</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dmarc_forensic_sender</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="option">
+<primary><option>dmarc_history_file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dmarc_history_file</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="option">
+<primary><option>dmarc_tld_file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dmarc_tld_file</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DMARC</primary>
+<secondary>main section options</secondary>
+</indexterm>
+These options control DMARC processing.
+See section <xref linkend="SECDMARC"/> for details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dns_again_means_nonexist</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dns_again_means_nonexist</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary><quote>try again</quote> response; overriding</secondary>
+</indexterm>
+DNS lookups give a <quote>try again</quote> response for the DNS errors
+<quote>non-authoritative host not found</quote> and <quote>SERVERFAIL</quote>. This can cause Exim to
+keep trying to deliver a message, or to give repeated temporary errors to
+incoming mail. Sometimes the effect is caused by a badly set up name server and
+may persist for a long time. If a domain which exhibits this problem matches
+anything in <option>dns_again_means_nonexist</option>, it is treated as if it did not exist.
+This option should be used with care. You can make it apply to reverse lookups
+by a setting such as this:
+</para>
+<literallayout class="monospaced">
+dns_again_means_nonexist = *.in-addr.arpa
+</literallayout>
+<para>
+This option applies to all DNS lookups that Exim does. It also applies when the
+<function>gethostbyname()</function> or <function>getipnodebyname()</function> functions give temporary errors,
+since these are most likely to be caused by DNS lookup problems. The
+<command>dnslookup</command> router has some options of its own for controlling what happens
+when lookups for MX or SRV records give temporary errors. These more specific
+options are applied after this global option.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dns_check_names_pattern</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dns_check_names_pattern</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>pre-check of name syntax</secondary>
+</indexterm>
+When this option is set to a non-empty string, it causes Exim to check domain
+names for characters that are not allowed in host names before handing them to
+the DNS resolver, because some resolvers give temporary errors for names that
+contain unusual characters. If a domain name contains any unwanted characters,
+a <quote>not found</quote> result is forced, and the resolver is not called. The check is
+done by matching the domain name against a regular expression, which is the
+value of this option. The default pattern is
+</para>
+<literallayout class="monospaced">
+dns_check_names_pattern = \
+ (?i)^(?>(?(1)\.|())[^\W_](?>[a-z0-9/-]*[^\W_])?)+$
+</literallayout>
+<para>
+which permits only letters, digits, slashes, and hyphens in components, but
+they must start and end with a letter or digit. Slashes are not, in fact,
+permitted in host names, but they are found in certain NS records (which can be
+accessed in Exim by using a <option>dnsdb</option> lookup). If you set
+<option>allow_utf8_domains</option>, you must modify this pattern, or set the option to an
+empty string.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dns_csa_search_limit</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dns_csa_search_limit</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>5</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option controls the depth of parental searching for CSA SRV records in the
+DNS, as described in more detail in section <xref linkend="SECTverifyCSA"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dns_csa_use_reverse</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dns_csa_use_reverse</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option controls whether or not an IP address, given as a CSA domain, is
+reversed and looked up in the reverse DNS, as described in more detail in
+section <xref linkend="SECTverifyCSA"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dns_cname_loops</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dns_cname_loops</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>1</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>CNAME following</secondary>
+</indexterm>
+This option controls the following of CNAME chains, needed if the resolver does
+not do it internally.
+As of 2018 most should, and the default can be left.
+If you have an ancient one, a value of 10 is likely needed.
+</para>
+<para>
+The default value of one CNAME-follow is needed
+thanks to the observed return for an MX request,
+given no MX presence but a CNAME to an A, of the CNAME.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dns_dnssec_ok</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dns_dnssec_ok</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>-1</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>resolver options</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>DNSSEC</secondary>
+</indexterm>
+If this option is set to a non-negative number then Exim will initialise the
+DNS resolver library to either use or not use DNSSEC, overriding the system
+default. A value of 0 coerces DNSSEC off, a value of 1 coerces DNSSEC on.
+</para>
+<para>
+If the resolver library does not support DNSSEC then this option has no effect.
+</para>
+<para revisionflag="changed">
+On Linux with glibc 2.31 or newer this is insufficient, the resolver library
+will default to stripping out a successful validation status.
+This will break a previously working Exim installation.
+Provided that you do trust the resolver (ie, is on localhost) you can tell
+glibc to pass through any successful validation with a new option in
+<filename>/etc/resolv.conf</filename>:
+</para>
+<literallayout class="monospaced" revisionflag="changed">
+options trust-ad
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>dns_ipv4_lookup</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dns_ipv4_lookup</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>IPv6</primary>
+<secondary>DNS lookup for AAAA records</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>IPv6 lookup for AAAA records</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>IPv6 disabling</secondary>
+</indexterm>
+When Exim is compiled with IPv6 support and <option>disable_ipv6</option> is not set, it
+looks for IPv6 address records (AAAA records) as well as IPv4 address records
+(A records) when trying to find IP addresses for hosts, unless the host’s
+domain matches this list.
+</para>
+<para>
+This is a fudge to help with name servers that give big delays or otherwise do
+not work for the AAAA record type. In due course, when the world’s name
+servers have all been upgraded, there should be no need for this option.
+Note that all lookups, including those done for verification, are affected;
+this will result in verify failure for IPv6 connections or ones using names
+only valid for IPv6 addresses.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dns_retrans</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dns_retrans</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>0s</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>resolver options</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>dns lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>timeout</secondary>
+</indexterm>
+The options <option>dns_retrans</option> and <option>dns_retry</option> can be used to set the
+retransmission and retry parameters for DNS lookups. Values of zero (the
+defaults) leave the system default settings unchanged. The first value is the
+time between retries, and the second is the number of retries. It isn’t
+totally clear exactly how these settings affect the total time a DNS lookup may
+take. I haven’t found any documentation about timeouts on DNS lookups; these
+parameter values are available in the external resolver interface structure,
+but nowhere does it seem to describe how they are used or what you might want
+to set in them.
+See also the <option>slow_lookup_log</option> option.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dns_retry</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dns_retry</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>0</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>dns_retrans</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dns_trust_aa</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dns_trust_aa</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>resolver options</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>DNSSEC</secondary>
+</indexterm>
+If this option is set then lookup results marked with the AA bit
+(Authoritative Answer) are trusted the same way as if they were
+DNSSEC-verified. The authority section’s name of the answer must
+match with this expanded domain list.
+</para>
+<para>
+Use this option only if you talk directly to a resolver that is
+authoritative for some zones and does not set the AD (Authentic Data)
+bit in the answer. Some DNS servers may have an configuration option to
+mark the answers from their own zones as verified (they set the AD bit).
+Others do not have this option. It is considered as poor practice using
+a resolver that is an authoritative server for some zones.
+</para>
+<para>
+Use this option only if you really have to (e.g. if you want
+to use DANE for remote delivery to a server that is listed in the DNS
+zones that your resolver is authoritative for).
+</para>
+<para>
+If the DNS answer packet has the AA bit set and contains resource record
+in the answer section, the name of the first NS record appearing in the
+authority section is compared against the list. If the answer packet is
+authoritative but the answer section is empty, the name of the first SOA
+record in the authoritative section is used instead.
+</para>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>resolver options</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>dns_use_edns0</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dns_use_edns0</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>-1</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>resolver options</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>EDNS0</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>OpenBSD</secondary>
+</indexterm>
+If this option is set to a non-negative number then Exim will initialise the
+DNS resolver library to either use or not use EDNS0 extensions, overriding
+the system default. A value of 0 coerces EDNS0 off, a value of 1 coerces EDNS0
+on.
+</para>
+<para>
+If the resolver library does not support EDNS0 then this option has no effect.
+</para>
+<para>
+OpenBSD’s asr resolver routines are known to ignore the EDNS0 option; this
+means that DNSSEC will not work with Exim on that platform either, unless Exim
+is linked against an alternative DNS client library.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>drop_cr</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>drop_cr</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This is an obsolete option that is now a no-op. It used to affect the way Exim
+handled CR and LF characters in incoming messages. What happens now is
+described in section <xref linkend="SECTlineendings"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dsn_advertise_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dsn_advertise_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>bounce messages</primary>
+<secondary>success</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DSN</primary>
+<secondary>success</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Delivery Status Notification</primary>
+<secondary>success</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>DSN</secondary>
+</indexterm>
+DSN extensions (RFC3461) will be advertised in the EHLO message to,
+and accepted from, these hosts.
+Hosts may use the NOTIFY and ENVID options on RCPT TO commands,
+and RET and ORCPT options on MAIL FROM commands.
+A NOTIFY=SUCCESS option requests success-DSN messages.
+A NOTIFY= option with no argument requests that no delay or failure DSNs
+are sent.
+</para>
+<para revisionflag="changed">
+<emphasis role="bold">Note</emphasis>: Supplying success-DSN messages has been criticised
+on privacy grounds; it can leak details of internal forwarding.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dsn_from</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dsn_from</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><emphasis>From:</emphasis> header line</primary>
+<secondary>in bounces</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>bounce messages</primary>
+<secondary><emphasis>From:</emphasis> line, specifying</secondary>
+</indexterm>
+This option can be used to vary the contents of <emphasis>From:</emphasis> header lines in
+bounces and other automatically generated messages (<quote>Delivery Status
+Notifications</quote> – hence the name of the option). The default setting is:
+</para>
+<literallayout class="monospaced">
+dsn_from = Mail Delivery System <Mailer-Daemon@$qualify_domain>
+</literallayout>
+<para>
+The value is expanded every time it is needed. If the expansion fails, a
+panic is logged, and the default value is used.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>envelope_to_remove</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>envelope_to_remove</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Envelope-to:</emphasis> header line</primary>
+</indexterm>
+Exim’s transports have an option for adding an <emphasis>Envelope-to:</emphasis> header to a
+message when it is delivered, in exactly the same way as <emphasis>Return-path:</emphasis> is
+handled. <emphasis>Envelope-to:</emphasis> records the original recipient address from the
+message’s envelope that caused the delivery to happen. Such headers should not
+be present in incoming messages, and this option causes them to be removed at
+the time the message is received, to avoid any problems that might occur when a
+delivered message is subsequently sent on to some other recipient.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>errors_copy</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>errors_copy</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>copy to other address</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>copy of bounce message</primary>
+</indexterm>
+Setting this option causes Exim to send bcc copies of bounce messages that it
+generates to other addresses. <emphasis role="bold">Note</emphasis>: This does not apply to bounce messages
+coming from elsewhere. The value of the option is a colon-separated list of
+items. Each item consists of a pattern, terminated by white space, followed by
+a comma-separated list of email addresses. If a pattern contains spaces, it
+must be enclosed in double quotes.
+</para>
+<para>
+Each pattern is processed in the same way as a single item in an address list
+(see section <xref linkend="SECTaddresslist"/>). When a pattern matches the recipient of
+the bounce message, the message is copied to the addresses on the list. The
+items are scanned in order, and once a matching one is found, no further items
+are examined. For example:
+</para>
+<literallayout class="monospaced">
+errors_copy = spqr@mydomain postmaster@mydomain.example :\
+ rqps@mydomain hostmaster@mydomain.example,\
+ postmaster@mydomain.example
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+The address list is expanded before use. The expansion variables <varname>$local_part</varname>
+and <varname>$domain</varname> are set from the original recipient of the error message, and if
+there was any wildcard matching in the pattern, the expansion
+<indexterm role="concept">
+<primary>numerical variables (<varname>$1</varname> <varname>$2</varname> etc)</primary>
+<secondary>in <option>errors_copy</option></secondary>
+</indexterm>
+variables <varname>$0</varname>, <varname>$1</varname>, etc. are set in the normal way.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>errors_reply_to</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>errors_reply_to</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary><emphasis>Reply-to:</emphasis> in</secondary>
+</indexterm>
+By default, Exim’s bounce and delivery warning messages contain the header line
+</para>
+<literallayout>
+<literal>From: Mail Delivery System <Mailer-Daemon@</literal><emphasis>qualify-domain</emphasis><literal>></literal>
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>quota_warn_message</option></primary>
+</indexterm>
+where <emphasis>qualify-domain</emphasis> is the value of the <option>qualify_domain</option> option.
+A warning message that is generated by the <option>quota_warn_message</option> option in an
+<command>appendfile</command> transport may contain its own <emphasis>From:</emphasis> header line that
+overrides the default.
+</para>
+<para>
+Experience shows that people reply to bounce messages. If the
+<option>errors_reply_to</option> option is set, a <emphasis>Reply-To:</emphasis> header is added to bounce
+and warning messages. For example:
+</para>
+<literallayout class="monospaced">
+errors_reply_to = postmaster@my.domain.example
+</literallayout>
+<para>
+The value of the option is not expanded. It must specify a valid RFC 2822
+address. However, if a warning message that is generated by the
+<option>quota_warn_message</option> option in an <command>appendfile</command> transport contain its
+own <emphasis>Reply-To:</emphasis> header line, the value of the <option>errors_reply_to</option> option is
+not used.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>event_action</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>event_action</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>events</primary>
+</indexterm>
+This option declares a string to be expanded for Exim’s events mechanism.
+For details see chapter <xref linkend="CHAPevents"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>exim_group</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>exim_group</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>compile-time configured</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>gid (group id)</primary>
+<secondary>Exim’s own</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Exim group</primary>
+</indexterm>
+This option changes the gid under which Exim runs when it gives up root
+privilege. The default value is compiled into the binary. The value of this
+option is used only when <option>exim_user</option> is also set. Unless it consists entirely
+of digits, the string is looked up using <function>getgrnam()</function>, and failure causes a
+configuration error. See chapter <xref linkend="CHAPsecurity"/> for a discussion of
+security issues.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>exim_path</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>exim_path</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>Exim binary, path name</primary>
+</indexterm>
+This option specifies the path name of the Exim binary, which is used when Exim
+needs to re-exec itself. The default is set up to point to the file <emphasis>exim</emphasis> in
+the directory configured at compile time by the BIN_DIRECTORY setting. It
+is necessary to change <option>exim_path</option> if, exceptionally, Exim is run from some
+other place.
+<emphasis role="bold">Warning</emphasis>: Do not use a macro to define the value of this option, because
+you will break those Exim utilities that scan the configuration file to find
+where the binary is. (They then use the <option>-bP</option> option to extract option
+settings such as the value of <option>spool_directory</option>.)
+</para>
+<para>
+<indexterm role="option">
+<primary><option>exim_user</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>exim_user</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>compile-time configured</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>uid (user id)</primary>
+<secondary>Exim’s own</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Exim user</primary>
+</indexterm>
+This option changes the uid under which Exim runs when it gives up root
+privilege. The default value is compiled into the binary. Ownership of the run
+time configuration file and the use of the <option>-C</option> and <option>-D</option> command line
+options is checked against the values in the binary, not what is set here.
+</para>
+<para>
+Unless it consists entirely of digits, the string is looked up using
+<function>getpwnam()</function>, and failure causes a configuration error. If <option>exim_group</option> is
+not also supplied, the gid is taken from the result of <function>getpwnam()</function> if it is
+used. See chapter <xref linkend="CHAPsecurity"/> for a discussion of security issues.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>exim_version</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>exim_version</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>current version</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>Exim version</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>customizing</primary>
+<secondary>version number</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>version number of Exim</primary>
+<secondary>override</secondary>
+</indexterm>
+This option overrides the <varname>$version_number</varname>/<varname>$exim_version</varname> that Exim reports in
+various places. Use with care; this may fool stupid security scanners.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>extra_local_interfaces</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>extra_local_interfaces</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option defines network interfaces that are to be considered local when
+routing, but which are not used for listening by the daemon. See section
+<xref linkend="SECTreclocipadd"/> for details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>extract_addresses_remove_arguments</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>extract_addresses_remove_arguments</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="option">
+<primary><option>-t</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>command line</primary>
+<secondary>addresses with <option>-t</option></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary><option>-t</option> option</secondary>
+</indexterm>
+According to some Sendmail documentation (Sun, IRIX, HP-UX), if any addresses
+are present on the command line when the <option>-t</option> option is used to build an
+envelope from a message’s <emphasis>To:</emphasis>, <emphasis>Cc:</emphasis> and <emphasis>Bcc:</emphasis> headers, the command
+line addresses are removed from the recipients list. This is also how Smail
+behaves. However, other Sendmail documentation (the O’Reilly book) states that
+command line addresses are added to those obtained from the header lines. When
+<option>extract_addresses_remove_arguments</option> is true (the default), Exim subtracts
+argument headers. If it is set false, Exim adds rather than removes argument
+addresses.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>finduser_retries</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>finduser_retries</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>0</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>NIS, retrying user lookups</primary>
+</indexterm>
+On systems running NIS or other schemes in which user and group information is
+distributed from a remote system, there can be times when <function>getpwnam()</function> and
+related functions fail, even when given valid data, because things time out.
+Unfortunately these failures cannot be distinguished from genuine <quote>not found</quote>
+errors. If <option>finduser_retries</option> is set greater than zero, Exim will try that
+many extra times to find a user or a group, waiting for one second between
+retries.
+</para>
+<para>
+<indexterm role="concept">
+<primary><filename>/etc/passwd</filename></primary>
+<secondary>multiple reading of</secondary>
+</indexterm>
+You should not set this option greater than zero if your user information is in
+a traditional <filename>/etc/passwd</filename> file, because it will cause Exim needlessly to
+search the file multiple times for non-existent users, and also cause delay.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>freeze_tell</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>freeze_tell</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list, comma separated</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>freezing messages</primary>
+<secondary>sending a message when freezing</secondary>
+</indexterm>
+On encountering certain errors, or when configured to do so in a system filter,
+ACL, or special router, Exim freezes a message. This means that no further
+delivery attempts take place until an administrator thaws the message, or the
+<option>auto_thaw</option>, <option>ignore_bounce_errors_after</option>, or <option>timeout_frozen_after</option>
+feature cause it to be processed. If <option>freeze_tell</option> is set, Exim generates a
+warning message whenever it freezes something, unless the message it is
+freezing is a locally-generated bounce message. (Without this exception there
+is the possibility of looping.) The warning message is sent to the addresses
+supplied as the comma-separated value of this option. If several of the
+message’s addresses cause freezing, only a single message is sent. If the
+freezing was automatic, the reason(s) for freezing can be found in the message
+log. If you configure freezing in a filter or ACL, you must arrange for any
+logging that you require.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>gecos_name</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>gecos_name</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>HP-UX</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><quote>gecos</quote> field, parsing</primary>
+</indexterm>
+Some operating systems, notably HP-UX, use the <quote>gecos</quote> field in the system
+password file to hold other information in addition to users’ real names. Exim
+looks up this field for use when it is creating <emphasis>Sender:</emphasis> or <emphasis>From:</emphasis>
+headers. If either <option>gecos_pattern</option> or <option>gecos_name</option> are unset, the contents
+of the field are used unchanged, except that, if an ampersand is encountered,
+it is replaced by the user’s login name with the first character forced to
+upper case, since this is a convention that is observed on many systems.
+</para>
+<para>
+When these options are set, <option>gecos_pattern</option> is treated as a regular
+expression that is to be applied to the field (again with & replaced by the
+login name), and if it matches, <option>gecos_name</option> is expanded and used as the
+user’s name.
+</para>
+<para>
+<indexterm role="concept">
+<primary>numerical variables (<varname>$1</varname> <varname>$2</varname> etc)</primary>
+<secondary>in <option>gecos_name</option></secondary>
+</indexterm>
+Numeric variables such as <varname>$1</varname>, <varname>$2</varname>, etc. can be used in the expansion to
+pick up sub-fields that were matched by the pattern. In HP-UX, where the user’s
+name terminates at the first comma, the following can be used:
+</para>
+<literallayout class="monospaced">
+gecos_pattern = ([^,]*)
+gecos_name = $1
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>gecos_pattern</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>gecos_pattern</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>gecos_name</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>gnutls_compat_mode</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>gnutls_compat_mode</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option controls whether GnuTLS is used in compatibility mode in an Exim
+server. This reduces security slightly, but improves interworking with older
+implementations of TLS.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>gnutls_allow_auto_pkcs11</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>gnutls_allow_auto_pkcs11</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option will let GnuTLS (2.12.0 or later) autoload PKCS11 modules with
+the p11-kit configuration files in <filename>/etc/pkcs11/modules/</filename>.
+</para>
+<para>
+See
+<emphasis role="bold"><ulink url="https://www.gnutls.org/manual/gnutls.html#Smart-cards-and-HSMs">https://www.gnutls.org/manual/gnutls.html#Smart-cards-and-HSMs</ulink></emphasis>
+for documentation.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>headers_charset</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>headers_charset</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option sets a default character set for translating from encoded MIME
+<quote>words</quote> in header lines, when referenced by an <varname>$h_xxx</varname> expansion item. The
+default is the value of HEADERS_CHARSET in <filename>Local/Makefile</filename>. The
+ultimate default is ISO-8859-1. For more details see the description of header
+insertions in section <xref linkend="SECTexpansionitems"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>header_maxsize</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>header_maxsize</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>header section</primary>
+<secondary>maximum size of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>size of message header section</secondary>
+</indexterm>
+This option controls the overall maximum size of a message’s header
+section. The default is the value of HEADER_MAXSIZE in
+<filename>Local/Makefile</filename>; the default for that is 1M. Messages with larger header
+sections are rejected.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>header_line_maxsize</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>header_line_maxsize</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>0</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>maximum size of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>size of one header line</secondary>
+</indexterm>
+This option limits the length of any individual header line in a message, after
+all the continuations have been joined together. Messages with individual
+header lines that are longer than the limit are rejected. The default value of
+zero means <quote>no limit</quote>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>helo_accept_junk_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>helo_accept_junk_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>HELO</primary>
+<secondary>accepting junk data</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>EHLO</primary>
+<secondary>accepting junk data</secondary>
+</indexterm>
+Exim checks the syntax of HELO and EHLO commands for incoming SMTP
+mail, and gives an error response for invalid data. Unfortunately, there are
+some SMTP clients that send syntactic junk. They can be accommodated by setting
+this option. Note that this is a syntax check only. See <option>helo_verify_hosts</option>
+if you want to do semantic checking.
+See also <option>helo_allow_chars</option> for a way of extending the permitted character
+set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>helo_allow_chars</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>helo_allow_chars</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>HELO</primary>
+<secondary>underscores in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>EHLO</primary>
+<secondary>underscores in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>underscore in EHLO/HELO</primary>
+</indexterm>
+This option can be set to a string of rogue characters that are permitted in
+all EHLO and HELO names in addition to the standard letters, digits,
+hyphens, and dots. If you really must allow underscores, you can set
+</para>
+<literallayout class="monospaced">
+helo_allow_chars = _
+</literallayout>
+<para>
+Note that the value is one string, not a list.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>helo_lookup_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>helo_lookup_domains</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis><literal>@:@[]</literal></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>HELO</primary>
+<secondary>forcing reverse lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>EHLO</primary>
+<secondary>forcing reverse lookup</secondary>
+</indexterm>
+If the domain given by a client in a HELO or EHLO command matches this
+list, a reverse lookup is done in order to establish the host’s true name. The
+default forces a lookup if the client host gives the server’s name or any of
+its IP addresses (in brackets), something that broken clients have been seen to
+do.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>helo_try_verify_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>helo_try_verify_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>HELO verifying</primary>
+<secondary>optional</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>EHLO</primary>
+<secondary>verifying, optional</secondary>
+</indexterm>
+By default, Exim just checks the syntax of HELO and EHLO commands (see
+<option>helo_accept_junk_hosts</option> and <option>helo_allow_chars</option>). However, some sites like
+to do more extensive checking of the data supplied by these commands. The ACL
+condition <literal>verify = helo</literal> is provided to make this possible.
+Formerly, it was necessary also to set this option (<option>helo_try_verify_hosts</option>)
+to force the check to occur. From release 4.53 onwards, this is no longer
+necessary. If the check has not been done before <literal>verify = helo</literal> is
+encountered, it is done at that time. Consequently, this option is obsolete.
+Its specification is retained here for backwards compatibility.
+</para>
+<para>
+When an EHLO or HELO command is received, if the calling host matches
+<option>helo_try_verify_hosts</option>, Exim checks that the host name given in the HELO or
+EHLO command either:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+is an IP literal matching the calling address of the host, or
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>reverse lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>reverse DNS lookup</primary>
+</indexterm>
+matches the host name that Exim obtains by doing a reverse lookup of the
+calling host address, or
+</para>
+</listitem>
+<listitem>
+<para>
+when looked up in DNS yields the calling host address.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+However, the EHLO or HELO command is not rejected if any of the checks
+fail. Processing continues, but the result of the check is remembered, and can
+be detected later in an ACL by the <literal>verify = helo</literal> condition.
+</para>
+<para>
+If DNS was used for successful verification, the variable
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>DNSSEC</secondary>
+</indexterm>
+<varname>$helo_verify_dnssec</varname> records the DNSSEC status of the lookups.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>helo_verify_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>helo_verify_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>HELO verifying</primary>
+<secondary>mandatory</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>EHLO</primary>
+<secondary>verifying, mandatory</secondary>
+</indexterm>
+Like <option>helo_try_verify_hosts</option>, this option is obsolete, and retained only for
+backwards compatibility. For hosts that match this option, Exim checks the host
+name given in the HELO or EHLO in the same way as for
+<option>helo_try_verify_hosts</option>. If the check fails, the HELO or EHLO command is
+rejected with a 550 error, and entries are written to the main and reject logs.
+If a MAIL command is received before EHLO or HELO, it is rejected with a 503
+error.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hold_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hold_domains</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>domain</primary>
+<secondary>delaying delivery</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>delaying certain domains</secondary>
+</indexterm>
+This option allows mail for particular domains to be held in the queue
+manually. The option is overridden if a message delivery is forced with the
+<option>-M</option>, <option>-qf</option>, <option>-Rf</option> or <option>-Sf</option> options, and also while testing or
+verifying addresses using <option>-bt</option> or <option>-bv</option>. Otherwise, if a domain matches an
+item in <option>hold_domains</option>, no routing or delivery for that address is done, and
+it is deferred every time the message is looked at.
+</para>
+<para>
+This option is intended as a temporary operational measure for delaying the
+delivery of mail while some problem is being sorted out, or some new
+configuration tested. If you just want to delay the processing of some
+domains until a queue run occurs, you should use <option>queue_domains</option> or
+<option>queue_smtp_domains</option>, not <option>hold_domains</option>.
+</para>
+<para>
+A setting of <option>hold_domains</option> does not override Exim’s code for removing
+messages from the queue if they have been there longer than the longest retry
+time in any retry rule. If you want to hold messages for longer than the normal
+retry times, insert a dummy retry rule with a long retry time.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>host_lookup</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>host_lookup</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>host name</primary>
+<secondary>lookup, forcing</secondary>
+</indexterm>
+Exim does not look up the name of a calling host from its IP address unless it
+is required to compare against some host list, or the host matches
+<option>helo_try_verify_hosts</option> or <option>helo_verify_hosts</option>, or the host matches this
+option (which normally contains IP addresses rather than host names). The
+default configuration file contains
+</para>
+<literallayout class="monospaced">
+host_lookup = *
+</literallayout>
+<para>
+which causes a lookup to happen for all hosts. If the expense of these lookups
+is felt to be too great, the setting can be changed or removed.
+</para>
+<para>
+After a successful reverse lookup, Exim does a forward lookup on the name it
+has obtained, to verify that it yields the IP address that it started with. If
+this check fails, Exim behaves as if the name lookup failed.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$host_lookup_failed</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$sender_host_name</varname></primary>
+</indexterm>
+After any kind of failure, the host name (in <varname>$sender_host_name</varname>) remains
+unset, and <varname>$host_lookup_failed</varname> is set to the string <quote>1</quote>. See also
+<option>dns_again_means_nonexist</option>, <option>helo_lookup_domains</option>, and
+<literal>verify = reverse_host_lookup</literal> in ACLs.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>host_lookup_order</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>host_lookup_order</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis><literal>bydns:byaddr</literal></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies the order of different lookup methods when Exim is trying
+to find a host name from an IP address. The default is to do a DNS lookup
+first, and then to try a local lookup (using <function>gethostbyaddr()</function> or equivalent)
+if that fails. You can change the order of these lookups, or omit one entirely,
+if you want.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: The <quote>byaddr</quote> method does not always yield aliases when there are
+multiple PTR records in the DNS and the IP address is not listed in
+<filename>/etc/hosts</filename>. Different operating systems give different results in this
+case. That is why the default tries a DNS lookup first.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>host_reject_connection</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>host_reject_connection</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>rejecting connections from</secondary>
+</indexterm>
+If this option is set, incoming SMTP calls from the hosts listed are rejected
+as soon as the connection is made.
+This option is obsolete, and retained only for backward compatibility, because
+nowadays the ACL specified by <option>acl_smtp_connect</option> can also reject incoming
+connections immediately.
+</para>
+<para>
+The ability to give an immediate rejection (either by this option or using an
+ACL) is provided for use in unusual cases. Many hosts will just try again,
+sometimes without much delay. Normally, it is better to use an ACL to reject
+incoming messages at a later stage, such as after RCPT commands. See
+chapter <xref linkend="CHAPACL"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_connection_nolog</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_connection_nolog</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>not logging connections from</secondary>
+</indexterm>
+This option defines a list of hosts for which connection logging does not
+happen, even though the <option>smtp_connection</option> log selector is set. For example,
+you might want not to log SMTP connections from local processes, or from
+127.0.0.1, or from your local LAN. This option is consulted in the main loop of
+the daemon; you should therefore strive to restrict its value to a short inline
+list of IP addresses and networks. To disable logging SMTP connections from
+local processes, you must create a host list with an empty item. For example:
+</para>
+<literallayout class="monospaced">
+hosts_connection_nolog = :
+</literallayout>
+<para>
+If the <option>smtp_connection</option> log selector is not set, this option has no effect.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_proxy</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_proxy</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>proxy</primary>
+<secondary>proxy protocol</secondary>
+</indexterm>
+This option enables use of Proxy Protocol proxies for incoming
+connections. For details see section <xref linkend="SECTproxyInbound"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_treat_as_local</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_treat_as_local</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>local host</primary>
+<secondary>domains treated as</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>treated as local</secondary>
+</indexterm>
+If this option is set, any host names that match the domain list are treated as
+if they were the local host when Exim is scanning host lists obtained from MX
+records
+or other sources. Note that the value of this option is a domain list, not a
+host list, because it is always used to check host names, not IP addresses.
+</para>
+<para>
+This option also applies when Exim is matching the special items
+<literal>@mx_any</literal>, <literal>@mx_primary</literal>, and <literal>@mx_secondary</literal> in a domain list (see
+section <xref linkend="SECTdomainlist"/>), and when checking the <option>hosts</option> option in the
+<command>smtp</command> transport for the local host (see the <option>allow_localhost</option> option in
+that transport). See also <option>local_interfaces</option>, <option>extra_local_interfaces</option>, and
+chapter <xref linkend="CHAPinterfaces"/>, which contains a discussion about local network
+interfaces and recognizing the local host.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ibase_servers</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ibase_servers</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>InterBase</primary>
+<secondary>server list</secondary>
+</indexterm>
+This option provides a list of InterBase servers and associated connection data,
+to be used in conjunction with <command>ibase</command> lookups (see section <xref linkend="SECID72"/>).
+The option is available only if Exim has been built with InterBase support.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ignore_bounce_errors_after</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ignore_bounce_errors_after</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>10w</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>discarding</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>discarding bounce message</primary>
+</indexterm>
+This option affects the processing of bounce messages that cannot be delivered,
+that is, those that suffer a permanent delivery failure. (Bounce messages that
+suffer temporary delivery failures are of course retried in the usual way.)
+</para>
+<para>
+After a permanent delivery failure, bounce messages are frozen,
+because there is no sender to whom they can be returned. When a frozen bounce
+message has been in the queue for more than the given time, it is unfrozen at
+the next queue run, and a further delivery is attempted. If delivery fails
+again, the bounce message is discarded. This makes it possible to keep failed
+bounce messages around for a shorter time than the normal maximum retry time
+for frozen messages. For example,
+</para>
+<literallayout class="monospaced">
+ignore_bounce_errors_after = 12h
+</literallayout>
+<para>
+retries failed bounce message deliveries after 12 hours, discarding any further
+failures. If the value of this option is set to a zero time period, bounce
+failures are discarded immediately. Setting a very long time (as in the default
+value) has the effect of disabling this option. For ways of automatically
+dealing with other kinds of frozen message, see <option>auto_thaw</option> and
+<option>timeout_frozen_after</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ignore_fromline_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ignore_fromline_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><quote>From</quote> line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>UUCP</primary>
+<secondary><quote>From</quote> line</secondary>
+</indexterm>
+Some broken SMTP clients insist on sending a UUCP-like <quote>From </quote> line before
+the headers of a message. By default this is treated as the start of the
+message’s body, which means that any following headers are not recognized as
+such. Exim can be made to ignore it by setting <option>ignore_fromline_hosts</option> to
+match those hosts that insist on sending it. If the sender is actually a local
+process rather than a remote host, and is using <option>-bs</option> to inject the messages,
+<option>ignore_fromline_local</option> must be set to achieve this effect.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ignore_fromline_local</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ignore_fromline_local</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>ignore_fromline_hosts</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>keep_environment</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>keep_environment</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>environment</primary>
+<secondary>values from</secondary>
+</indexterm>
+This option contains a string list of environment variables to keep.
+You have to trust these variables or you have to be sure that
+these variables do not impose any security risk. Keep in mind that
+during the startup phase Exim is running with an effective UID 0 in most
+installations. As the default value is an empty list, the default
+environment for using libraries, running embedded Perl code, or running
+external binaries is empty, and does not not even contain PATH or HOME.
+</para>
+<para>
+Actually the list is interpreted as a list of patterns
+(<xref linkend="SECTlistexpand"/>), except that it is not expanded first.
+</para>
+<para>
+WARNING: Macro substitution is still done first, so having a macro
+FOO and having FOO_HOME in your <option>keep_environment</option> option may have
+unexpected results. You may work around this using a regular expression
+that does not match the macro name: ^[F]OO_HOME$.
+</para>
+<para>
+Current versions of Exim issue a warning during startup if you do not mention
+<option>keep_environment</option> in your runtime configuration file and if your
+current environment is not empty. Future versions may not issue that warning
+anymore.
+</para>
+<para>
+See the <option>add_environment</option> main config option for a way to set
+environment variables to a fixed value. The environment for <command>pipe</command>
+transports is handled separately, see section <xref linkend="SECTpipeenv"/> for
+details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>keep_malformed</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>keep_malformed</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>4d</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies the length of time to keep messages whose spool files
+have been corrupted in some way. This should, of course, never happen. At the
+next attempt to deliver such a message, it gets removed. The incident is
+logged.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ldap_ca_cert_dir</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ldap_ca_cert_dir</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>,</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>directory for LDAP</secondary>
+</indexterm>
+This option indicates which directory contains CA certificates for verifying
+a TLS certificate presented by an LDAP server.
+While Exim does not provide a default value, your SSL library may.
+Analogous to <option>tls_verify_certificates</option> but as a client-side option for LDAP
+and constrained to be a directory.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ldap_ca_cert_file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ldap_ca_cert_file</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>,</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>file for LDAP</secondary>
+</indexterm>
+This option indicates which file contains CA certificates for verifying
+a TLS certificate presented by an LDAP server.
+While Exim does not provide a default value, your SSL library may.
+Analogous to <option>tls_verify_certificates</option> but as a client-side option for LDAP
+and constrained to be a file.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ldap_cert_file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ldap_cert_file</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>TLS client certificate file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>file for LDAP</secondary>
+</indexterm>
+This option indicates which file contains an TLS client certificate which
+Exim should present to the LDAP server during TLS negotiation.
+Should be used together with <option>ldap_cert_key</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ldap_cert_key</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ldap_cert_key</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>TLS client key file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>key for LDAP</secondary>
+</indexterm>
+This option indicates which file contains the secret/private key to use
+to prove identity to the LDAP server during TLS negotiation.
+Should be used together with <option>ldap_cert_file</option>, which contains the
+identity to be proven.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ldap_cipher_suite</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ldap_cipher_suite</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>TLS cipher suite</secondary>
+</indexterm>
+This controls the TLS cipher-suite negotiation during TLS negotiation with
+the LDAP server. See <xref linkend="SECTreqciphssl"/> for more details of the format of
+cipher-suite options with OpenSSL (as used by LDAP client libraries).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ldap_default_servers</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ldap_default_servers</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>default servers</secondary>
+</indexterm>
+This option provides a list of LDAP servers which are tried in turn when an
+LDAP query does not contain a server. See section <xref linkend="SECTforldaque"/> for
+details of LDAP queries. This option is available only when Exim has been built
+with LDAP support.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ldap_require_cert</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ldap_require_cert</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset.</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>policy for LDAP server TLS cert presentation</secondary>
+</indexterm>
+This should be one of the values "hard", "demand", "allow", "try" or "never".
+A value other than one of these is interpreted as "never".
+See the entry "TLS_REQCERT" in your system man page for ldap.conf(5).
+Although Exim does not set a default, the LDAP library probably defaults
+to hard/demand.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ldap_start_tls</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ldap_start_tls</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>whether or not to negotiate TLS</secondary>
+</indexterm>
+If set, Exim will attempt to negotiate TLS with the LDAP server when
+connecting on a regular LDAP port. This is the LDAP equivalent of SMTP’s
+"STARTTLS". This is distinct from using "ldaps", which is the LDAP form
+of SSL-on-connect.
+In the event of failure to negotiate TLS, the action taken is controlled
+by <option>ldap_require_cert</option>.
+This option is ignored for <literal>ldapi</literal> connections.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ldap_version</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ldap_version</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>LDAP</primary>
+<secondary>protocol version, forcing</secondary>
+</indexterm>
+This option can be used to force Exim to set a specific protocol version for
+LDAP. If it option is unset, it is shown by the <option>-bP</option> command line option as
+-1. When this is the case, the default is 3 if LDAP_VERSION3 is defined in
+the LDAP headers; otherwise it is 2. This option is available only when Exim
+has been built with LDAP support.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>local_from_check</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>local_from_check</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Sender:</emphasis> header line</primary>
+<secondary>disabling addition of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>From:</emphasis> header line</primary>
+<secondary>disabling checking of</secondary>
+</indexterm>
+When a message is submitted locally (that is, not over a TCP/IP connection) by
+an untrusted user, Exim removes any existing <emphasis>Sender:</emphasis> header line, and
+checks that the <emphasis>From:</emphasis> header line matches the login of the calling user and
+the domain specified by <option>qualify_domain</option>.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: An unqualified address (no domain) in the <emphasis>From:</emphasis> header in a
+locally submitted message is automatically qualified by Exim, unless the
+<option>-bnq</option> command line option is used.
+</para>
+<para>
+You can use <option>local_from_prefix</option> and <option>local_from_suffix</option> to permit affixes
+on the local part. If the <emphasis>From:</emphasis> header line does not match, Exim adds a
+<emphasis>Sender:</emphasis> header with an address constructed from the calling user’s login
+and the default qualify domain.
+</para>
+<para>
+If <option>local_from_check</option> is set false, the <emphasis>From:</emphasis> header check is disabled,
+and no <emphasis>Sender:</emphasis> header is ever added. If, in addition, you want to retain
+<emphasis>Sender:</emphasis> header lines supplied by untrusted users, you must also set
+<option>local_sender_retain</option> to be true.
+</para>
+<para>
+<indexterm role="concept">
+<primary>envelope from</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope sender</primary>
+</indexterm>
+These options affect only the header lines in the message. The envelope sender
+is still forced to be the login id at the qualify domain unless
+<option>untrusted_set_sender</option> permits the user to supply an envelope sender.
+</para>
+<para>
+For messages received over TCP/IP, an ACL can specify <quote>submission mode</quote> to
+request similar header line checking. See section <xref linkend="SECTthesenhea"/>, which
+has more details about <emphasis>Sender:</emphasis> processing.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>local_from_prefix</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>local_from_prefix</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+When Exim checks the <emphasis>From:</emphasis> header line of locally submitted messages for
+matching the login id (see <option>local_from_check</option> above), it can be configured to
+ignore certain prefixes and suffixes in the local part of the address. This is
+done by setting <option>local_from_prefix</option> and/or <option>local_from_suffix</option> to
+appropriate lists, in the same form as the <option>local_part_prefix</option> and
+<option>local_part_suffix</option> router options (see chapter <xref linkend="CHAProutergeneric"/>). For
+example, if
+</para>
+<literallayout class="monospaced">
+local_from_prefix = *-
+</literallayout>
+<para>
+is set, a <emphasis>From:</emphasis> line containing
+</para>
+<literallayout class="monospaced">
+From: anything-user@your.domain.example
+</literallayout>
+<para>
+will not cause a <emphasis>Sender:</emphasis> header to be added if <emphasis>user@your.domain.example</emphasis>
+matches the actual sender address that is constructed from the login name and
+qualify domain.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>local_from_suffix</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>local_from_suffix</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>local_from_prefix</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>local_interfaces</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>local_interfaces</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option controls which network interfaces are used by the daemon for
+listening; they are also used to identify the local host when routing. Chapter
+<xref linkend="CHAPinterfaces"/> contains a full description of this option and the related
+options <option>daemon_smtp_ports</option>, <option>extra_local_interfaces</option>,
+<option>hosts_treat_as_local</option>, and <option>tls_on_connect_ports</option>. The default value for
+<option>local_interfaces</option> is
+</para>
+<literallayout class="monospaced">
+local_interfaces = 0.0.0.0
+</literallayout>
+<para>
+when Exim is built without IPv6 support; otherwise it is
+</para>
+<literallayout class="monospaced">
+local_interfaces = <; ::0 ; 0.0.0.0
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>local_scan_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>local_scan_timeout</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>5m</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>for <function>local_scan()</function> function</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><function>local_scan()</function> function</primary>
+<secondary>timeout</secondary>
+</indexterm>
+This timeout applies to the <function>local_scan()</function> function (see chapter
+<xref linkend="CHAPlocalscan"/>). Zero means <quote>no timeout</quote>. If the timeout is exceeded,
+the incoming message is rejected with a temporary error if it is an SMTP
+message. For a non-SMTP message, the message is dropped and Exim ends with a
+non-zero code. The incident is logged on the main and reject logs.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>local_sender_retain</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>local_sender_retain</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Sender:</emphasis> header line</primary>
+<secondary>retaining from local submission</secondary>
+</indexterm>
+When a message is submitted locally (that is, not over a TCP/IP connection) by
+an untrusted user, Exim removes any existing <emphasis>Sender:</emphasis> header line. If you
+do not want this to happen, you must set <option>local_sender_retain</option>, and you must
+also set <option>local_from_check</option> to be false (Exim will complain if you do not).
+See also the ACL modifier <literal>control = suppress_local_fixups</literal>. Section
+<xref linkend="SECTthesenhea"/> has more details about <emphasis>Sender:</emphasis> processing.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>localhost_number</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>localhost_number</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>locally unique number for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message ids</primary>
+<secondary>with multiple hosts</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$localhost_number</varname></primary>
+</indexterm>
+Exim’s message ids are normally unique only within the local host. If
+uniqueness among a set of hosts is required, each host must set a different
+value for the <option>localhost_number</option> option. The string is expanded immediately
+after reading the configuration file (so that a number can be computed from the
+host name, for example) and the result of the expansion must be a number in the
+range 0–16 (or 0–10 on operating systems with case-insensitive file
+systems). This is available in subsequent string expansions via the variable
+<varname>$localhost_number</varname>. When <option>localhost_number is set</option>, the final two
+characters of the message id, instead of just being a fractional part of the
+time, are computed from the time and the local host number as described in
+section <xref linkend="SECTmessiden"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>log_file_path</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>log_file_path</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>set at compile time</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>file path for</secondary>
+</indexterm>
+This option sets the path which is used to determine the names of Exim’s log
+files, or indicates that logging is to be to syslog, or both. It is expanded
+when Exim is entered, so it can, for example, contain a reference to the host
+name. If no specific path is set for the log files at compile or runtime,
+or if the option is unset at runtime (i.e. <literal>log_file_path = </literal>)
+they are written in a sub-directory called <filename>log</filename> in Exim’s spool directory.
+A path must start with a slash.
+To send to syslog, use the word <quote>syslog</quote>.
+Chapter <xref linkend="CHAPlog"/> contains further details about Exim’s logging, and
+section <xref linkend="SECTwhelogwri"/> describes how the contents of <option>log_file_path</option> are
+used. If this string is fixed at your installation (contains no expansion
+variables) it is recommended that you do not set this option in the
+configuration file, but instead supply the path using LOG_FILE_PATH in
+<filename>Local/Makefile</filename> so that it is available to Exim for logging errors detected
+early on – in particular, failure to read the configuration file.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>log_selector</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>log_selector</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>selectors</secondary>
+</indexterm>
+This option can be used to reduce or increase the number of things that Exim
+writes to its log files. Its argument is made up of names preceded by plus or
+minus characters. For example:
+</para>
+<literallayout class="monospaced">
+log_selector = +arguments -retry_defer
+</literallayout>
+<para>
+A list of possible names and what they control is given in the chapter on
+logging, in section <xref linkend="SECTlogselector"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>log_timezone</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>log_timezone</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>timezone for entries</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tod_log</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tod_zone</varname></primary>
+</indexterm>
+By default, the timestamps on log lines are in local time without the
+timezone. This means that if your timezone changes twice a year, the timestamps
+in log lines are ambiguous for an hour when the clocks go back. One way of
+avoiding this problem is to set the timezone to UTC. An alternative is to set
+<option>log_timezone</option> true. This turns on the addition of the timezone offset to
+timestamps in log lines. Turning on this option can add quite a lot to the size
+of log files because each line is extended by 6 characters. Note that the
+<varname>$tod_log</varname> variable contains the log timestamp without the zone, but there is
+another variable called <varname>$tod_zone</varname> that contains just the timezone offset.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>lookup_open_max</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>lookup_open_max</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>25</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>too many open files</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>open files, too many</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>too many open</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>maximum open files</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>open files for lookups</secondary>
+</indexterm>
+This option limits the number of simultaneously open files for single-key
+lookups that use regular files (that is, <command>lsearch</command>, <command>dbm</command>, and <command>cdb</command>).
+Exim normally keeps these files open during routing, because often the same
+file is required several times. If the limit is reached, Exim closes the least
+recently used file. Note that if you are using the <emphasis>ndbm</emphasis> library, it
+actually opens two files for each logical DBM database, though it still counts
+as one for the purposes of <option>lookup_open_max</option>. If you are getting <quote>too many
+open files</quote> errors with NDBM, you need to reduce the value of
+<option>lookup_open_max</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>max_username_length</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>max_username_length</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>0</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>length of login name</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>user name</primary>
+<secondary>maximum length</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>user name length</secondary>
+</indexterm>
+Some operating systems are broken in that they truncate long arguments to
+<function>getpwnam()</function> to eight characters, instead of returning <quote>no such user</quote>. If
+this option is set greater than zero, any attempt to call <function>getpwnam()</function> with
+an argument that is longer behaves as if <function>getpwnam()</function> failed.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>message_body_newlines</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>message_body_newlines</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>bool</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>message body</primary>
+<secondary>newlines in variables</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>newline</primary>
+<secondary>in message body variables</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$message_body</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$message_body_end</varname></primary>
+</indexterm>
+By default, newlines in the message body are replaced by spaces when setting
+the <varname>$message_body</varname> and <varname>$message_body_end</varname> expansion variables. If this
+option is set true, this no longer happens.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>message_body_visible</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>message_body_visible</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>500</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>body of message</primary>
+<secondary>visible size</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message body</primary>
+<secondary>visible size</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$message_body</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$message_body_end</varname></primary>
+</indexterm>
+This option specifies how much of a message’s body is to be included in the
+<varname>$message_body</varname> and <varname>$message_body_end</varname> expansion variables.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>message_id_header_domain</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>message_id_header_domain</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Message-ID:</emphasis> header line</primary>
+</indexterm>
+If this option is set, the string is expanded and used as the right hand side
+(domain) of the <emphasis>Message-ID:</emphasis> header that Exim creates if a
+locally-originated incoming message does not have one. <quote>Locally-originated</quote>
+means <quote>not received over TCP/IP.</quote>
+Otherwise, the primary host name is used.
+Only letters, digits, dot and hyphen are accepted; any other characters are
+replaced by hyphens. If the expansion is forced to fail, or if the result is an
+empty string, the option is ignored.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>message_id_header_text</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>message_id_header_text</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this variable is set, the string is expanded and used to augment the text of
+the <emphasis>Message-id:</emphasis> header that Exim creates if a locally-originated incoming
+message does not have one. The text of this header is required by RFC 2822 to
+take the form of an address. By default, Exim uses its internal message id as
+the local part, and the primary host name as the domain. If this option is set,
+it is expanded, and provided the expansion is not forced to fail, and does not
+yield an empty string, the result is inserted into the header immediately
+before the @, separated from the internal message id by a dot. Any characters
+that are illegal in an address are automatically converted into hyphens. This
+means that variables such as <varname>$tod_log</varname> can be used, because the spaces and
+colons will become hyphens.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>message_logs</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>message_logs</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>message logs</primary>
+<secondary>disabling</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>message log; disabling</secondary>
+</indexterm>
+If this option is turned off, per-message log files are not created in the
+<filename>msglog</filename> spool sub-directory. This reduces the amount of disk I/O required by
+Exim, by reducing the number of files involved in handling a message from a
+minimum of four (header spool file, body spool file, delivery journal, and
+per-message log) to three. The other major I/O activity is Exim’s main log,
+which is not affected by this option.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>message_size_limit</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>message_size_limit</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>50M</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>size limit</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>message size</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>size</primary>
+<secondary>of message, limit</secondary>
+</indexterm>
+This option limits the maximum size of message that Exim will process. The
+value is expanded for each incoming connection so, for example, it can be made
+to depend on the IP address of the remote host for messages arriving via
+TCP/IP. After expansion, the value must be a sequence of decimal digits,
+optionally followed by K or M.
+</para>
+<para>
+<indexterm role="concept">
+<primary>SIZE</primary>
+<secondary>ESMTP extension, advertising</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>SIZE</secondary>
+</indexterm>
+If nonzero the value will be advertised as a parameter to the ESMTP SIZE
+service extension keyword.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: This limit cannot be made to depend on a message’s sender or any
+other properties of an individual message, because it has to be advertised in
+the server’s response to EHLO. String expansion failure causes a temporary
+error. A value of zero means no limit, but its use is not recommended. See also
+<option>bounce_return_size_limit</option>.
+</para>
+<para>
+Incoming SMTP messages are failed with a 552 error if the limit is
+exceeded; locally-generated messages either get a stderr message or a delivery
+failure message to the sender, depending on the <option>-oe</option> setting. Rejection of
+an oversized message is logged in both the main and the reject logs. See also
+the generic transport option <option>message_size_limit</option>, which limits the size of
+message that an individual transport can process.
+</para>
+<para>
+If you use a virus-scanner and set this option to to a value larger than the
+maximum size that your virus-scanner is configured to support, you may get
+failures triggered by large mails. The right size to configure for the
+virus-scanner depends upon what data is passed and the options in use but it’s
+probably safest to just set it to a little larger than this value. E.g., with a
+default Exim message size of 50M and a default ClamAV StreamMaxLength of 10M,
+some problems may result.
+</para>
+<para>
+A value of 0 will disable size limit checking; Exim will still advertise the
+SIZE extension in an EHLO response, but without a limit, so as to permit
+SMTP clients to still indicate the message size along with the MAIL verb.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>move_frozen_messages</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>move_frozen_messages</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>moving</secondary>
+</indexterm>
+This option, which is available only if Exim has been built with the setting
+</para>
+<literallayout class="monospaced">
+SUPPORT_MOVE_FROZEN_MESSAGES=yes
+</literallayout>
+<para>
+in <filename>Local/Makefile</filename>, causes frozen messages and their message logs to be
+moved from the <filename>input</filename> and <filename>msglog</filename> directories on the spool to <filename>Finput</filename>
+and <filename>Fmsglog</filename>, respectively. There is currently no support in Exim or the
+standard utilities for handling such moved messages, and they do not show up in
+lists generated by <option>-bp</option> or by the Exim monitor.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mua_wrapper</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>mua_wrapper</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Setting this option true causes Exim to run in a very restrictive mode in which
+it passes messages synchronously to a smart host. Chapter <xref linkend="CHAPnonqueueing"/>
+contains a full description of this facility.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mysql_servers</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>mysql_servers</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>MySQL</primary>
+<secondary>server list</secondary>
+</indexterm>
+This option provides a list of MySQL servers and associated connection data, to
+be used in conjunction with <command>mysql</command> lookups (see section <xref linkend="SECID72"/>). The
+option is available only if Exim has been built with MySQL support.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>never_users</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>never_users</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option is expanded just once, at the start of Exim’s processing. Local
+message deliveries are normally run in processes that are setuid to the
+recipient, and remote deliveries are normally run under Exim’s own uid and gid.
+It is usually desirable to prevent any deliveries from running as root, as a
+safety precaution.
+</para>
+<para>
+When Exim is built, an option called FIXED_NEVER_USERS can be set to a
+list of users that must not be used for local deliveries. This list is fixed in
+the binary and cannot be overridden by the configuration file. By default, it
+contains just the single user name <quote>root</quote>. The <option>never_users</option> runtime option
+can be used to add more users to the fixed list.
+</para>
+<para>
+If a message is to be delivered as one of the users on the fixed list or the
+<option>never_users</option> list, an error occurs, and delivery is deferred. A common
+example is
+</para>
+<literallayout class="monospaced">
+never_users = root:daemon:bin
+</literallayout>
+<para>
+Including root is redundant if it is also on the fixed list, but it does no
+harm. This option overrides the <option>pipe_as_creator</option> option of the <command>pipe</command>
+transport driver.
+</para>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>notifier_socket</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all" revisionflag="changed">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>notifier_socket</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>$spool_directory/exim_daemon_notify</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para revisionflag="changed">
+This option gives the name for a unix-domain socket on which the daemon
+listens for work and information-requests.
+Only installations running multiple daemons sharing a spool directory
+should need to modify the default.
+</para>
+<para revisionflag="changed">
+The option is expanded before use.
+If the platform supports Linux-style abstract socket names, the result
+is used with a nul byte prefixed.
+Otherwise, it should be a full path name and use a directory accessible
+to Exim.
+</para>
+<para revisionflag="changed">
+If the Exim command line uses a <option>-oX</option> option and does not use <option>-oP</option>
+then a notifier socket is not created.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>openssl_options</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>openssl_options</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>+no_sslv2 +no_sslv3 +single_dh_use +no_ticket +no_renegotiation</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>OpenSSL </primary>
+<secondary>compatibility</secondary>
+</indexterm>
+This option allows an administrator to adjust the SSL options applied
+by OpenSSL to connections. It is given as a space-separated list of items,
+each one to be +added or -subtracted from the current value.
+</para>
+<para>
+This option is only available if Exim is built against OpenSSL. The values
+available for this option vary according to the age of your OpenSSL install.
+The <quote>all</quote> value controls a subset of flags which are available, typically
+the bug workaround options. The <emphasis>SSL_CTX_set_options</emphasis> man page will
+list the values known on your system and Exim should support all the
+<quote>bug workaround</quote> options and many of the <quote>modifying</quote> options. The Exim
+names lose the leading <quote>SSL_OP_</quote> and are lower-cased.
+</para>
+<para>
+Note that adjusting the options can have severe impact upon the security of
+SSL as used by Exim. It is possible to disable safety checks and shoot
+yourself in the foot in various unpleasant ways. This option should not be
+adjusted lightly. An unrecognised item will be detected at startup, by
+invoking Exim with the <option>-bV</option> flag.
+</para>
+<para>
+The option affects Exim operating both as a server and as a client.
+</para>
+<para>
+Historical note: prior to release 4.80, Exim defaulted this value to
+"+dont_insert_empty_fragments", which may still be needed for compatibility
+with some clients, but which lowers security by increasing exposure to
+some now infamous attacks.
+</para>
+<para>
+Examples:
+</para>
+<literallayout class="monospaced">
+# Make both old MS and old Eudora happy:
+openssl_options = -all +microsoft_big_sslv3_buffer \
+ +dont_insert_empty_fragments
+
+# Disable older protocol versions:
+openssl_options = +no_sslv2 +no_sslv3
+</literallayout>
+<para>
+Possible options may include:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<literal>all</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>allow_unsafe_legacy_renegotiation</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>cipher_server_preference</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>dont_insert_empty_fragments</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>ephemeral_rsa</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>legacy_server_connect</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>microsoft_big_sslv3_buffer</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>microsoft_sess_id_bug</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>msie_sslv2_rsa_padding</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>netscape_challenge_bug</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>netscape_reuse_cipher_change_bug</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>no_compression</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>no_session_resumption_on_renegotiation</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>no_sslv2</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>no_sslv3</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>no_ticket</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>no_tlsv1</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>no_tlsv1_1</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>no_tlsv1_2</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>safari_ecdhe_ecdsa_bug</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>single_dh_use</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>single_ecdh_use</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>ssleay_080_client_dh_bug</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>sslref2_reuse_cert_type_bug</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>tls_block_padding_bug</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>tls_d5_bug</literal>
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>tls_rollback_bug</literal>
+</para>
+</listitem>
+</itemizedlist>
+<para>
+As an aside, the <literal>safari_ecdhe_ecdsa_bug</literal> item is a misnomer and affects
+all clients connecting using the MacOS SecureTransport TLS facility prior
+to MacOS 10.8.4, including email clients. If you see old MacOS clients failing
+to negotiate TLS then this option value might help, provided that your OpenSSL
+release is new enough to contain this work-around. This may be a situation
+where you have to upgrade OpenSSL to get buggy clients working.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>oracle_servers</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>oracle_servers</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>Oracle</primary>
+<secondary>server list</secondary>
+</indexterm>
+This option provides a list of Oracle servers and associated connection data,
+to be used in conjunction with <command>oracle</command> lookups (see section <xref linkend="SECID72"/>).
+The option is available only if Exim has been built with Oracle support.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>percent_hack_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>percent_hack_domains</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><quote>percent hack</quote></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>source routing</primary>
+<secondary>in email address</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address</primary>
+<secondary>source-routed</secondary>
+</indexterm>
+The <quote>percent hack</quote> is the convention whereby a local part containing a
+percent sign is re-interpreted as a new email address, with the percent
+replaced by @. This is sometimes called <quote>source routing</quote>, though that term is
+also applied to RFC 2822 addresses that begin with an @ character. If this
+option is set, Exim implements the percent facility for those domains listed,
+but no others. This happens before an incoming SMTP address is tested against
+an ACL.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: The <quote>percent hack</quote> has often been abused by people who are
+trying to get round relaying restrictions. For this reason, it is best avoided
+if at all possible. Unfortunately, a number of less security-conscious MTAs
+implement it unconditionally. If you are running Exim on a gateway host, and
+routing mail through to internal MTAs without processing the local parts, it is
+a good idea to reject recipient addresses with percent characters in their
+local parts. Exim’s default configuration does this.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>perl_at_start</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>perl_at_start</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>Perl</primary>
+</indexterm>
+This option is available only when Exim is built with an embedded Perl
+interpreter. See chapter <xref linkend="CHAPperl"/> for details of its use.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>perl_startup</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>perl_startup</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>Perl</primary>
+</indexterm>
+This option is available only when Exim is built with an embedded Perl
+interpreter. See chapter <xref linkend="CHAPperl"/> for details of its use.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>perl_taintmode</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>perl_taintmode</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>Perl</primary>
+</indexterm>
+This option enables the taint mode of the embedded Perl interpreter.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>pgsql_servers</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>pgsql_servers</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>PostgreSQL lookup type</primary>
+<secondary>server list</secondary>
+</indexterm>
+This option provides a list of PostgreSQL servers and associated connection
+data, to be used in conjunction with <command>pgsql</command> lookups (see section
+<xref linkend="SECID72"/>). The option is available only if Exim has been built with
+PostgreSQL support.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>pid_file_path</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>pid_file_path</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>set at compile time</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>daemon</primary>
+<secondary>pid file path</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>pid file, path for</primary>
+</indexterm>
+This option sets the name of the file to which the Exim daemon writes its
+process id. The string is expanded, so it can contain, for example, references
+to the host name:
+</para>
+<literallayout class="monospaced">
+pid_file_path = /var/log/$primary_hostname/exim.pid
+</literallayout>
+<para>
+If no path is set, the pid is written to the file <filename>exim-daemon.pid</filename> in Exim’s
+spool directory.
+The value set by the option can be overridden by the <option>-oP</option> command line
+option. A pid file is not written if a <quote>non-standard</quote> daemon is run by means
+of the <option>-oX</option> option, unless a path is explicitly supplied by <option>-oP</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>pipelining_advertise_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>pipelining_advertise_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>PIPELINING</primary>
+<secondary>suppressing advertising</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>PIPELINING</secondary>
+</indexterm>
+This option can be used to suppress the advertisement of the SMTP
+PIPELINING extension to specific hosts. See also the <emphasis role="bold">no_pipelining</emphasis>
+control in section <xref linkend="SECTcontrols"/>. When PIPELINING is not advertised and
+<option>smtp_enforce_sync</option> is true, an Exim server enforces strict synchronization
+for each SMTP command and response. When PIPELINING is advertised, Exim assumes
+that clients will use it; <quote>out of order</quote> commands that are <quote>expected</quote> do
+not count as protocol errors (see <option>smtp_max_synprot_errors</option>).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>pipelining_connect_advertise_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>pipelining_connect_advertise_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>pipelining</primary>
+<secondary>early connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>pipelining</primary>
+<secondary>PIPE_CONNECT</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>X_PIPE_CONNECT</secondary>
+</indexterm>
+If Exim is built with the SUPPORT_PIPE_CONNECT build option
+this option controls which hosts the facility is advertised to
+and from which pipeline early-connection (before MAIL) SMTP
+commands are acceptable.
+When used, the pipelining saves on roundtrip times.
+</para>
+<para>
+See also the <option>hosts_pipe_connect</option> smtp transport option.
+</para>
+<para>
+Currently the option name <quote>X_PIPE_CONNECT</quote> is used.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>prdr_enable</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>prdr_enable</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>PRDR</primary>
+<secondary>enabling on server</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>PRDR</secondary>
+</indexterm>
+This option can be used to enable the Per-Recipient Data Response extension
+to SMTP, defined by Eric Hall.
+If the option is set, PRDR is advertised by Exim when operating as a server.
+If the client requests PRDR, and more than one recipient, for a message
+an additional ACL is called for each recipient after the message content
+is received. See section <xref linkend="SECTPRDRACL"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>preserve_message_logs</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>preserve_message_logs</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>message logs</primary>
+<secondary>preserving</secondary>
+</indexterm>
+If this option is set, message log files are not deleted when messages are
+completed. Instead, they are moved to a sub-directory of the spool directory
+called <filename>msglog.OLD</filename>, where they remain available for statistical or debugging
+purposes. This is a dangerous option to set on systems with any appreciable
+volume of mail. Use with care!
+</para>
+<para>
+<indexterm role="option">
+<primary><option>primary_hostname</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>primary_hostname</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>name</primary>
+<secondary>of local host</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>name of local</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local host</primary>
+<secondary>name of</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$primary_hostname</varname></primary>
+</indexterm>
+This specifies the name of the current host. It is used in the default EHLO or
+HELO command for outgoing SMTP messages (changeable via the <option>helo_data</option>
+option in the <command>smtp</command> transport), and as the default for <option>qualify_domain</option>.
+The value is also used by default in some SMTP response messages from an Exim
+server. This can be changed dynamically by setting <option>smtp_active_hostname</option>.
+</para>
+<para>
+If <option>primary_hostname</option> is not set, Exim calls <function>uname()</function> to find the host
+name. If this fails, Exim panics and dies. If the name returned by <function>uname()</function>
+contains only one component, Exim passes it to <function>gethostbyname()</function> (or
+<function>getipnodebyname()</function> when available) in order to obtain the fully qualified
+version. The variable <varname>$primary_hostname</varname> contains the host name, whether set
+explicitly by this option, or defaulted.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>print_topbitchars</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>print_topbitchars</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>printing characters</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>8-bit characters</primary>
+</indexterm>
+By default, Exim considers only those characters whose codes lie in the range
+32–126 to be printing characters. In a number of circumstances (for example,
+when writing log entries) non-printing characters are converted into escape
+sequences, primarily to avoid messing up the layout. If <option>print_topbitchars</option>
+is set, code values of 128 and above are also considered to be printing
+characters.
+</para>
+<para>
+This option also affects the header syntax checks performed by the
+<command>autoreply</command> transport, and whether Exim uses RFC 2047 encoding of
+the user’s full name when constructing From: and Sender: addresses (as
+described in section <xref linkend="SECTconstr"/>). Setting this option can cause
+Exim to generate eight bit message headers that do not conform to the
+standards.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>process_log_path</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>process_log_path</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>process log path</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>process log</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>exiwhat</emphasis></primary>
+</indexterm>
+This option sets the name of the file to which an Exim process writes its
+<quote>process log</quote> when sent a USR1 signal. This is used by the <emphasis>exiwhat</emphasis>
+utility script. If this option is unset, the file called <filename>exim-process.info</filename>
+in Exim’s spool directory is used. The ability to specify the name explicitly
+can be useful in environments where two different Exims are running, using
+different spool directories.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>prod_requires_admin</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>prod_requires_admin</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-M</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-R</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-q</option></primary>
+</indexterm>
+The <option>-M</option>, <option>-R</option>, and <option>-q</option> command-line options require the caller to be an
+admin user unless <option>prod_requires_admin</option> is set false. See also
+<option>queue_list_requires_admin</option> and <option>commandline_checks_require_admin</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>qualify_domain</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>qualify_domain</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>domain</primary>
+<secondary>for qualifying addresses</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address</primary>
+<secondary>qualification</secondary>
+</indexterm>
+This option specifies the domain name that is added to any envelope sender
+addresses that do not have a domain qualification. It also applies to
+recipient addresses if <option>qualify_recipient</option> is not set. Unqualified addresses
+are accepted by default only for locally-generated messages. Qualification is
+also applied to addresses in header lines such as <emphasis>From:</emphasis> and <emphasis>To:</emphasis> for
+locally-generated messages, unless the <option>-bnq</option> command line option is used.
+</para>
+<para>
+Messages from external sources must always contain fully qualified addresses,
+unless the sending host matches <option>sender_unqualified_hosts</option> or
+<option>recipient_unqualified_hosts</option> (as appropriate), in which case incoming
+addresses are qualified with <option>qualify_domain</option> or <option>qualify_recipient</option> as
+necessary. Internally, Exim always works with fully qualified envelope
+addresses. If <option>qualify_domain</option> is not set, it defaults to the
+<option>primary_hostname</option> value.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>qualify_recipient</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>qualify_recipient</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option allows you to specify a different domain for qualifying recipient
+addresses to the one that is used for senders. See <option>qualify_domain</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>queue_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>queue_domains</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>domain</primary>
+<secondary>specifying non-immediate delivery</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>queueing incoming messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>queueing certain domains</secondary>
+</indexterm>
+This option lists domains for which immediate delivery is not required.
+A delivery process is started whenever a message is received, but only those
+domains that do not match are processed. All other deliveries wait until the
+next queue run. See also <option>hold_domains</option> and <option>queue_smtp_domains</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>queue_list_requires_admin</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>queue_list_requires_admin</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-bp</option></primary>
+</indexterm>
+The <option>-bp</option> command-line option, which lists the messages that are on the
+queue, requires the caller to be an admin user unless
+<option>queue_list_requires_admin</option> is set false.
+See also <option>prod_requires_admin</option> and <option>commandline_checks_require_admin</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>queue_only</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>queue_only</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>queueing incoming messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>queueing unconditionally</secondary>
+</indexterm>
+If <option>queue_only</option> is set, a delivery process is not automatically started
+whenever a message is received. Instead, the message waits in the queue for the
+next queue run. Even if <option>queue_only</option> is false, incoming messages may not get
+delivered immediately when certain conditions (such as heavy load) occur.
+</para>
+<para>
+The <option>-odq</option> command line has the same effect as <option>queue_only</option>. The <option>-odb</option>
+and <option>-odi</option> command line options override <option>queue_only</option> unless
+<option>queue_only_override</option> is set false. See also <option>queue_only_file</option>,
+<option>queue_only_load</option>, and <option>smtp_accept_queue</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>queue_only_file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>queue_only_file</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>queueing incoming messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>queueing by file existence</secondary>
+</indexterm>
+This option can be set to a colon-separated list of absolute path names, each
+one optionally preceded by <quote>smtp</quote>. When Exim is receiving a message,
+it tests for the existence of each listed path using a call to <function>stat()</function>. For
+each path that exists, the corresponding queueing option is set.
+For paths with no prefix, <option>queue_only</option> is set; for paths prefixed by
+<quote>smtp</quote>, <option>queue_smtp_domains</option> is set to match all domains. So, for example,
+</para>
+<literallayout class="monospaced">
+queue_only_file = smtp/some/file
+</literallayout>
+<para>
+causes Exim to behave as if <option>queue_smtp_domains</option> were set to <quote>*</quote> whenever
+<filename>/some/file</filename> exists.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>queue_only_load</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>queue_only_load</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>fixed-point</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>load average</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queueing incoming messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>queueing by load</secondary>
+</indexterm>
+If the system load average is higher than this value, incoming messages from
+all sources are queued, and no automatic deliveries are started. If this
+happens during local or remote SMTP input, all subsequent messages received on
+the same SMTP connection are queued by default, whatever happens to the load in
+the meantime, but this can be changed by setting <option>queue_only_load_latch</option>
+false.
+</para>
+<para>
+Deliveries will subsequently be performed by queue runner processes. This
+option has no effect on ancient operating systems on which Exim cannot
+determine the load average. See also <option>deliver_queue_load_max</option> and
+<option>smtp_load_reserve</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>queue_only_load_latch</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>queue_only_load_latch</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>load average</primary>
+<secondary>re-evaluating per message</secondary>
+</indexterm>
+When this option is true (the default), once one message has been queued
+because the load average is higher than the value set by <option>queue_only_load</option>,
+all subsequent messages received on the same SMTP connection are also queued.
+This is a deliberate choice; even though the load average may fall below the
+threshold, it doesn’t seem right to deliver later messages on the same
+connection when not delivering earlier ones. However, there are special
+circumstances such as very long-lived connections from scanning appliances
+where this is not the best strategy. In such cases, <option>queue_only_load_latch</option>
+should be set false. This causes the value of the load average to be
+re-evaluated for each message.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>queue_only_override</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>queue_only_override</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>queueing incoming messages</primary>
+</indexterm>
+When this option is true, the <option>-od</option><emphasis>x</emphasis> command line options override the
+setting of <option>queue_only</option> or <option>queue_only_file</option> in the configuration file. If
+<option>queue_only_override</option> is set false, the <option>-od</option><emphasis>x</emphasis> options cannot be used
+to override; they are accepted, but ignored.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>queue_run_in_order</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>queue_run_in_order</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>queue runner</primary>
+<secondary>processing messages in order</secondary>
+</indexterm>
+If this option is set, queue runs happen in order of message arrival instead of
+in an arbitrary order. For this to happen, a complete list of the entire queue
+must be set up before the deliveries start. When the queue is all held in a
+single directory (the default), a single list is created for both the ordered
+and the non-ordered cases. However, if <option>split_spool_directory</option> is set, a
+single list is not created when <option>queue_run_in_order</option> is false. In this case,
+the sub-directories are processed one at a time (in a random order), and this
+avoids setting up one huge list for the whole queue. Thus, setting
+<option>queue_run_in_order</option> with <option>split_spool_directory</option> may degrade performance
+when the queue is large, because of the extra work in setting up the single,
+large list. In most situations, <option>queue_run_in_order</option> should not be set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>queue_run_max</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>queue_run_max</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>5</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>queue runner</primary>
+<secondary>maximum number of</secondary>
+</indexterm>
+This controls the maximum number of queue runner processes that an Exim daemon
+can run simultaneously. This does not mean that it starts them all at once,
+but rather that if the maximum number are still running when the time comes to
+start another one, it refrains from starting another one. This can happen with
+very large queues and/or very sluggish deliveries. This option does not,
+however, interlock with other processes, so additional queue runners can be
+started by other means, or by killing and restarting the daemon.
+</para>
+<para>
+Setting this option to zero does not suppress queue runs; rather, it disables
+the limit, allowing any number of simultaneous queue runner processes to be
+run. If you do not want queue runs to occur, omit the <option>-q</option><emphasis>xx</emphasis> setting on
+the daemon’s command line.
+</para>
+<para>
+<indexterm role="concept">
+<primary>queues</primary>
+<secondary>named</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>named queues</primary>
+<secondary>resource limit</secondary>
+</indexterm>
+To set limits for different named queues use
+an expansion depending on the <varname>$queue_name</varname> variable.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>queue_smtp_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>queue_smtp_domains</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>queueing incoming messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>queueing remote deliveries</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>first pass routing</primary>
+</indexterm>
+When this option is set, a delivery process is started whenever a message is
+received, routing is performed, and local deliveries take place.
+However, if any SMTP deliveries are required for domains that match
+<option>queue_smtp_domains</option>, they are not immediately delivered, but instead the
+message waits in the queue for the next queue run. Since routing of the message
+has taken place, Exim knows to which remote hosts it must be delivered, and so
+when the queue run happens, multiple messages for the same host are delivered
+over a single SMTP connection. The <option>-odqs</option> command line option causes all
+SMTP deliveries to be queued in this way, and is equivalent to setting
+<option>queue_smtp_domains</option> to <quote>*</quote>. See also <option>hold_domains</option> and
+<option>queue_domains</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>receive_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>receive_timeout</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>0s</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>for non-SMTP input</secondary>
+</indexterm>
+This option sets the timeout for accepting a non-SMTP message, that is, the
+maximum time that Exim waits when reading a message on the standard input. If
+the value is zero, it will wait forever. This setting is overridden by the
+<option>-or</option> command line option. The timeout for incoming SMTP messages is
+controlled by <option>smtp_receive_timeout</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>received_header_text</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>received_header_text</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>customizing</primary>
+<secondary><emphasis>Received:</emphasis> header</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>Received:</emphasis> header line</primary>
+<secondary>customizing</secondary>
+</indexterm>
+This string defines the contents of the <emphasis>Received:</emphasis> message header that is
+added to each message, except for the timestamp, which is automatically added
+on at the end (preceded by a semicolon). The string is expanded each time it is
+used. If the expansion yields an empty string, no <emphasis>Received:</emphasis> header line is
+added to the message. Otherwise, the string should start with the text
+<quote>Received:</quote> and conform to the RFC 2822 specification for <emphasis>Received:</emphasis>
+header lines.
+The default setting is:
+</para>
+<literallayout class="monospaced">
+received_header_text = Received: \
+ ${if def:sender_rcvhost {from $sender_rcvhost\n\t}\
+ {${if def:sender_ident \
+ {from ${quote_local_part:$sender_ident} }}\
+ ${if def:sender_helo_name {(helo=$sender_helo_name)\n\t}}}}\
+ by $primary_hostname \
+ ${if def:received_protocol {with $received_protocol }}\
+ ${if def:tls_in_ver { ($tls_in_ver)}}\
+ ${if def:tls_in_cipher_std { tls $tls_in_cipher_std\n\t}}\
+ (Exim $version_number)\n\t\
+ ${if def:sender_address \
+ {(envelope-from <$sender_address>)\n\t}}\
+ id $message_exim_id\
+ ${if def:received_for {\n\tfor $received_for}}
+</literallayout>
+<para>
+The references to the TLS version and cipher are
+omitted when Exim is built without TLS
+support. The use of conditional expansions ensures that this works for both
+locally generated messages and messages received from remote hosts, giving
+header lines such as the following:
+</para>
+<literallayout class="monospaced">
+Received: from scrooge.carol.example ([192.168.12.25] ident=root)
+by marley.carol.example with esmtp (Exim 4.00)
+(envelope-from <bob@carol.example>)
+id 16IOWa-00019l-00
+for chas@dickens.example; Tue, 25 Dec 2001 14:43:44 +0000
+Received: by scrooge.carol.example with local (Exim 4.00)
+id 16IOWW-000083-00; Tue, 25 Dec 2001 14:43:41 +0000
+</literallayout>
+<para>
+Until the body of the message has been received, the timestamp is the time when
+the message started to be received. Once the body has arrived, and all policy
+checks have taken place, the timestamp is updated to the time at which the
+message was accepted.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>received_headers_max</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>received_headers_max</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>30</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>loop</primary>
+<secondary>prevention</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>mail loop prevention</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>Received:</emphasis> header line</primary>
+<secondary>counting</secondary>
+</indexterm>
+When a message is to be delivered, the number of <emphasis>Received:</emphasis> headers is
+counted, and if it is greater than this parameter, a mail loop is assumed to
+have occurred, the delivery is abandoned, and an error message is generated.
+This applies to both local and remote deliveries.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>recipient_unqualified_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>recipient_unqualified_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>unqualified addresses</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>unqualified addresses from</secondary>
+</indexterm>
+This option lists those hosts from which Exim is prepared to accept unqualified
+recipient addresses in message envelopes. The addresses are made fully
+qualified by the addition of the <option>qualify_recipient</option> value. This option also
+affects message header lines. Exim does not reject unqualified recipient
+addresses in headers, but it qualifies them only if the message came from a
+host that matches <option>recipient_unqualified_hosts</option>,
+or if the message was submitted locally (not using TCP/IP), and the <option>-bnq</option>
+option was not set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>recipients_max</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>recipients_max</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>0</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>number of recipients</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>recipient</primary>
+<secondary>maximum number</secondary>
+</indexterm>
+If this option is set greater than zero, it specifies the maximum number of
+original recipients for any message. Additional recipients that are generated
+by aliasing or forwarding do not count. SMTP messages get a 452 response for
+all recipients over the limit; earlier recipients are delivered as normal.
+Non-SMTP messages with too many recipients are failed, and no deliveries are
+done.
+</para>
+<para>
+<indexterm role="concept">
+<primary>RCPT</primary>
+<secondary>maximum number of incoming</secondary>
+</indexterm>
+<emphasis role="bold">Note</emphasis>: The RFCs specify that an SMTP server should accept at least 100
+RCPT commands in a single message.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>recipients_max_reject</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>recipients_max_reject</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is set true, Exim rejects SMTP messages containing too many
+recipients by giving 552 errors to the surplus RCPT commands, and a 554
+error to the eventual DATA command. Otherwise (the default) it gives a 452
+error to the surplus RCPT commands and accepts the message on behalf of the
+initial set of recipients. The remote server should then re-send the message
+for the remaining recipients at a later time.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>remote_max_parallel</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>remote_max_parallel</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>2</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>parallelism for remote</secondary>
+</indexterm>
+This option controls parallel delivery of one message to a number of remote
+hosts. If the value is less than 2, parallel delivery is disabled, and Exim
+does all the remote deliveries for a message one by one. Otherwise, if a single
+message has to be delivered to more than one remote host, or if several copies
+have to be sent to the same remote host, up to <option>remote_max_parallel</option>
+deliveries are done simultaneously. If more than <option>remote_max_parallel</option>
+deliveries are required, the maximum number of processes are started, and as
+each one finishes, another is begun. The order of starting processes is the
+same as if sequential delivery were being done, and can be controlled by the
+<option>remote_sort_domains</option> option. If parallel delivery takes place while running
+with debugging turned on, the debugging output from each delivery process is
+tagged with its process id.
+</para>
+<para>
+This option controls only the maximum number of parallel deliveries for one
+message in one Exim delivery process. Because Exim has no central queue
+manager, there is no way of controlling the total number of simultaneous
+deliveries if the configuration allows a delivery attempt as soon as a message
+is received.
+</para>
+<para>
+<indexterm role="concept">
+<primary>number of deliveries</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>maximum number of</secondary>
+</indexterm>
+If you want to control the total number of deliveries on the system, you
+need to set the <option>queue_only</option> option. This ensures that all incoming messages
+are added to the queue without starting a delivery process. Then set up an Exim
+daemon to start queue runner processes at appropriate intervals (probably
+fairly often, for example, every minute), and limit the total number of queue
+runners by setting the <option>queue_run_max</option> parameter. Because each queue runner
+delivers only one message at a time, the maximum number of deliveries that can
+then take place at once is <option>queue_run_max</option> multiplied by
+<option>remote_max_parallel</option>.
+</para>
+<para>
+If it is purely remote deliveries you want to control, use
+<option>queue_smtp_domains</option> instead of <option>queue_only</option>. This has the added benefit of
+doing the SMTP routing before queueing, so that several messages for the same
+host will eventually get delivered down the same connection.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>remote_sort_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>remote_sort_domains</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>sorting remote deliveries</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>sorting remote</secondary>
+</indexterm>
+When there are a number of remote deliveries for a message, they are sorted by
+domain into the order given by this list. For example,
+</para>
+<literallayout class="monospaced">
+remote_sort_domains = *.cam.ac.uk:*.uk
+</literallayout>
+<para>
+would attempt to deliver to all addresses in the <emphasis>cam.ac.uk</emphasis> domain first,
+then to those in the <option>uk</option> domain, then to any others.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>retry_data_expire</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>retry_data_expire</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>7d</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>data expiry</secondary>
+</indexterm>
+This option sets a <quote>use before</quote> time on retry information in Exim’s hints
+database. Any older retry data is ignored. This means that, for example, once a
+host has not been tried for 7 days, Exim behaves as if it has no knowledge of
+past failures.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>retry_interval_max</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>retry_interval_max</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>24h</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>limit on interval</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>on retry interval</secondary>
+</indexterm>
+Chapter <xref linkend="CHAPretry"/> describes Exim’s mechanisms for controlling the
+intervals between delivery attempts for messages that cannot be delivered
+straight away. This option sets an overall limit to the length of time between
+retries. It cannot be set greater than 24 hours; any attempt to do so forces
+the default value.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>return_path_remove</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>return_path_remove</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Return-path:</emphasis> header line</primary>
+<secondary>removing</secondary>
+</indexterm>
+RFC 2821, section 4.4, states that an SMTP server must insert a
+<emphasis>Return-path:</emphasis> header line into a message when it makes a <quote>final delivery</quote>.
+The <emphasis>Return-path:</emphasis> header preserves the sender address as received in the
+MAIL command. This description implies that this header should not be present
+in an incoming message. If <option>return_path_remove</option> is true, any existing
+<emphasis>Return-path:</emphasis> headers are removed from messages at the time they are
+received. Exim’s transports have options for adding <emphasis>Return-path:</emphasis> headers at
+the time of delivery. They are normally used only for final local deliveries.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>return_size_limit</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>return_size_limit</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>100K</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option is an obsolete synonym for <option>bounce_return_size_limit</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>rfc1413_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>rfc1413_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>@[]</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>RFC 1413</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>for RFC 1413 calls</secondary>
+</indexterm>
+RFC 1413 identification calls are made to any client host which matches
+an item in the list.
+The default value specifies just this host, being any local interface
+for the system.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>rfc1413_query_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>rfc1413_query_timeout</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>0s</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>RFC 1413</primary>
+<secondary>query timeout</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>for RFC 1413 call</secondary>
+</indexterm>
+This sets the timeout on RFC 1413 identification calls. If it is set to zero,
+no RFC 1413 calls are ever made.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>sender_unqualified_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>sender_unqualified_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>unqualified addresses</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>unqualified addresses from</secondary>
+</indexterm>
+This option lists those hosts from which Exim is prepared to accept unqualified
+sender addresses. The addresses are made fully qualified by the addition of
+<option>qualify_domain</option>. This option also affects message header lines. Exim does
+not reject unqualified addresses in headers that contain sender addresses, but
+it qualifies them only if the message came from a host that matches
+<option>sender_unqualified_hosts</option>, or if the message was submitted locally (not
+using TCP/IP), and the <option>-bnq</option> option was not set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>slow_lookup_log</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>slow_lookup_log</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>0</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>logging</primary>
+<secondary>slow lookups</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>dns</primary>
+<secondary>logging slow lookups</secondary>
+</indexterm>
+This option controls logging of slow lookups.
+If the value is nonzero it is taken as a number of milliseconds
+and lookups taking longer than this are logged.
+Currently this applies only to DNS lookups.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_accept_keepalive</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_accept_keepalive</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>keepalive</primary>
+<secondary>on incoming connection</secondary>
+</indexterm>
+This option controls the setting of the SO_KEEPALIVE option on incoming
+TCP/IP socket connections. When set, it causes the kernel to probe idle
+connections periodically, by sending packets with <quote>old</quote> sequence numbers. The
+other end of the connection should send an acknowledgment if the connection is
+still okay or a reset if the connection has been aborted. The reason for doing
+this is that it has the beneficial effect of freeing up certain types of
+connection that can get stuck when the remote host is disconnected without
+tidying up the TCP/IP call properly. The keepalive mechanism takes several
+hours to detect unreachable hosts.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_accept_max</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_accept_max</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>20</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>incoming SMTP connections</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>incoming connection count</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>inetd</primary>
+</indexterm>
+This option specifies the maximum number of simultaneous incoming SMTP calls
+that Exim will accept. It applies only to the listening daemon; there is no
+control (in Exim) when incoming SMTP is being handled by <emphasis>inetd</emphasis>. If the
+value is set to zero, no limit is applied. However, it is required to be
+non-zero if either <option>smtp_accept_max_per_host</option> or <option>smtp_accept_queue</option> is
+set. See also <option>smtp_accept_reserve</option> and <option>smtp_load_reserve</option>.
+</para>
+<para>
+A new SMTP connection is immediately rejected if the <option>smtp_accept_max</option> limit
+has been reached. If not, Exim first checks <option>smtp_accept_max_per_host</option>. If
+that limit has not been reached for the client host, <option>smtp_accept_reserve</option>
+and <option>smtp_load_reserve</option> are then checked before accepting the connection.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_accept_max_nonmail</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_accept_max_nonmail</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>10</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>non-mail SMTP commands</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>limiting non-mail commands</secondary>
+</indexterm>
+Exim counts the number of <quote>non-mail</quote> commands in an SMTP session, and drops
+the connection if there are too many. This option defines <quote>too many</quote>. The
+check catches some denial-of-service attacks, repeated failing AUTHs, or a mad
+client looping sending EHLO, for example. The check is applied only if the
+client host matches <option>smtp_accept_max_nonmail_hosts</option>.
+</para>
+<para>
+When a new message is expected, one occurrence of RSET is not counted. This
+allows a client to send one RSET between messages (this is not necessary,
+but some clients do it). Exim also allows one uncounted occurrence of HELO
+or EHLO, and one occurrence of STARTTLS between messages. After
+starting up a TLS session, another EHLO is expected, and so it too is not
+counted. The first occurrence of AUTH in a connection, or immediately
+following STARTTLS is not counted. Otherwise, all commands other than
+MAIL, RCPT, DATA, and QUIT are counted.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_accept_max_nonmail_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_accept_max_nonmail_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+You can control which hosts are subject to the <option>smtp_accept_max_nonmail</option>
+check by setting this option. The default value makes it apply to all hosts. By
+changing the value, you can exclude any badly-behaved hosts that you have to
+live with.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_accept_max_per_connection</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_accept_max_per_connection</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>1000</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>limiting incoming message count</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>messages per SMTP connection</secondary>
+</indexterm>
+The value of this option limits the number of MAIL commands that Exim is
+prepared to accept over a single SMTP connection, whether or not each command
+results in the transfer of a message. After the limit is reached, a 421
+response is given to subsequent MAIL commands. This limit is a safety
+precaution against a client that goes mad (incidents of this type have been
+seen).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_accept_max_per_host</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_accept_max_per_host</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>SMTP connections from one host</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>limiting SMTP connections from</secondary>
+</indexterm>
+This option restricts the number of simultaneous IP connections from a single
+host (strictly, from a single IP address) to the Exim daemon. The option is
+expanded, to enable different limits to be applied to different hosts by
+reference to <varname>$sender_host_address</varname>. Once the limit is reached, additional
+connection attempts from the same host are rejected with error code 421. This
+is entirely independent of <option>smtp_accept_reserve</option>. The option’s default value
+of zero imposes no limit. If this option is set greater than zero, it is
+required that <option>smtp_accept_max</option> be non-zero.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: When setting this option you should not use any expansion
+constructions that take an appreciable amount of time. The expansion and test
+happen in the main daemon loop, in order to reject additional connections
+without forking additional processes (otherwise a denial-of-service attack
+could cause a vast number or processes to be created). While the daemon is
+doing this processing, it cannot accept any other incoming connections.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_accept_queue</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_accept_queue</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>0</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>incoming connection count</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>queueing incoming messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>queueing by SMTP connection count</secondary>
+</indexterm>
+If the number of simultaneous incoming SMTP connections being handled via the
+listening daemon exceeds this value, messages received by SMTP are just placed
+in the queue; no delivery processes are started automatically. The count is
+fixed at the start of an SMTP connection. It cannot be updated in the
+subprocess that receives messages, and so the queueing or not queueing applies
+to all messages received in the same connection.
+</para>
+<para>
+A value of zero implies no limit, and clearly any non-zero value is useful only
+if it is less than the <option>smtp_accept_max</option> value (unless that is zero). See
+also <option>queue_only</option>, <option>queue_only_load</option>, <option>queue_smtp_domains</option>, and the
+various <option>-od</option><emphasis>x</emphasis> command line options.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_accept_queue_per_connection</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_accept_queue_per_connection</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>10</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>queueing incoming messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>queueing by message count</secondary>
+</indexterm>
+This option limits the number of delivery processes that Exim starts
+automatically when receiving messages via SMTP, whether via the daemon or by
+the use of <option>-bs</option> or <option>-bS</option>. If the value of the option is greater than zero,
+and the number of messages received in a single SMTP session exceeds this
+number, subsequent messages are placed in the queue, but no delivery processes
+are started. This helps to limit the number of Exim processes when a server
+restarts after downtime and there is a lot of mail waiting for it on other
+systems. On large systems, the default should probably be increased, and on
+dial-in client systems it should probably be set to zero (that is, disabled).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_accept_reserve</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_accept_reserve</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>0</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>incoming call count</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>reserved</secondary>
+</indexterm>
+When <option>smtp_accept_max</option> is set greater than zero, this option specifies a
+number of SMTP connections that are reserved for connections from the hosts
+that are specified in <option>smtp_reserve_hosts</option>. The value set in
+<option>smtp_accept_max</option> includes this reserve pool. The specified hosts are not
+restricted to this number of connections; the option specifies a minimum number
+of connection slots for them, not a maximum. It is a guarantee that this group
+of hosts can always get at least <option>smtp_accept_reserve</option> connections. However,
+the limit specified by <option>smtp_accept_max_per_host</option> is still applied to each
+individual host.
+</para>
+<para>
+For example, if <option>smtp_accept_max</option> is set to 50 and <option>smtp_accept_reserve</option> is
+set to 5, once there are 45 active connections (from any hosts), new
+connections are accepted only from hosts listed in <option>smtp_reserve_hosts</option>,
+provided the other criteria for acceptance are met.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_active_hostname</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_active_hostname</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>name in SMTP responses</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>host name in responses</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$primary_hostname</varname></primary>
+</indexterm>
+This option is provided for multi-homed servers that want to masquerade as
+several different hosts. At the start of an incoming SMTP connection, its value
+is expanded and used instead of the value of <varname>$primary_hostname</varname> in SMTP
+responses. For example, it is used as domain name in the response to an
+incoming HELO or EHLO command.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$smtp_active_hostname</varname></primary>
+</indexterm>
+The active hostname is placed in the <varname>$smtp_active_hostname</varname> variable, which
+is saved with any messages that are received. It is therefore available for use
+in routers and transports when the message is later delivered.
+</para>
+<para>
+If this option is unset, or if its expansion is forced to fail, or if the
+expansion results in an empty string, the value of <varname>$primary_hostname</varname> is
+used. Other expansion failures cause a message to be written to the main and
+panic logs, and the SMTP command receives a temporary error. Typically, the
+value of <option>smtp_active_hostname</option> depends on the incoming interface address.
+For example:
+</para>
+<literallayout class="monospaced">
+smtp_active_hostname = ${if eq{$received_ip_address}{10.0.0.1}\
+ {cox.mydomain}{box.mydomain}}
+</literallayout>
+<para>
+Although <varname>$smtp_active_hostname</varname> is primarily concerned with incoming
+messages, it is also used as the default for HELO commands in callout
+verification if there is no remote transport from which to obtain a
+<option>helo_data</option> value.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_banner</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_banner</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>welcome banner</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>banner for SMTP</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>welcome banner for SMTP</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>customizing</primary>
+<secondary>SMTP banner</secondary>
+</indexterm>
+This string, which is expanded every time it is used, is output as the initial
+positive response to an SMTP connection. The default setting is:
+</para>
+<literallayout class="monospaced">
+smtp_banner = $smtp_active_hostname ESMTP Exim \
+ $version_number $tod_full
+</literallayout>
+<para>
+Failure to expand the string causes a panic error. If you want to create a
+multiline response to the initial SMTP connection, use <quote>\n</quote> in the string at
+appropriate points, but not at the end. Note that the 220 code is not included
+in this string. Exim adds it automatically (several times in the case of a
+multiline response).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_check_spool_space</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_check_spool_space</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>checking disk space</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>disk space, checking</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>spool directory</primary>
+<secondary>checking space</secondary>
+</indexterm>
+When this option is set, if an incoming SMTP session encounters the SIZE
+option on a MAIL command, it checks that there is enough space in the
+spool directory’s partition to accept a message of that size, while still
+leaving free the amount specified by <option>check_spool_space</option> (even if that value
+is zero). If there isn’t enough space, a temporary error code is returned.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_connect_backlog</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_connect_backlog</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>20</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>connection backlog</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>connection backlog</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>backlog of connections</primary>
+</indexterm>
+This option specifies a maximum number of waiting SMTP connections. Exim passes
+this value to the TCP/IP system when it sets up its listener. Once this number
+of connections are waiting for the daemon’s attention, subsequent connection
+attempts are refused at the TCP/IP level. At least, that is what the manuals
+say; in some circumstances such connection attempts have been observed to time
+out instead. For large systems it is probably a good idea to increase the
+value (to 50, say). It also gives some protection against denial-of-service
+attacks by SYN flooding.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_enforce_sync</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_enforce_sync</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>synchronization checking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>synchronization checking in SMTP</primary>
+</indexterm>
+The SMTP protocol specification requires the client to wait for a response from
+the server at certain points in the dialogue. Without PIPELINING these
+synchronization points are after every command; with PIPELINING they are
+fewer, but they still exist.
+</para>
+<para>
+Some spamming sites send out a complete set of SMTP commands without waiting
+for any response. Exim protects against this by rejecting a message if the
+client has sent further input when it should not have. The error response <quote>554
+SMTP synchronization error</quote> is sent, and the connection is dropped. Testing
+for this error cannot be perfect because of transmission delays (unexpected
+input may be on its way but not yet received when Exim checks). However, it
+does detect many instances.
+</para>
+<para>
+The check can be globally disabled by setting <option>smtp_enforce_sync</option> false.
+If you want to disable the check selectively (for example, only for certain
+hosts), you can do so by an appropriate use of a <option>control</option> modifier in an ACL
+(see section <xref linkend="SECTcontrols"/>). See also <option>pipelining_advertise_hosts</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_etrn_command</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_etrn_command</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>ETRN</primary>
+<secondary>command to be run</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>ETRN</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+If this option is set, the given command is run whenever an SMTP ETRN
+command is received from a host that is permitted to issue such commands (see
+chapter <xref linkend="CHAPACL"/>). The string is split up into separate arguments which
+are independently expanded. The expansion variable <varname>$domain</varname> is set to the
+argument of the ETRN command, and no syntax checking is done on it. For
+example:
+</para>
+<literallayout class="monospaced">
+smtp_etrn_command = /etc/etrn_command $domain \
+ $sender_host_address
+</literallayout>
+<para revisionflag="changed">
+If the option is not set, the argument for the ETRN command must
+be a <emphasis>#</emphasis> followed by an address string.
+In this case an <emphasis>exim -R <string></emphasis> command is used;
+if the ETRN ACL has set up a named-queue then <emphasis>-MCG <queue></emphasis> is appended.
+</para>
+<para>
+A new process is created to run the command, but Exim does not wait for it to
+complete. Consequently, its status cannot be checked. If the command cannot be
+run, a line is written to the panic log, but the ETRN caller still receives
+a 250 success response. Exim is normally running under its own uid when
+receiving SMTP, so it is not possible for it to change the uid before running
+the command.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_etrn_serialize</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_etrn_serialize</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>ETRN</primary>
+<secondary>serializing</secondary>
+</indexterm>
+When this option is set, it prevents the simultaneous execution of more than
+one identical command as a result of ETRN in an SMTP connection. See
+section <xref linkend="SECTETRN"/> for details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_load_reserve</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_load_reserve</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>fixed-point</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>load average</primary>
+</indexterm>
+If the system load average ever gets higher than this, incoming SMTP calls are
+accepted only from those hosts that match an entry in <option>smtp_reserve_hosts</option>.
+If <option>smtp_reserve_hosts</option> is not set, no incoming SMTP calls are accepted when
+the load is over the limit. The option has no effect on ancient operating
+systems on which Exim cannot determine the load average. See also
+<option>deliver_queue_load_max</option> and <option>queue_only_load</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_max_synprot_errors</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_max_synprot_errors</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>3</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>limiting syntax and protocol errors</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>SMTP syntax and protocol errors</secondary>
+</indexterm>
+Exim rejects SMTP commands that contain syntax or protocol errors. In
+particular, a syntactically invalid email address, as in this command:
+</para>
+<literallayout class="monospaced">
+RCPT TO:<abc xyz@a.b.c>
+</literallayout>
+<para>
+causes immediate rejection of the command, before any other tests are done.
+(The ACL cannot be run if there is no valid address to set up for it.) An
+example of a protocol error is receiving RCPT before MAIL. If there are
+too many syntax or protocol errors in one SMTP session, the connection is
+dropped. The limit is set by this option.
+</para>
+<para>
+<indexterm role="concept">
+<primary>PIPELINING</primary>
+<secondary>expected errors</secondary>
+</indexterm>
+When the PIPELINING extension to SMTP is in use, some protocol errors are
+<quote>expected</quote>, for instance, a RCPT command after a rejected MAIL command.
+Exim assumes that PIPELINING will be used if it advertises it (see
+<option>pipelining_advertise_hosts</option>), and in this situation, <quote>expected</quote> errors do
+not count towards the limit.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_max_unknown_commands</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_max_unknown_commands</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>3</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>limiting unknown commands</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>unknown SMTP commands</secondary>
+</indexterm>
+If there are too many unrecognized commands in an incoming SMTP session, an
+Exim server drops the connection. This is a defence against some kinds of abuse
+that subvert web
+clients
+into making connections to SMTP ports; in these circumstances, a number of
+non-SMTP command lines are sent first.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_ratelimit_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_ratelimit_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>rate limiting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>rate of message arrival</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>RCPT</primary>
+<secondary>rate limiting</secondary>
+</indexterm>
+Some sites find it helpful to be able to limit the rate at which certain hosts
+can send them messages, and the rate at which an individual message can specify
+recipients.
+</para>
+<para>
+Exim has two rate-limiting facilities. This section describes the older
+facility, which can limit rates within a single connection. The newer
+<option>ratelimit</option> ACL condition can limit rates across all connections. See section
+<xref linkend="SECTratelimiting"/> for details of the newer facility.
+</para>
+<para>
+When a host matches <option>smtp_ratelimit_hosts</option>, the values of
+<option>smtp_ratelimit_mail</option> and <option>smtp_ratelimit_rcpt</option> are used to control the
+rate of acceptance of MAIL and RCPT commands in a single SMTP session,
+respectively. Each option, if set, must contain a set of four comma-separated
+values:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+A threshold, before which there is no rate limiting.
+</para>
+</listitem>
+<listitem>
+<para>
+An initial time delay. Unlike other times in Exim, numbers with decimal
+fractional parts are allowed here.
+</para>
+</listitem>
+<listitem>
+<para>
+A factor by which to increase the delay each time.
+</para>
+</listitem>
+<listitem>
+<para>
+A maximum value for the delay. This should normally be less than 5 minutes,
+because after that time, the client is liable to timeout the SMTP command.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+For example, these settings have been used successfully at the site which
+first suggested this feature, for controlling mail from their customers:
+</para>
+<literallayout class="monospaced">
+smtp_ratelimit_mail = 2,0.5s,1.05,4m
+smtp_ratelimit_rcpt = 4,0.25s,1.015,4m
+</literallayout>
+<para>
+The first setting specifies delays that are applied to MAIL commands after
+two have been received over a single connection. The initial delay is 0.5
+seconds, increasing by a factor of 1.05 each time. The second setting applies
+delays to RCPT commands when more than four occur in a single message.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_ratelimit_mail</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_ratelimit_mail</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>smtp_ratelimit_hosts</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_ratelimit_rcpt</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_ratelimit_rcpt</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>smtp_ratelimit_hosts</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_receive_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_receive_timeout</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>5m</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>for SMTP input</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>input timeout</secondary>
+</indexterm>
+This sets a timeout value for SMTP reception. It applies to all forms of SMTP
+input, including batch SMTP. If a line of input (either an SMTP command or a
+data line) is not received within this time, the SMTP connection is dropped and
+the message is abandoned.
+A line is written to the log containing one of the following messages:
+</para>
+<literallayout class="monospaced">
+SMTP command timeout on connection from...
+SMTP data timeout on connection from...
+</literallayout>
+<para>
+The former means that Exim was expecting to read an SMTP command; the latter
+means that it was in the DATA phase, reading the contents of a message.
+</para>
+<para>
+If the first character of the option is a <quote>$</quote> the option is
+expanded before use and may depend on
+<varname>$sender_host_name</varname>, <varname>$sender_host_address</varname> and <varname>$sender_host_port</varname>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>-os</option></primary>
+</indexterm>
+The value set by this option can be overridden by the
+<option>-os</option> command-line option. A setting of zero time disables the timeout, but
+this should never be used for SMTP over TCP/IP. (It can be useful in some cases
+of local input using <option>-bs</option> or <option>-bS</option>.) For non-SMTP input, the reception
+timeout is controlled by <option>receive_timeout</option> and <option>-or</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_reserve_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_reserve_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option defines hosts for which SMTP connections are reserved; see
+<option>smtp_accept_reserve</option> and <option>smtp_load_reserve</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_return_error_details</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtp_return_error_details</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>details policy failures</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>policy control</primary>
+<secondary>rejection, returning details</secondary>
+</indexterm>
+In the default state, Exim uses bland messages such as
+<quote>Administrative prohibition</quote> when it rejects SMTP commands for policy
+reasons. Many sysadmins like this because it gives away little information
+to spammers. However, some other sysadmins who are applying strict checking
+policies want to give out much fuller information about failures. Setting
+<option>smtp_return_error_details</option> true causes Exim to be more forthcoming. For
+example, instead of <quote>Administrative prohibition</quote>, it might give:
+</para>
+<literallayout class="monospaced">
+550-Rejected after DATA: '>' missing at end of address:
+550 failing address in "From" header is: <user@dom.ain
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>smtputf8_advertise_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>smtputf8_advertise_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SMTPUTF8</primary>
+<secondary>ESMTP extension, advertising</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>SMTPUTF8</secondary>
+</indexterm>
+When Exim is built with support for internationalised mail names,
+the availability thereof is advertised in
+response to EHLO only to those client hosts that match this option. See
+chapter <xref linkend="CHAPi18n"/> for details of Exim’s support for internationalisation.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>spamd_address</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>spamd_address</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>127.0.0.1 783</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option is available when Exim is compiled with the content-scanning
+extension. It specifies how Exim connects to SpamAssassin’s <option>spamd</option> daemon.
+See section <xref linkend="SECTscanspamass"/> for more details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>spf_guess</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>spf_guess</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>v=spf1 a/24 mx/24 ptr ?all</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option is available when Exim is compiled with SPF support.
+See section <xref linkend="SECSPF"/> for more details.
+</para>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>spf_smtp_comment_template</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all" revisionflag="changed">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>spf_smtp_comment_template</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>Please%_see%_http://www.open-spf.org/Why</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para revisionflag="changed">
+This option is available when Exim is compiled with SPF support. It
+allows the customisation of the SMTP comment that the SPF library
+generates. You are strongly encouraged to link to your own explanative
+site. The template must not contain spaces. If you need spaces in the
+output, use the proper placeholder. If libspf2 can not parse the
+template, it uses a built-in default broken link. The following placeholders
+(along with Exim variables (but see below)) are allowed in the template:
+</para>
+<itemizedlist revisionflag="changed">
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">%_</emphasis>: A space.
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">%{L}</emphasis>: Envelope sender’s local part.
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">%{S}</emphasis>: Envelope sender.
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">%{O}</emphasis>: Envelope sender’s domain.
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">%{D}</emphasis>: Current(?) domain.
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">%{I}</emphasis>: SMTP client Ip.
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">%{C}</emphasis>: SMTP client pretty IP.
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">%{T}</emphasis>: Epoch time (UTC).
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">%{P}</emphasis>: SMTP client domain name.
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">%{V}</emphasis>: IP version.
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">%{H}</emphasis>: EHLO/HELO domain.
+</para>
+</listitem>
+<listitem>
+<para revisionflag="changed">
+<emphasis role="bold">%{R}</emphasis>: Receiving domain.
+</para>
+</listitem>
+</itemizedlist>
+<para revisionflag="changed">
+The capitalized placeholders do proper URL encoding, if you use them
+lowercased, no encoding takes place. This list was compiled from the
+libspf2 sources.
+</para>
+<para revisionflag="changed">
+A note on using Exim variables: As
+currently the SPF library is initialized before the SMTP EHLO phase,
+the variables useful for expansion are quite limited.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>split_spool_directory</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>split_spool_directory</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>multiple spool directories</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>spool directory</primary>
+<secondary>split</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>directories, multiple</primary>
+</indexterm>
+If this option is set, it causes Exim to split its input directory into 62
+subdirectories, each with a single alphanumeric character as its name. The
+sixth character of the message id is used to allocate messages to
+subdirectories; this is the least significant base-62 digit of the time of
+arrival of the message.
+</para>
+<para>
+Splitting up the spool in this way may provide better performance on systems
+where there are long mail queues, by reducing the number of files in any one
+directory. The msglog directory is also split up in a similar way to the input
+directory; however, if <option>preserve_message_logs</option> is set, all old msglog files
+are still placed in the single directory <filename>msglog.OLD</filename>.
+</para>
+<para>
+It is not necessary to take any special action for existing messages when
+changing <option>split_spool_directory</option>. Exim notices messages that are in the
+<quote>wrong</quote> place, and continues to process them. If the option is turned off
+after a period of being on, the subdirectories will eventually empty and be
+automatically deleted.
+</para>
+<para>
+When <option>split_spool_directory</option> is set, the behaviour of queue runner processes
+changes. Instead of creating a list of all messages in the queue, and then
+trying to deliver each one, in turn, it constructs a list of those in one
+sub-directory and tries to deliver them, before moving on to the next
+sub-directory. The sub-directories are processed in a random order. This
+spreads out the scanning of the input directories, and uses less memory. It is
+particularly beneficial when there are lots of messages in the queue. However,
+if <option>queue_run_in_order</option> is set, none of this new processing happens. The
+entire queue has to be scanned and sorted before any deliveries can start.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>spool_directory</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>spool_directory</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>set at compile time</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>spool directory</primary>
+<secondary>path to</secondary>
+</indexterm>
+This defines the directory in which Exim keeps its spool, that is, the messages
+it is waiting to deliver. The default value is taken from the compile-time
+configuration setting, if there is one. If not, this option must be set. The
+string is expanded, so it can contain, for example, a reference to
+<varname>$primary_hostname</varname>.
+</para>
+<para>
+If the spool directory name is fixed on your installation, it is recommended
+that you set it at build time rather than from this option, particularly if the
+log files are being written to the spool directory (see <option>log_file_path</option>).
+Otherwise log files cannot be used for errors that are detected early on, such
+as failures in the configuration file.
+</para>
+<para>
+By using this option to override the compiled-in path, it is possible to run
+tests of Exim without using the standard spool.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>spool_wireformat</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>spool_wireformat</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>spool directory</primary>
+<secondary>file formats</secondary>
+</indexterm>
+If this option is set, Exim may for some messages use an alternative format
+for data-files in the spool which matches the wire format.
+Doing this permits more efficient message reception and transmission.
+Currently it is only done for messages received using the ESMTP CHUNKING
+option.
+</para>
+<para>
+The following variables will not have useful values:
+</para>
+<literallayout class="monospaced">
+$max_received_linelength
+$body_linecount
+$body_zerocount
+</literallayout>
+<para>
+Users of the local_scan() API (see <xref linkend="CHAPlocalscan"/>),
+and any external programs which are passed a reference to a message data file
+(except via the <quote>regex</quote>, <quote>malware</quote> or <quote>spam</quote>) ACL conditions)
+will need to be aware of the different formats potentially available.
+</para>
+<para>
+Using any of the ACL conditions noted will negate the reception benefit
+(as a Unix-mbox-format file is constructed for them).
+The transmission benefit is maintained.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>sqlite_lock_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>sqlite_lock_timeout</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>5s</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>sqlite lookup type</primary>
+<secondary>lock timeout</secondary>
+</indexterm>
+This option controls the timeout that the <command>sqlite</command> lookup uses when trying to
+access an SQLite database. See section <xref linkend="SECTsqlite"/> for more details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>strict_acl_vars</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>strict_acl_vars</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>variables, handling unset</secondary>
+</indexterm>
+This option controls what happens if a syntactically valid but undefined ACL
+variable is referenced. If it is false (the default), an empty string
+is substituted; if it is true, an error is generated. See section
+<xref linkend="SECTaclvariables"/> for details of ACL variables.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>strip_excess_angle_brackets</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>strip_excess_angle_brackets</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>angle brackets, excess</primary>
+</indexterm>
+If this option is set, redundant pairs of angle brackets round <quote>route-addr</quote>
+items in addresses are stripped. For example, <emphasis><<xxx@a.b.c.d>></emphasis> is
+treated as <emphasis><xxx@a.b.c.d></emphasis>. If this is in the envelope and the message is
+passed on to another MTA, the excess angle brackets are not passed on. If this
+option is not set, multiple pairs of angle brackets cause a syntax error.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>strip_trailing_dot</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>strip_trailing_dot</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>trailing dot on domain</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>dot</primary>
+<secondary>trailing on domain</secondary>
+</indexterm>
+If this option is set, a trailing dot at the end of a domain in an address is
+ignored. If this is in the envelope and the message is passed on to another
+MTA, the dot is not passed on. If this option is not set, a dot at the end of a
+domain causes a syntax error.
+However, addresses in header lines are checked only when an ACL requests header
+syntax checking.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>syslog_duplication</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>syslog_duplication</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>syslog</primary>
+<secondary>duplicate log lines; suppressing</secondary>
+</indexterm>
+When Exim is logging to syslog, it writes the log lines for its three
+separate logs at different syslog priorities so that they can in principle
+be separated on the logging hosts. Some installations do not require this
+separation, and in those cases, the duplication of certain log lines is a
+nuisance. If <option>syslog_duplication</option> is set false, only one copy of any
+particular log line is written to syslog. For lines that normally go to
+both the main log and the reject log, the reject log version (possibly
+containing message header lines) is written, at LOG_NOTICE priority.
+Lines that normally go to both the main and the panic log are written at
+the LOG_ALERT priority.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>syslog_facility</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>syslog_facility</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>syslog</primary>
+<secondary>facility; setting</secondary>
+</indexterm>
+This option sets the syslog <quote>facility</quote> name, used when Exim is logging to
+syslog. The value must be one of the strings <quote>mail</quote>, <quote>user</quote>, <quote>news</quote>,
+<quote>uucp</quote>, <quote>daemon</quote>, or <quote>local<emphasis>x</emphasis></quote> where <emphasis>x</emphasis> is a digit between 0 and 7.
+If this option is unset, <quote>mail</quote> is used. See chapter <xref linkend="CHAPlog"/> for
+details of Exim’s logging.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>syslog_pid</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>syslog_pid</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>syslog</primary>
+<secondary>pid</secondary>
+</indexterm>
+If <option>syslog_pid</option> is set false, the PID on Exim’s log lines are
+omitted when these lines are sent to syslog. (Syslog normally prefixes
+the log lines with the PID of the logging process automatically.) You need
+to enable the <literal>+pid</literal> log selector item, if you want Exim to write it’s PID
+into the logs.) See chapter <xref linkend="CHAPlog"/> for details of Exim’s logging.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>syslog_processname</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>syslog_processname</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis><literal>exim</literal></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>syslog</primary>
+<secondary>process name; setting</secondary>
+</indexterm>
+This option sets the syslog <quote>ident</quote> name, used when Exim is logging to
+syslog. The value must be no longer than 32 characters. See chapter
+<xref linkend="CHAPlog"/> for details of Exim’s logging.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>syslog_timestamp</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>syslog_timestamp</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>syslog</primary>
+<secondary>timestamps</secondary>
+</indexterm>
+If <option>syslog_timestamp</option> is set false, the timestamps on Exim’s log lines are
+omitted when these lines are sent to syslog. See chapter <xref linkend="CHAPlog"/> for
+details of Exim’s logging.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>system_filter</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>system_filter</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>system filter</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>system filter</primary>
+<secondary>specifying</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary>not available for system filter</secondary>
+</indexterm>
+This option specifies an Exim filter file that is applied to all messages at
+the start of each delivery attempt, before any routing is done. System filters
+must be Exim filters; they cannot be Sieve filters. If the system filter
+generates any deliveries to files or pipes, or any new mail messages, the
+appropriate <option>system_filter_..._transport</option> option(s) must be set, to define
+which transports are to be used. Details of this facility are given in chapter
+<xref linkend="CHAPsystemfilter"/>.
+A forced expansion failure results in no filter operation.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>system_filter_directory_transport</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>system_filter_directory_transport</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="variable">
+<primary><varname>$address_file</varname></primary>
+</indexterm>
+This sets the name of the transport driver that is to be used when the
+<option>save</option> command in a system message filter specifies a path ending in <quote>/</quote>,
+implying delivery of each message into a separate file in some directory.
+During the delivery, the variable <varname>$address_file</varname> contains the path name.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>system_filter_file_transport</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>system_filter_file_transport</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>transport for system filter</secondary>
+</indexterm>
+This sets the name of the transport driver that is to be used when the <option>save</option>
+command in a system message filter specifies a path not ending in <quote>/</quote>. During
+the delivery, the variable <varname>$address_file</varname> contains the path name.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>system_filter_group</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>system_filter_group</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>gid (group id)</primary>
+<secondary>system filter</secondary>
+</indexterm>
+This option is used only when <option>system_filter_user</option> is also set. It sets the
+gid under which the system filter is run, overriding any gid that is associated
+with the user. The value may be numerical or symbolic.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>system_filter_pipe_transport</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>system_filter_pipe_transport</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><command>pipe</command> transport</primary>
+<secondary>for system filter</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$address_pipe</varname></primary>
+</indexterm>
+This specifies the transport driver that is to be used when a <option>pipe</option> command
+is used in a system filter. During the delivery, the variable <varname>$address_pipe</varname>
+contains the pipe command.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>system_filter_reply_transport</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>system_filter_reply_transport</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><command>autoreply</command> transport</primary>
+<secondary>for system filter</secondary>
+</indexterm>
+This specifies the transport driver that is to be used when a <option>mail</option> command
+is used in a system filter.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>system_filter_user</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>system_filter_user</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>uid (user id)</primary>
+<secondary>system filter</secondary>
+</indexterm>
+If this option is set to root, the system filter is run in the main Exim
+delivery process, as root. Otherwise, the system filter runs in a separate
+process, as the given user, defaulting to the Exim run-time user.
+Unless the string consists entirely of digits, it
+is looked up in the password data. Failure to find the named user causes a
+configuration error. The gid is either taken from the password data, or
+specified by <option>system_filter_group</option>. When the uid is specified numerically,
+<option>system_filter_group</option> is required to be set.
+</para>
+<para>
+If the system filter generates any pipe, file, or reply deliveries, the uid
+under which the filter is run is used when transporting them, unless a
+transport option overrides.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tcp_nodelay</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tcp_nodelay</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>daemon</primary>
+<secondary>TCP_NODELAY on sockets</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Nagle algorithm</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP_NODELAY on listening sockets</primary>
+</indexterm>
+If this option is set false, it stops the Exim daemon setting the
+TCP_NODELAY option on its listening sockets. Setting TCP_NODELAY
+turns off the <quote>Nagle algorithm</quote>, which is a way of improving network
+performance in interactive (character-by-character) situations. Turning it off
+should improve Exim’s performance a bit, so that is what happens by default.
+However, it appears that some broken clients cannot cope, and time out. Hence
+this option. It affects only those sockets that are set up for listening by the
+daemon. Sockets created by the smtp transport for delivering mail always set
+TCP_NODELAY.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>timeout_frozen_after</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>timeout_frozen_after</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>0s</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>timing out</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>frozen messages</secondary>
+</indexterm>
+If <option>timeout_frozen_after</option> is set to a time greater than zero, a frozen
+message of any kind that has been in the queue for longer than the given time
+is automatically cancelled at the next queue run. If the frozen message is a
+bounce message, it is just discarded; otherwise, a bounce is sent to the
+sender, in a similar manner to cancellation by the <option>-Mg</option> command line option.
+If you want to timeout frozen bounce messages earlier than other kinds of
+frozen message, see <option>ignore_bounce_errors_after</option>.
+</para>
+<para>
+<emphasis role="bold">Note:</emphasis> the default value of zero means no timeouts; with this setting,
+frozen messages remain in the queue forever (except for any frozen bounce
+messages that are released by <option>ignore_bounce_errors_after</option>).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>timezone</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>timezone</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>timezone, setting</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>environment</primary>
+<secondary>values from</secondary>
+</indexterm>
+The value of <option>timezone</option> is used to set the environment variable TZ while
+running Exim (if it is different on entry). This ensures that all timestamps
+created by Exim are in the required timezone. If you want all your timestamps
+to be in UTC (aka GMT) you should set
+</para>
+<literallayout class="monospaced">
+timezone = UTC
+</literallayout>
+<para>
+The default value is taken from TIMEZONE_DEFAULT in <filename>Local/Makefile</filename>,
+or, if that is not set, from the value of the TZ environment variable when Exim
+is built. If <option>timezone</option> is set to the empty string, either at build or run
+time, any existing TZ variable is removed from the environment when Exim
+runs. This is appropriate behaviour for obtaining wall-clock time on some, but
+unfortunately not all, operating systems.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_advertise_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_advertise_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>advertising</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>encryption</primary>
+<secondary>on SMTP connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>encrypted connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>STARTTLS</secondary>
+</indexterm>
+When Exim is built with support for TLS encrypted connections, the availability
+of the STARTTLS command to set up an encrypted session is advertised in
+response to EHLO only to those client hosts that match this option. See
+chapter <xref linkend="CHAPTLS"/> for details of Exim’s support for TLS.
+Note that the default value requires that a certificate be supplied
+using the <option>tls_certificate</option> option. If TLS support for incoming connections
+is not required the <option>tls_advertise_hosts</option> option should be set empty.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>unset</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_certificate</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>list</emphasis>†<emphasis></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>server certificate; location of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>server, location of</secondary>
+</indexterm>
+The value of this option is expanded, and must then be a list of absolute paths to
+files which contain the server’s certificates (in PEM format).
+Commonly only one file is needed.
+The server’s private key is also
+assumed to be in this file if <option>tls_privatekey</option> is unset. See chapter
+<xref linkend="CHAPTLS"/> for further details.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: The certificates defined by this option are used only when Exim is
+receiving incoming messages as a server. If you want to supply certificates for
+use when sending messages as a client, you must set the <option>tls_certificate</option>
+option in the relevant <command>smtp</command> transport.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: If you use filenames based on IP addresses, change the list
+separator in the usual way (<xref linkend="SECTlistsepchange"/>) to avoid confusion under IPv6.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: Under versions of OpenSSL preceding 1.1.1,
+when a list of more than one
+file is used, the <varname>$tls_in_ourcert</varname> variable is unreliable.
+The macro "_TLS_BAD_MULTICERT_IN_OURCERT" will be defined for those versions.
+</para>
+<para>
+If the option contains <varname>$tls_out_sni</varname> and Exim is built against OpenSSL, then
+if the OpenSSL build supports TLS extensions and the TLS client sends the
+Server Name Indication extension, then this option and others documented in
+<xref linkend="SECTtlssni"/> will be re-expanded.
+</para>
+<para>
+If this option is unset or empty a fresh self-signed certificate will be
+generated for every connection.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_crl</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_crl</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>server certificate revocation list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>revocation list for server</secondary>
+</indexterm>
+This option specifies a certificate revocation list. The expanded value must
+be the name of a file that contains CRLs in PEM format.
+</para>
+<para>
+Under OpenSSL the option can specify a directory with CRL files.
+</para>
+<para>
+<emphasis role="bold">Note:</emphasis> Under OpenSSL the option must, if given, supply a CRL
+for each signing element of the certificate chain (i.e. all but the leaf).
+For the file variant this can be multiple PEM blocks in the one file.
+</para>
+<para>
+See <xref linkend="SECTtlssni"/> for discussion of when this option might be re-expanded.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_dh_max_bits</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_dh_max_bits</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>2236</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>D-H bit count</secondary>
+</indexterm>
+The number of bits used for Diffie-Hellman key-exchange may be suggested by
+the chosen TLS library. That value might prove to be too high for
+interoperability. This option provides a maximum clamp on the value
+suggested, trading off security for interoperability.
+</para>
+<para>
+The value must be at least 1024.
+</para>
+<para>
+The value 2236 was chosen because, at time of adding the option, it was the
+hard-coded maximum value supported by the NSS cryptographic library, as used
+by Thunderbird, while GnuTLS was suggesting 2432 bits as normal.
+</para>
+<para>
+If you prefer more security and are willing to break some clients, raise this
+number.
+</para>
+<para>
+Note that the value passed to GnuTLS for *generating* a new prime may be a
+little less than this figure, because GnuTLS is inexact and may produce a
+larger prime than requested.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_dhparam</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_dhparam</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>D-H parameters for server</secondary>
+</indexterm>
+The value of this option is expanded and indicates the source of DH parameters
+to be used by Exim.
+</para>
+<para>
+This option is ignored for GnuTLS version 3.6.0 and later.
+The library manages parameter negotiation internally.
+</para>
+<para>
+<emphasis role="bold">Note: The Exim Maintainers strongly recommend,
+for other TLS library versions,
+using a filename with site-generated
+local DH parameters</emphasis>, which has been supported across all versions of Exim. The
+other specific constants available are a fallback so that even when
+"unconfigured", Exim can offer Perfect Forward Secrecy in older ciphersuites in TLS.
+</para>
+<para>
+If <option>tls_dhparam</option> is a filename starting with a <literal>/</literal>,
+then it names a file from which DH
+parameters should be loaded. If the file exists, it should hold a PEM-encoded
+PKCS#3 representation of the DH prime. If the file does not exist, for
+OpenSSL it is an error. For GnuTLS, Exim will attempt to create the file and
+fill it with a generated DH prime. For OpenSSL, if the DH bit-count from
+loading the file is greater than <option>tls_dh_max_bits</option> then it will be ignored,
+and treated as though the <option>tls_dhparam</option> were set to "none".
+</para>
+<para>
+If this option expands to the string "none", then no DH parameters will be
+loaded by Exim.
+</para>
+<para>
+If this option expands to the string "historic" and Exim is using GnuTLS, then
+Exim will attempt to load a file from inside the spool directory. If the file
+does not exist, Exim will attempt to create it.
+See section <xref linkend="SECTgnutlsparam"/> for further details.
+</para>
+<para>
+If Exim is using OpenSSL and this option is empty or unset, then Exim will load
+a default DH prime; the default is Exim-specific but lacks verifiable provenance.
+</para>
+<para>
+In older versions of Exim the default was the 2048 bit prime described in section
+2.2 of RFC 5114, "2048-bit MODP Group with 224-bit Prime Order Subgroup", which
+in IKE is assigned number 23.
+</para>
+<para>
+Otherwise, the option must expand to the name used by Exim for any of a number
+of DH primes specified in RFC 2409, RFC 3526, RFC 5114, RFC 7919, or from other
+sources. As names, Exim uses a standard specified name, else "ike" followed by
+the number used by IKE, or "default" which corresponds to
+<literal>exim.dev.20160529.3</literal>.
+</para>
+<para>
+The available standard primes are:
+<literal>ffdhe2048</literal>, <literal>ffdhe3072</literal>, <literal>ffdhe4096</literal>, <literal>ffdhe6144</literal>, <literal>ffdhe8192</literal>,
+<literal>ike1</literal>, <literal>ike2</literal>, <literal>ike5</literal>,
+<literal>ike14</literal>, <literal>ike15</literal>, <literal>ike16</literal>, <literal>ike17</literal>, <literal>ike18</literal>,
+<literal>ike22</literal>, <literal>ike23</literal> and <literal>ike24</literal>.
+</para>
+<para>
+The available additional primes are:
+<literal>exim.dev.20160529.1</literal>, <literal>exim.dev.20160529.2</literal> and <literal>exim.dev.20160529.3</literal>.
+</para>
+<para>
+Some of these will be too small to be accepted by clients.
+Some may be too large to be accepted by clients.
+The open cryptographic community has suspicions about the integrity of some
+of the later IKE values, which led into RFC7919 providing new fixed constants
+(the "ffdhe" identifiers).
+</para>
+<para>
+At this point, all of the "ike" values should be considered obsolete;
+they’re still in Exim to avoid breaking unusual configurations, but are
+candidates for removal the next time we have backwards-incompatible changes.
+</para>
+<para>
+The TLS protocol does not negotiate an acceptable size for this; clients tend
+to hard-drop connections if what is offered by the server is unacceptable,
+whether too large or too small, and there’s no provision for the client to
+tell the server what these constraints are. Thus, as a server operator, you
+need to make an educated guess as to what is most likely to work for your
+userbase.
+</para>
+<para>
+Some known size constraints suggest that a bit-size in the range 2048 to 2236
+is most likely to maximise interoperability. The upper bound comes from
+applications using the Mozilla Network Security Services (NSS) library, which
+used to set its <literal>DH_MAX_P_BITS</literal> upper-bound to 2236. This affects many
+mail user agents (MUAs). The lower bound comes from Debian installs of Exim4
+prior to the 4.80 release, as Debian used to patch Exim to raise the minimum
+acceptable bound from 1024 to 2048.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_eccurve</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_eccurve</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis><literal>auto</literal></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>EC cryptography</secondary>
+</indexterm>
+This option selects a EC curve for use by Exim when used with OpenSSL.
+It has no effect when Exim is used with GnuTLS.
+</para>
+<para>
+After expansion it must contain a valid EC curve parameter, such as
+<literal>prime256v1</literal>, <literal>secp384r1</literal>, or <literal>P-512</literal>. Consult your OpenSSL manual
+for valid selections.
+</para>
+<para>
+For OpenSSL versions before (and not including) 1.0.2, the string
+<literal>auto</literal> selects <literal>prime256v1</literal>. For more recent OpenSSL versions
+<literal>auto</literal> tells the library to choose.
+</para>
+<para>
+If the option expands to an empty string, no EC curves will be enabled.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_ocsp_file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_ocsp_file</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>certificate status</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>OCSP proof file</secondary>
+</indexterm>
+This option
+must if set expand to the absolute path to a file which contains a current
+status proof for the server’s certificate, as obtained from the
+Certificate Authority.
+</para>
+<para>
+Usable for GnuTLS 3.4.4 or 3.3.17 or OpenSSL 1.1.0 (or later).
+The macro "_HAVE_TLS_OCSP" will be defined for those versions.
+</para>
+<para>
+For OpenSSL 1.1.0 or later, and
+for GnuTLS 3.5.6 or later the expanded value of this option can be a list
+of files, to match a list given for the <option>tls_certificate</option> option.
+The ordering of the two lists must match.
+The macro "_HAVE_TLS_OCSP_LIST" will be defined for those versions.
+</para>
+<para>
+The file(s) should be in DER format,
+except for GnuTLS 3.6.3 or later
+or for OpenSSL,
+when an optional filetype prefix can be used.
+The prefix must be one of "DER" or "PEM", followed by
+a single space. If one is used it sets the format for subsequent
+files in the list; the initial format is DER.
+If multiple proofs are wanted, for multiple chain elements
+(this only works under TLS1.3)
+they must be coded as a combined OCSP response.
+</para>
+<para>
+Although GnuTLS will accept PEM files with multiple separate
+PEM blobs (ie. separate OCSP responses), it sends them in the
+TLS Certificate record interleaved with the certificates of the chain;
+although a GnuTLS client is happy with that, an OpenSSL client is not.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_on_connect_ports</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_on_connect_ports</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SSMTP</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTPS</primary>
+</indexterm>
+This option specifies a list of incoming SSMTP (aka SMTPS) ports that should
+operate the SSMTP (SMTPS) protocol, where a TLS session is immediately
+set up without waiting for the client to issue a STARTTLS command. For
+further details, see section <xref linkend="SECTsupobssmt"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>unset</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_privatekey</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>list</emphasis>†<emphasis></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>server private key; location of</secondary>
+</indexterm>
+The value of this option is expanded, and must then be a list of absolute paths to
+files which contains the server’s private keys.
+If this option is unset, or if
+the expansion is forced to fail, or the result is an empty string, the private
+key is assumed to be in the same file as the server’s certificates. See chapter
+<xref linkend="CHAPTLS"/> for further details.
+</para>
+<para>
+See <xref linkend="SECTtlssni"/> for discussion of when this option might be re-expanded.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_remember_esmtp</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_remember_esmtp</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>esmtp state; remembering</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>broken clients</secondary>
+</indexterm>
+If this option is set true, Exim violates the RFCs by remembering that it is in
+<quote>esmtp</quote> state after successfully negotiating a TLS session. This provides
+support for broken clients that fail to send a new EHLO after starting a
+TLS session.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_require_ciphers</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_require_ciphers</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>requiring specific ciphers</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>cipher</primary>
+<secondary>requiring specific</secondary>
+</indexterm>
+This option controls which ciphers can be used for incoming TLS connections.
+The <command>smtp</command> transport has an option of the same name for controlling outgoing
+connections. This option is expanded for each connection, so can be varied for
+different clients if required. The value of this option must be a list of
+permitted cipher suites. The OpenSSL and GnuTLS libraries handle cipher control
+in somewhat different ways. If GnuTLS is being used, the client controls the
+preference order of the available ciphers. Details are given in sections
+<xref linkend="SECTreqciphssl"/> and <xref linkend="SECTreqciphgnu"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_try_verify_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_try_verify_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>client certificate verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>verification of client</secondary>
+</indexterm>
+See <option>tls_verify_hosts</option> below.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_verify_certificates</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_verify_certificates</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>system</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>client certificate verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>verification of client</secondary>
+</indexterm>
+The value of this option is expanded, and must then be either the
+word "system"
+or the absolute path to
+a file or directory containing permitted certificates for clients that
+match <option>tls_verify_hosts</option> or <option>tls_try_verify_hosts</option>.
+</para>
+<para>
+The "system" value for the option will use a
+system default location compiled into the SSL library.
+This is not available for GnuTLS versions preceding 3.0.20,
+and will be taken as empty; an explicit location
+must be specified.
+</para>
+<para>
+The use of a directory for the option value is not available for GnuTLS versions
+preceding 3.3.6 and a single file must be used.
+</para>
+<para>
+With OpenSSL the certificates specified
+explicitly
+either by file or directory
+are added to those given by the system default location.
+</para>
+<para>
+These certificates should be for the certificate authorities trusted, rather
+than the public cert of individual clients. With both OpenSSL and GnuTLS, if
+the value is a file then the certificates are sent by Exim as a server to
+connecting clients, defining the list of accepted certificate authorities.
+Thus the values defined should be considered public data. To avoid this,
+use the explicit directory version.
+</para>
+<para>
+See <xref linkend="SECTtlssni"/> for discussion of when this option might be re-expanded.
+</para>
+<para>
+A forced expansion failure or setting to an empty string is equivalent to
+being unset.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_verify_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_verify_hosts</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>client certificate verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>verification of client</secondary>
+</indexterm>
+This option, along with <option>tls_try_verify_hosts</option>, controls the checking of
+certificates from clients. The expected certificates are defined by
+<option>tls_verify_certificates</option>, which must be set. A configuration error occurs if
+either <option>tls_verify_hosts</option> or <option>tls_try_verify_hosts</option> is set and
+<option>tls_verify_certificates</option> is not set.
+</para>
+<para>
+Any client that matches <option>tls_verify_hosts</option> is constrained by
+<option>tls_verify_certificates</option>. When the client initiates a TLS session, it must
+present one of the listed certificates. If it does not, the connection is
+aborted. <emphasis role="bold">Warning</emphasis>: Including a host in <option>tls_verify_hosts</option> does not require
+the host to use TLS. It can still send SMTP commands through unencrypted
+connections. Forcing a client to use TLS has to be done separately using an
+ACL to reject inappropriate commands when the connection is not encrypted.
+</para>
+<para>
+A weaker form of checking is provided by <option>tls_try_verify_hosts</option>. If a client
+matches this option (but not <option>tls_verify_hosts</option>), Exim requests a
+certificate and checks it against <option>tls_verify_certificates</option>, but does not
+abort the connection if there is no certificate or if it does not match. This
+state can be detected in an ACL, which makes it possible to implement policies
+such as <quote>accept for relay only if a verified certificate has been received,
+but accept for local delivery if encrypted, even without a verified
+certificate</quote>.
+</para>
+<para>
+Client hosts that match neither of these lists are not asked to present
+certificates.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>trusted_groups</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>trusted_groups</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>trusted groups</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>groups</primary>
+<secondary>trusted</secondary>
+</indexterm>
+This option is expanded just once, at the start of Exim’s processing. If this
+option is set, any process that is running in one of the listed groups, or
+which has one of them as a supplementary group, is trusted. The groups can be
+specified numerically or by name. See section <xref linkend="SECTtrustedadmin"/> for
+details of what trusted callers are permitted to do. If neither
+<option>trusted_groups</option> nor <option>trusted_users</option> is set, only root and the Exim user
+are trusted.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>trusted_users</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>trusted_users</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>trusted users</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>user</primary>
+<secondary>trusted</secondary>
+</indexterm>
+This option is expanded just once, at the start of Exim’s processing. If this
+option is set, any process that is running as one of the listed users is
+trusted. The users can be specified numerically or by name. See section
+<xref linkend="SECTtrustedadmin"/> for details of what trusted callers are permitted to do.
+If neither <option>trusted_groups</option> nor <option>trusted_users</option> is set, only root and the
+Exim user are trusted.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>unknown_login</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>unknown_login</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>uid (user id)</primary>
+<secondary>unknown caller</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$caller_uid</varname></primary>
+</indexterm>
+This is a specialized feature for use in unusual configurations. By default, if
+the uid of the caller of Exim cannot be looked up using <function>getpwuid()</function>, Exim
+gives up. The <option>unknown_login</option> option can be used to set a login name to be
+used in this circumstance. It is expanded, so values like <option>user$caller_uid</option>
+can be set. When <option>unknown_login</option> is used, the value of <option>unknown_username</option>
+is used for the user’s real name (gecos field), unless this has been set by the
+<option>-F</option> option.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>unknown_username</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>unknown_username</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>unknown_login</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>untrusted_set_sender</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>untrusted_set_sender</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>address list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>trusted users</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>setting by untrusted user</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>untrusted user setting sender</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>user</primary>
+<secondary>untrusted setting sender</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope from</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope sender</primary>
+</indexterm>
+When an untrusted user submits a message to Exim using the standard input, Exim
+normally creates an envelope sender address from the user’s login and the
+default qualification domain. Data from the <option>-f</option> option (for setting envelope
+senders on non-SMTP messages) or the SMTP MAIL command (if <option>-bs</option> or <option>-bS</option>
+is used) is ignored.
+</para>
+<para>
+However, untrusted users are permitted to set an empty envelope sender address,
+to declare that a message should never generate any bounces. For example:
+</para>
+<literallayout class="monospaced">
+exim -f '<>' user@domain.example
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_ident</varname></primary>
+</indexterm>
+The <option>untrusted_set_sender</option> option allows you to permit untrusted users to set
+other envelope sender addresses in a controlled way. When it is set, untrusted
+users are allowed to set envelope sender addresses that match any of the
+patterns in the list. Like all address lists, the string is expanded. The
+identity of the user is in <varname>$sender_ident</varname>, so you can, for example, restrict
+users to setting senders that start with their login ids
+followed by a hyphen
+by a setting like this:
+</para>
+<literallayout class="monospaced">
+untrusted_set_sender = ^$sender_ident-
+</literallayout>
+<para>
+If you want to allow untrusted users to set envelope sender addresses without
+restriction, you can use
+</para>
+<literallayout class="monospaced">
+untrusted_set_sender = *
+</literallayout>
+<para>
+The <option>untrusted_set_sender</option> option applies to all forms of local input, but
+only to the setting of the envelope sender. It does not permit untrusted users
+to use the other options which trusted user can use to override message
+parameters. Furthermore, it does not stop Exim from removing an existing
+<emphasis>Sender:</emphasis> header in the message, or from adding a <emphasis>Sender:</emphasis> header if
+necessary. See <option>local_sender_retain</option> and <option>local_from_check</option> for ways of
+overriding these actions. The handling of the <emphasis>Sender:</emphasis> header is also
+described in section <xref linkend="SECTthesenhea"/>.
+</para>
+<para>
+The log line for a message’s arrival shows the envelope sender following
+<quote><=</quote>. For local messages, the user’s login always follows, after <quote>U=</quote>. In
+<option>-bp</option> displays, and in the Exim monitor, if an untrusted user sets an
+envelope sender address, the user’s login is shown in parentheses after the
+sender address.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>uucp_from_pattern</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>uucp_from_pattern</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><quote>From</quote> line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>UUCP</primary>
+<secondary><quote>From</quote> line</secondary>
+</indexterm>
+Some applications that pass messages to an MTA via a command line interface use
+an initial line starting with <quote>From </quote> to pass the envelope sender. In
+particular, this is used by UUCP software. Exim recognizes such a line by means
+of a regular expression that is set in <option>uucp_from_pattern</option>. When the pattern
+matches, the sender address is constructed by expanding the contents of
+<option>uucp_from_sender</option>, provided that the caller of Exim is a trusted user. The
+default pattern recognizes lines in the following two forms:
+</para>
+<literallayout class="monospaced">
+From ph10 Fri Jan 5 12:35 GMT 1996
+From ph10 Fri, 7 Jan 97 14:00:00 GMT
+</literallayout>
+<para>
+The pattern can be seen by running
+</para>
+<literallayout class="monospaced">
+exim -bP uucp_from_pattern
+</literallayout>
+<para>
+It checks only up to the hours and minutes, and allows for a 2-digit or 4-digit
+year in the second case. The first word after <quote>From </quote> is matched in the
+regular expression by a parenthesized subpattern. The default value for
+<option>uucp_from_sender</option> is <quote>$1</quote>, which therefore just uses this first word
+(<quote>ph10</quote> in the example above) as the message’s sender. See also
+<option>ignore_fromline_hosts</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>uucp_from_sender</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>uucp_from_sender</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis><literal>$1</literal></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>uucp_from_pattern</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>warn_message_file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>warn_message_file</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>warning of delay</primary>
+<secondary>customizing the message</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>customizing</primary>
+<secondary>warning message</secondary>
+</indexterm>
+This option defines a template file containing paragraphs of text to be used
+for constructing the warning message which is sent by Exim when a message has
+been in the queue for a specified amount of time, as specified by
+<option>delay_warning</option>. Details of the file’s contents are given in chapter
+<xref linkend="CHAPemsgcust"/>.
+</para>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>warn_message_file</primary>
+<secondary>tainted data</secondary>
+</indexterm>
+The option is expanded to give the file path, which must be
+absolute and untainted.
+</para>
+<para>
+See also <option>bounce_message_file</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>write_rejectlog</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>write_rejectlog</option></entry>
+<entry>Use: <emphasis>main</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>reject log</primary>
+<secondary>disabling</secondary>
+</indexterm>
+If this option is set false, Exim no longer writes anything to the reject log.
+See chapter <xref linkend="CHAPlog"/> for details of what Exim writes to its logs.
+<indexterm role="concept" startref="IIDconfima" class="endofrange"/>
+<indexterm role="concept" startref="IIDmaiconf" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAProutergeneric">
+<title>Generic options for routers</title>
+<para>
+<indexterm role="concept" id="IIDgenoprou1" class="startofrange">
+<primary>options</primary>
+<secondary>generic; for routers</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDgenoprou2" class="startofrange">
+<primary>generic options</primary>
+<secondary>router</secondary>
+</indexterm>
+This chapter describes the generic options that apply to all routers.
+Those that are preconditions are marked with ‡ in the <quote>use</quote> field.
+</para>
+<para>
+For a general description of how a router operates, see sections
+<xref linkend="SECTrunindrou"/> and <xref linkend="SECTrouprecon"/>. The latter specifies the order in
+which the preconditions are tested. The order of expansion of the options that
+provide data for a transport is: <option>errors_to</option>, <option>headers_add</option>,
+<option>headers_remove</option>, <option>transport</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>address_data</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>address_data</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>data attached to address</secondary>
+</indexterm>
+The string is expanded just before the router is run, that is, after all the
+precondition tests have succeeded. If the expansion is forced to fail, the
+router declines, the value of <option>address_data</option> remains unchanged, and the
+<option>more</option> option controls what happens next. Other expansion failures cause
+delivery of the address to be deferred.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$address_data</varname></primary>
+</indexterm>
+When the expansion succeeds, the value is retained with the address, and can be
+accessed using the variable <varname>$address_data</varname> in the current router, subsequent
+routers, and the eventual transport.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: If the current or any subsequent router is a <command>redirect</command> router
+that runs a user’s filter file, the contents of <varname>$address_data</varname> are accessible
+in the filter. This is not normally a problem, because such data is usually
+either not confidential or it <quote>belongs</quote> to the current user, but if you do
+put confidential data into <varname>$address_data</varname> you need to remember this point.
+</para>
+<para>
+Even if the router declines or passes, the value of <varname>$address_data</varname> remains
+with the address, though it can be changed by another <option>address_data</option> setting
+on a subsequent router. If a router generates child addresses, the value of
+<varname>$address_data</varname> propagates to them. This also applies to the special kind of
+<quote>child</quote> that is generated by a router with the <option>unseen</option> option.
+</para>
+<para>
+The idea of <option>address_data</option> is that you can use it to look up a lot of data
+for the address once, and then pick out parts of the data later. For example,
+you could use a single LDAP lookup to return a string of the form
+</para>
+<literallayout class="monospaced">
+uid=1234 gid=5678 mailbox=/mail/xyz forward=/home/xyz/.forward
+</literallayout>
+<para>
+In the transport you could pick out the mailbox by a setting such as
+</para>
+<literallayout class="monospaced">
+file = ${extract{mailbox}{$address_data}}
+</literallayout>
+<para>
+This makes the configuration file less messy, and also reduces the number of
+lookups (though Exim does cache lookups).
+</para>
+<para>
+See also the <option>set</option> option below.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_address_data</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$address_data</varname></primary>
+</indexterm>
+The <option>address_data</option> facility is also useful as a means of passing information
+from one router to another, and from a router to a transport. In addition, if
+<varname>$address_data</varname> is set by a router when verifying a recipient address from an
+ACL, it remains available for use in the rest of the ACL statement. After
+verifying a sender, the value is transferred to <varname>$sender_address_data</varname>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>address_test</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>address_test</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="option">
+<primary><option>-bt</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>skipping when address testing</secondary>
+</indexterm>
+If this option is set false, the router is skipped when routing is being tested
+by means of the <option>-bt</option> command line option. This can be a convenience when
+your first router sends messages to an external scanner, because it saves you
+having to set the <quote>already scanned</quote> indicator when testing real address
+routing.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>cannot_route_message</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>cannot_route_message</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>customizing <quote>cannot route</quote> message</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>customizing</primary>
+<secondary><quote>cannot route</quote> message</secondary>
+</indexterm>
+This option specifies a text message that is used when an address cannot be
+routed because Exim has run out of routers. The default message is
+<quote>Unrouteable address</quote>. This option is useful only on routers that have
+<option>more</option> set false, or on the very last router in a configuration, because the
+value that is used is taken from the last router that is considered. This
+includes a router that is skipped because its preconditions are not met, as
+well as a router that declines. For example, using the default configuration,
+you could put:
+</para>
+<literallayout class="monospaced">
+cannot_route_message = Remote domain not found in DNS
+</literallayout>
+<para>
+on the first router, which is a <command>dnslookup</command> router with <option>more</option> set false,
+and
+</para>
+<literallayout class="monospaced">
+cannot_route_message = Unknown local user
+</literallayout>
+<para>
+on the final router that checks for local users. If string expansion fails for
+this option, the default message is used. Unless the expansion failure was
+explicitly forced, a message about the failure is written to the main and panic
+logs, in addition to the normal message about the routing failure.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>caseful_local_part</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>caseful_local_part</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>case of local parts</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>case of local parts</secondary>
+</indexterm>
+By default, routers handle the local parts of addresses in a case-insensitive
+manner, though the actual case is preserved for transmission with the message.
+If you want the case of letters to be significant in a router, you must set
+this option true. For individual router options that contain address or local
+part lists (for example, <option>local_parts</option>), case-sensitive matching can be
+turned on by <quote>+caseful</quote> as a list item. See section <xref linkend="SECTcasletadd"/> for
+more details.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$original_local_part</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$parent_local_part</varname></primary>
+</indexterm>
+The value of the <varname>$local_part</varname> variable is forced to lower case while a
+router is running unless <option>caseful_local_part</option> is set. When a router assigns
+an address to a transport, the value of <varname>$local_part</varname> when the transport runs
+is the same as it was in the router. Similarly, when a router generates child
+addresses by aliasing or forwarding, the values of <varname>$original_local_part</varname>
+and <varname>$parent_local_part</varname> are those that were used by the redirecting router.
+</para>
+<para>
+This option applies to the processing of an address by a router. When a
+recipient address is being processed in an ACL, there is a separate <option>control</option>
+modifier that can be used to specify case-sensitive processing within the ACL
+(see section <xref linkend="SECTcontrols"/>).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_local_user</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_local_user</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>local user, checking in router</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>checking for local user</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><filename>/etc/passwd</filename></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$home</varname></primary>
+</indexterm>
+When this option is true, Exim checks that the local part of the recipient
+address (with affixes removed if relevant) is the name of an account on the
+local system. The check is done by calling the <function>getpwnam()</function> function rather
+than trying to read <filename>/etc/passwd</filename> directly. This means that other methods of
+holding password data (such as NIS) are supported. If the local part is a local
+user, <varname>$home</varname> is set from the password data, and can be tested in other
+preconditions that are evaluated after this one (the order of evaluation is
+given in section <xref linkend="SECTrouprecon"/>). However, the value of <varname>$home</varname> can be
+overridden by <option>router_home_directory</option>. If the local part is not a local user,
+the router is skipped.
+</para>
+<para>
+If you want to check that the local part is either the name of a local user
+or matches something else, you cannot combine <option>check_local_user</option> with a
+setting of <option>local_parts</option>, because that specifies the logical <emphasis>and</emphasis> of the
+two conditions. However, you can use a <command>passwd</command> lookup in a <option>local_parts</option>
+setting to achieve this. For example:
+</para>
+<literallayout class="monospaced">
+local_parts = passwd;$local_part : lsearch;/etc/other/users
+</literallayout>
+<para>
+Note, however, that the side effects of <option>check_local_user</option> (such as setting
+up a home directory) do not occur when a <command>passwd</command> lookup is used in a
+<option>local_parts</option> (or any other) precondition.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>condition</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>condition</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>customized precondition</secondary>
+</indexterm>
+This option specifies a general precondition test that has to succeed for the
+router to be called. The <option>condition</option> option is the last precondition to be
+evaluated (see section <xref linkend="SECTrouprecon"/>). The string is expanded, and if the
+result is a forced failure, or an empty string, or one of the strings <quote>0</quote> or
+<quote>no</quote> or <quote>false</quote> (checked without regard to the case of the letters), the
+router is skipped, and the address is offered to the next one.
+</para>
+<para>
+If the result is any other value, the router is run (as this is the last
+precondition to be evaluated, all the other preconditions must be true).
+</para>
+<para>
+This option is unusual in that multiple <option>condition</option> options may be present.
+All <option>condition</option> options must succeed.
+</para>
+<para>
+The <option>condition</option> option provides a means of applying custom conditions to the
+running of routers. Note that in the case of a simple conditional expansion,
+the default expansion values are exactly what is wanted. For example:
+</para>
+<literallayout class="monospaced">
+condition = ${if >{$message_age}{600}}
+</literallayout>
+<para>
+Because of the default behaviour of the string expansion, this is equivalent to
+</para>
+<literallayout class="monospaced">
+condition = ${if >{$message_age}{600}{true}{}}
+</literallayout>
+<para>
+A multiple condition example, which succeeds:
+</para>
+<literallayout class="monospaced">
+condition = ${if >{$message_age}{600}}
+condition = ${if !eq{${lc:$local_part}}{postmaster}}
+condition = foobar
+</literallayout>
+<para>
+If the expansion fails (other than forced failure) delivery is deferred. Some
+of the other precondition options are common special cases that could in fact
+be specified using <option>condition</option>.
+</para>
+<para>
+Historical note: We have <option>condition</option> on ACLs and on Routers. Routers
+are far older, and use one set of semantics. ACLs are newer and when
+they were created, the ACL <option>condition</option> process was given far stricter
+parse semantics. The <option>bool{}</option> expansion condition uses the same rules as
+ACLs. The <option>bool_lax{}</option> expansion condition uses the same rules as
+Routers. More pointedly, the <option>bool_lax{}</option> was written to match the existing
+Router rules processing behavior.
+</para>
+<para>
+This is best illustrated in an example:
+</para>
+<literallayout class="monospaced">
+# If used in an ACL condition will fail with a syntax error, but
+# in a router condition any extra characters are treated as a string
+
+$ exim -be '${if eq {${lc:GOOGLE.com}} {google.com}} {yes} {no}}'
+true {yes} {no}}
+
+$ exim -be '${if eq {${lc:WHOIS.com}} {google.com}} {yes} {no}}'
+ {yes} {no}}
+</literallayout>
+<para>
+In each example above, the <option>if</option> statement actually ends after
+<quote>{google.com}}</quote>. Since no true or false braces were defined, the
+default <option>if</option> behavior is to return a boolean true or a null answer
+(which evaluates to false). The rest of the line is then treated as a
+string. So the first example resulted in the boolean answer <quote>true</quote>
+with the string <quote> {yes} {no}}</quote> appended to it. The second example
+resulted in the null output (indicating false) with the string
+<quote> {yes} {no}}</quote> appended to it.
+</para>
+<para>
+In fact you can put excess forward braces in too. In the router
+<option>condition</option>, Exim’s parser only looks for <quote>{</quote> symbols when they
+mean something, like after a <quote>$</quote> or when required as part of a
+conditional. But otherwise <quote>{</quote> and <quote>}</quote> are treated as ordinary
+string characters.
+</para>
+<para>
+Thus, in a Router, the above expansion strings will both always evaluate
+true, as the result of expansion is a non-empty string which doesn’t
+match an explicit false value. This can be tricky to debug. By
+contrast, in an ACL either of those strings will always result in an
+expansion error because the result doesn’t look sufficiently boolean.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>debug_print</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>debug_print</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>variables in drivers</secondary>
+</indexterm>
+If this option is set and debugging is enabled (see the <option>-d</option> command line
+option) or in address-testing mode (see the <option>-bt</option> command line option),
+the string is expanded and included in the debugging output.
+If expansion of the string fails, the error message is written to the debugging
+output, and Exim carries on processing.
+This option is provided to help with checking out the values of variables and
+so on when debugging router configurations. For example, if a <option>condition</option>
+option appears not to be working, <option>debug_print</option> can be used to output the
+variables it references. The output happens after checks for <option>domains</option>,
+<option>local_parts</option>, and <option>check_local_user</option> but before any other preconditions
+are tested. A newline is added to the text if it does not end with one.
+The variable <varname>$router_name</varname> contains the name of the router.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>disable_logging</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>disable_logging</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is set true, nothing is logged for any routing errors
+or for any deliveries caused by this router. You should not set this option
+unless you really, really know what you are doing. See also the generic
+transport option of the same name.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dnssec_request_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dnssec_request_domains</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>MX record</primary>
+<secondary>security</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNSSEC</primary>
+<secondary>MX lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>security</primary>
+<secondary>MX lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>DNSSEC</secondary>
+</indexterm>
+DNS lookups for domains matching <option>dnssec_request_domains</option> will be done with
+the dnssec request bit set.
+This applies to all of the SRV, MX, AAAA, A lookup sequence.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dnssec_require_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dnssec_require_domains</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>MX record</primary>
+<secondary>security</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNSSEC</primary>
+<secondary>MX lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>security</primary>
+<secondary>MX lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>DNSSEC</secondary>
+</indexterm>
+DNS lookups for domains matching <option>dnssec_require_domains</option> will be done with
+the dnssec request bit set. Any returns not having the Authenticated Data bit
+(AD bit) set will be ignored and logged as a host-lookup failure.
+This applies to all of the SRV, MX, AAAA, A lookup sequence.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>domains</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>restricting to specific domains</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$domain_data</varname></primary>
+</indexterm>
+If this option is set, the router is skipped unless the current domain matches
+the list. If the match is achieved by means of a file lookup, the data that the
+lookup returned for the domain is placed in <varname>$domain_data</varname> for use in string
+expansions of the driver’s private options. See section <xref linkend="SECTrouprecon"/> for
+a list of the order in which preconditions are evaluated.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>driver</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>driver</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option must always be set. It specifies which of the available routers is
+to be used.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dsn_lasthop</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dsn_lasthop</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DSN</primary>
+<secondary>success</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Delivery Status Notification</primary>
+<secondary>success</secondary>
+</indexterm>
+If this option is set true, and extended DSN (RFC3461) processing is in effect,
+Exim will not pass on DSN requests to downstream DSN-aware hosts but will
+instead send a success DSN as if the next hop does not support DSN.
+Not effective on redirect routers.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>errors_to</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>errors_to</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>envelope from</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope sender</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>changing address for errors</secondary>
+</indexterm>
+If a router successfully handles an address, it may assign the address to a
+transport for delivery or it may generate child addresses. In both cases, if
+there is a delivery problem during later processing, the resulting bounce
+message is sent to the address that results from expanding this string,
+provided that the address verifies successfully. The <option>errors_to</option> option is
+expanded before <option>headers_add</option>, <option>headers_remove</option>, and <option>transport</option>.
+</para>
+<para>
+The <option>errors_to</option> setting associated with an address can be overridden if it
+subsequently passes through other routers that have their own <option>errors_to</option>
+settings, or if the message is delivered by a transport with a <option>return_path</option>
+setting.
+</para>
+<para>
+If <option>errors_to</option> is unset, or the expansion is forced to fail, or the result of
+the expansion fails to verify, the errors address associated with the incoming
+address is used. At top level, this is the envelope sender. A non-forced
+expansion failure causes delivery to be deferred.
+</para>
+<para>
+If an address for which <option>errors_to</option> has been set ends up being delivered over
+SMTP, the envelope sender for that delivery is the <option>errors_to</option> value, so that
+any bounces that are generated by other MTAs on the delivery route are also
+sent there. You can set <option>errors_to</option> to the empty string by either of these
+settings:
+</para>
+<literallayout class="monospaced">
+errors_to =
+errors_to = ""
+</literallayout>
+<para>
+An expansion item that yields an empty string has the same effect. If you do
+this, a locally detected delivery error for addresses processed by this router
+no longer gives rise to a bounce message; the error is discarded. If the
+address is delivered to a remote host, the return path is set to <literal><></literal>, unless
+overridden by the <option>return_path</option> option on the transport.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$address_data</varname></primary>
+</indexterm>
+If for some reason you want to discard local errors, but use a non-empty
+MAIL command for remote delivery, you can preserve the original return
+path in <varname>$address_data</varname> in the router, and reinstate it in the transport by
+setting <option>return_path</option>.
+</para>
+<para>
+The most common use of <option>errors_to</option> is to direct mailing list bounces to the
+manager of the list, as described in section <xref linkend="SECTmailinglists"/>, or to
+implement VERP (Variable Envelope Return Paths) (see section <xref linkend="SECTverp"/>).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>expn</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>expn</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>address</primary>
+<secondary>testing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>addresses</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>EXPN</primary>
+<secondary>router skipping</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>skipping for EXPN</secondary>
+</indexterm>
+If this option is turned off, the router is skipped when testing an address
+as a result of processing an SMTP EXPN command. You might, for example,
+want to turn it off on a router for users’ <filename>.forward</filename> files, while leaving it
+on for the system alias file.
+See section <xref linkend="SECTrouprecon"/> for a list of the order in which preconditions
+are evaluated.
+</para>
+<para>
+The use of the SMTP EXPN command is controlled by an ACL (see chapter
+<xref linkend="CHAPACL"/>). When Exim is running an EXPN command, it is similar to testing
+an address with <option>-bt</option>. Compare VRFY, whose counterpart is <option>-bv</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>fail_verify</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>fail_verify</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>forcing verification failure</secondary>
+</indexterm>
+Setting this option has the effect of setting both <option>fail_verify_sender</option> and
+<option>fail_verify_recipient</option> to the same value.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>fail_verify_recipient</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>fail_verify_recipient</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is true and an address is accepted by this router when
+verifying a recipient, verification fails.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>fail_verify_sender</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>fail_verify_sender</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is true and an address is accepted by this router when
+verifying a sender, verification fails.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>fallback_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>fallback_hosts</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>fallback hosts</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>fallback</primary>
+<secondary>hosts specified on router</secondary>
+</indexterm>
+String expansion is not applied to this option. The argument must be a
+colon-separated list of host names or IP addresses. The list separator can be
+changed (see section <xref linkend="SECTlistsepchange"/>), and a port can be specified with
+each name or address. In fact, the format of each item is exactly the same as
+defined for the list of hosts in a <command>manualroute</command> router (see section
+<xref linkend="SECTformatonehostitem"/>).
+</para>
+<para>
+If a router queues an address for a remote transport, this host list is
+associated with the address, and used instead of the transport’s fallback host
+list. If <option>hosts_randomize</option> is set on the transport, the order of the list is
+randomized for each use. See the <option>fallback_hosts</option> option of the <command>smtp</command>
+transport for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>group</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>group</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>gid (group id)</primary>
+<secondary>local delivery</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local transports</primary>
+<secondary>uid and gid</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>local</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>setting group</secondary>
+</indexterm>
+When a router queues an address for a transport, and the transport does not
+specify a group, the group given here is used when running the delivery
+process.
+The group may be specified numerically or by name. If expansion fails, the
+error is logged and delivery is deferred.
+The default is unset, unless <option>check_local_user</option> is set, when the default
+is taken from the password information. See also <option>initgroups</option> and <option>user</option>
+and the discussion in chapter <xref linkend="CHAPenvironment"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>headers_add</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>headers_add</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>adding</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>adding header lines</secondary>
+</indexterm>
+This option specifies a list of text headers,
+newline-separated (by default, changeable in the usual way <xref linkend="SECTlistsepchange"/>),
+that is associated with any addresses that are accepted by the router.
+Each item is separately expanded, at routing time. However, this
+option has no effect when an address is just being verified. The way in which
+the text is used to add header lines at transport time is described in section
+<xref linkend="SECTheadersaddrem"/>. New header lines are not actually added until the
+message is in the process of being transported. This means that references to
+header lines in string expansions in the transport’s configuration do not
+<quote>see</quote> the added header lines.
+</para>
+<para>
+The <option>headers_add</option> option is expanded after <option>errors_to</option>, but before
+<option>headers_remove</option> and <option>transport</option>. If an item is empty, or if
+an item expansion is forced to fail, the item has no effect. Other expansion
+failures are treated as configuration errors.
+</para>
+<para>
+Unlike most options, <option>headers_add</option> can be specified multiple times
+for a router; all listed headers are added.
+</para>
+<para>
+<emphasis role="bold">Warning 1</emphasis>: The <option>headers_add</option> option cannot be used for a <command>redirect</command>
+router that has the <option>one_time</option> option set.
+</para>
+<para>
+<indexterm role="concept">
+<primary>duplicate addresses</primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>unseen</option></primary>
+</indexterm>
+<emphasis role="bold">Warning 2</emphasis>: If the <option>unseen</option> option is set on the router, all header
+additions are deleted when the address is passed on to subsequent routers.
+For a <option>redirect</option> router, if a generated address is the same as the incoming
+address, this can lead to duplicate addresses with different header
+modifications. Exim does not do duplicate deliveries (except, in certain
+circumstances, to pipes -- see section <xref linkend="SECTdupaddr"/>), but it is undefined
+which of the duplicates is discarded, so this ambiguous situation should be
+avoided. The <option>repeat_use</option> option of the <option>redirect</option> router may be of help.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>headers_remove</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>headers_remove</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>removing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>removing header lines</secondary>
+</indexterm>
+This option specifies a list of text headers,
+colon-separated (by default, changeable in the usual way <xref linkend="SECTlistsepchange"/>),
+that is associated with any addresses that are accepted by the router.
+However, the option has no effect when an address is just being verified.
+Each list item is separately expanded, at transport time.
+</para>
+<para revisionflag="changed">
+If an item ends in *, it will match any header with the given prefix.
+</para>
+<para>
+The way in which
+the text is used to remove header lines at transport time is described in
+section <xref linkend="SECTheadersaddrem"/>. Header lines are not actually removed until
+the message is in the process of being transported. This means that references
+to header lines in string expansions in the transport’s configuration still
+<quote>see</quote> the original header lines.
+</para>
+<para>
+The <option>headers_remove</option> option is handled after <option>errors_to</option> and
+<option>headers_add</option>, but before <option>transport</option>. If an item expansion is forced to fail,
+the item has no effect. Other expansion failures are treated as configuration
+errors.
+</para>
+<para>
+Unlike most options, <option>headers_remove</option> can be specified multiple times
+for a router; all listed headers are removed.
+</para>
+<para>
+<emphasis role="bold">Warning 1</emphasis>: The <option>headers_remove</option> option cannot be used for a <command>redirect</command>
+router that has the <option>one_time</option> option set.
+</para>
+<para>
+<emphasis role="bold">Warning 2</emphasis>: If the <option>unseen</option> option is set on the router, all header
+removal requests are deleted when the address is passed on to subsequent
+routers, and this can lead to problems with duplicates -- see the similar
+warning for <option>headers_add</option> above.
+</para>
+<para>
+<emphasis role="bold">Warning 3</emphasis>: Because of the separate expansion of the list items,
+items that contain a list separator must have it doubled.
+To avoid this, change the list separator (<xref linkend="SECTlistsepchange"/>).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ignore_target_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ignore_target_hosts</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>IP address</primary>
+<secondary>discarding</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>discarding IP addresses</secondary>
+</indexterm>
+Although this option is a host list, it should normally contain IP address
+entries rather than names. If any host that is looked up by the router has an
+IP address that matches an item in this list, Exim behaves as if that IP
+address did not exist. This option allows you to cope with rogue DNS entries
+like
+</para>
+<literallayout class="monospaced">
+remote.domain.example. A 127.0.0.1
+</literallayout>
+<para>
+by setting
+</para>
+<literallayout class="monospaced">
+ignore_target_hosts = 127.0.0.1
+</literallayout>
+<para>
+on the relevant router. If all the hosts found by a <command>dnslookup</command> router are
+discarded in this way, the router declines. In a conventional configuration, an
+attempt to mail to such a domain would normally provoke the <quote>unrouteable
+domain</quote> error, and an attempt to verify an address in the domain would fail.
+Similarly, if <option>ignore_target_hosts</option> is set on an <command>ipliteral</command> router, the
+router declines if presented with one of the listed addresses.
+</para>
+<para>
+You can use this option to disable the use of IPv4 or IPv6 for mail delivery by
+means of the first or the second of the following settings, respectively:
+</para>
+<literallayout class="monospaced">
+ignore_target_hosts = 0.0.0.0/0
+ignore_target_hosts = <; 0::0/0
+</literallayout>
+<para>
+The pattern in the first line matches all IPv4 addresses, whereas the pattern
+in the second line matches all IPv6 addresses.
+</para>
+<para>
+This option may also be useful for ignoring link-local and site-local IPv6
+addresses. Because, like all host lists, the value of <option>ignore_target_hosts</option>
+is expanded before use as a list, it is possible to make it dependent on the
+domain that is being routed.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$host_address</varname></primary>
+</indexterm>
+During its expansion, <varname>$host_address</varname> is set to the IP address that is being
+checked.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>initgroups</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>initgroups</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>additional groups</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>groups</primary>
+<secondary>additional</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local transports</primary>
+<secondary>uid and gid</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>local</secondary>
+</indexterm>
+If the router queues an address for a transport, and this option is true, and
+the uid supplied by the router is not overridden by the transport, the
+<function>initgroups()</function> function is called when running the transport to ensure that
+any additional groups associated with the uid are set up. See also <option>group</option>
+and <option>user</option> and the discussion in chapter <xref linkend="CHAPenvironment"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>local_part_prefix</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>local_part_prefix</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>affix</primary>
+<secondary>router precondition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>prefix for local part</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>prefix</primary>
+<secondary>for local part, used in router</secondary>
+</indexterm>
+If this option is set, the router is skipped unless the local part starts with
+one of the given strings, or <option>local_part_prefix_optional</option> is true. See
+section <xref linkend="SECTrouprecon"/> for a list of the order in which preconditions are
+evaluated.
+</para>
+<para>
+The list is scanned from left to right, and the first prefix that matches is
+used. A limited form of wildcard is available; if the prefix begins with an
+asterisk, it matches the longest possible sequence of arbitrary characters at
+the start of the local part. An asterisk should therefore always be followed by
+some character that does not occur in normal local parts.
+<indexterm role="concept">
+<primary>multiple mailboxes</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>mailbox</primary>
+<secondary>multiple</secondary>
+</indexterm>
+Wildcarding can be used to set up multiple user mailboxes, as described in
+section <xref linkend="SECTmulbox"/>.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part_prefix</varname></primary>
+</indexterm>
+During the testing of the <option>local_parts</option> option, and while the router is
+running, the prefix is removed from the local part, and is available in the
+expansion variable <varname>$local_part_prefix</varname>. When a message is being delivered, if
+the router accepts the address, this remains true during subsequent delivery by
+a transport. In particular, the local part that is transmitted in the RCPT
+command for LMTP, SMTP, and BSMTP deliveries has the prefix removed by default.
+This behaviour can be overridden by setting <option>rcpt_include_affixes</option> true on
+the relevant transport.
+</para>
+<para revisionflag="changed">
+<indexterm role="variable">
+<primary><varname>$local_part_prefix_v</varname></primary>
+</indexterm>
+If wildcarding (above) was used then the part of the prefix matching the
+wildcard is available in <varname>$local_part_prefix_v</varname>.
+</para>
+<para>
+When an address is being verified, <option>local_part_prefix</option> affects only the
+behaviour of the router. If the callout feature of verification is in use, this
+means that the full address, including the prefix, will be used during the
+callout.
+</para>
+<para>
+The prefix facility is commonly used to handle local parts of the form
+<option>owner-something</option>. Another common use is to support local parts of the form
+<option>real-username</option> to bypass a user’s <filename>.forward</filename> file – helpful when trying
+to tell a user their forwarding is broken – by placing a router like this one
+immediately before the router that handles <filename>.forward</filename> files:
+</para>
+<literallayout class="monospaced">
+real_localuser:
+ driver = accept
+ local_part_prefix = real-
+ check_local_user
+ transport = local_delivery
+</literallayout>
+<para>
+For security, it would probably be a good idea to restrict the use of this
+router to locally-generated messages, using a condition such as this:
+</para>
+<literallayout class="monospaced">
+ condition = ${if match {$sender_host_address}\
+ {\N^(|127\.0\.0\.1)$\N}}
+</literallayout>
+<para>
+If both <option>local_part_prefix</option> and <option>local_part_suffix</option> are set for a router,
+both conditions must be met if not optional. Care must be taken if wildcards
+are used in both a prefix and a suffix on the same router. Different
+separator characters must be used to avoid ambiguity.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>local_part_prefix_optional</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>local_part_prefix_optional</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>local_part_prefix</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>local_part_suffix</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>local_part_suffix</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>suffix for local part</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>suffix for local part</primary>
+<secondary>used in router</secondary>
+</indexterm>
+This option operates in the same way as <option>local_part_prefix</option>, except that the
+local part must end (rather than start) with the given string, the
+<option>local_part_suffix_optional</option> option determines whether the suffix is
+mandatory, and the wildcard * character, if present, must be the last
+character of the suffix. This option facility is commonly used to handle local
+parts of the form <option>something-request</option> and multiple user mailboxes of the form
+<option>username-foo</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>local_part_suffix_optional</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>local_part_suffix_optional</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>local_part_suffix</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>local_parts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>local_parts</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>local part list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>restricting to specific local parts</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>checking in router</secondary>
+</indexterm>
+The router is run only if the local part of the address matches the list.
+See section <xref linkend="SECTrouprecon"/> for a list of the order in which preconditions
+are evaluated, and
+section <xref linkend="SECTlocparlis"/> for a discussion of local part lists. Because the
+string is expanded, it is possible to make it depend on the domain, for
+example:
+</para>
+<literallayout class="monospaced">
+local_parts = dbm;/usr/local/specials/$domain
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part_data</varname></primary>
+</indexterm>
+If the match is achieved by a lookup, the data that the lookup returned
+for the local part is placed in the variable <varname>$local_part_data</varname> for use in
+expansions of the router’s private options. You might use this option, for
+example, if you have a large number of local virtual domains, and you want to
+send all postmaster mail to the same place without having to set up an alias in
+each virtual domain:
+</para>
+<literallayout class="monospaced">
+postmaster:
+ driver = redirect
+ local_parts = postmaster
+ data = postmaster@real.domain.example
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>log_as_local</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>log_as_local</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>delivery line</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>log line format</secondary>
+</indexterm>
+Exim has two logging styles for delivery, the idea being to make local
+deliveries stand out more visibly from remote ones. In the <quote>local</quote> style, the
+recipient address is given just as the local part, without a domain. The use of
+this style is controlled by this option. It defaults to true for the <command>accept</command>
+router, and false for all the others. This option applies only when a
+router assigns an address to a transport. It has no effect on routers that
+redirect addresses.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>more</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>more</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+The result of string expansion for this option must be a valid boolean value,
+that is, one of the strings <quote>yes</quote>, <quote>no</quote>, <quote>true</quote>, or <quote>false</quote>. Any other
+result causes an error, and delivery is deferred. If the expansion is forced to
+fail, the default value for the option (true) is used. Other failures cause
+delivery to be deferred.
+</para>
+<para>
+If this option is set false, and the router declines to handle the address, no
+further routers are tried, routing fails, and the address is bounced.
+<indexterm role="option">
+<primary><option>self</option></primary>
+</indexterm>
+However, if the router explicitly passes an address to the following router by
+means of the setting
+</para>
+<literallayout class="monospaced">
+self = pass
+</literallayout>
+<para>
+or otherwise, the setting of <option>more</option> is ignored. Also, the setting of <option>more</option>
+does not affect the behaviour if one of the precondition tests fails. In that
+case, the address is always passed to the next router.
+</para>
+<para>
+Note that <option>address_data</option> is not considered to be a precondition. If its
+expansion is forced to fail, the router declines, and the value of <option>more</option>
+controls what happens next.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>pass_on_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>pass_on_timeout</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>of router</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>timeout</secondary>
+</indexterm>
+If a router times out during a host lookup, it normally causes deferral of the
+address. If <option>pass_on_timeout</option> is set, the address is passed on to the next
+router, overriding <option>no_more</option>. This may be helpful for systems that are
+intermittently connected to the Internet, or those that want to pass to a smart
+host any messages that cannot immediately be delivered.
+</para>
+<para>
+There are occasional other temporary errors that can occur while doing DNS
+lookups. They are treated in the same way as a timeout, and this option
+applies to all of them.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>pass_router</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>pass_router</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>go to after <quote>pass</quote></secondary>
+</indexterm>
+Routers that recognize the generic <option>self</option> option (<command>dnslookup</command>,
+<command>ipliteral</command>, and <command>manualroute</command>) are able to return <quote>pass</quote>, forcing
+routing to continue, and overriding a false setting of <option>more</option>. When one of
+these routers returns <quote>pass</quote>, the address is normally handed on to the next
+router in sequence. This can be changed by setting <option>pass_router</option> to the name
+of another router. However (unlike <option>redirect_router</option>) the named router must
+be below the current router, to avoid loops. Note that this option applies only
+to the special case of <quote>pass</quote>. It does not apply when a router returns
+<quote>decline</quote> because it cannot handle an address.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>redirect_router</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>redirect_router</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>start at after redirection</secondary>
+</indexterm>
+Sometimes an administrator knows that it is pointless to reprocess addresses
+generated from alias or forward files with the same router again. For
+example, if an alias file translates real names into login ids there is no
+point searching the alias file a second time, especially if it is a large file.
+</para>
+<para>
+The <option>redirect_router</option> option can be set to the name of any router instance.
+It causes the routing of any generated addresses to start at the named router
+instead of at the first router. This option has no effect if the router in
+which it is set does not generate new addresses.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>require_files</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>require_files</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>requiring for router</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>requiring file existence</secondary>
+</indexterm>
+This option provides a general mechanism for predicating the running of a
+router on the existence or non-existence of certain files or directories.
+Before running a router, as one of its precondition tests, Exim works its way
+through the <option>require_files</option> list, expanding each item separately.
+</para>
+<para>
+Because the list is split before expansion, any colons in expansion items must
+be doubled, or the facility for using a different list separator must be used
+(<xref linkend="SECTlistsepchange"/>).
+If any expansion is forced to fail, the item is ignored. Other expansion
+failures cause routing of the address to be deferred.
+</para>
+<para>
+If any expanded string is empty, it is ignored. Otherwise, except as described
+below, each string must be a fully qualified file path, optionally preceded by
+<quote>!</quote>. The paths are passed to the <function>stat()</function> function to test for the
+existence of the files or directories. The router is skipped if any paths not
+preceded by <quote>!</quote> do not exist, or if any paths preceded by <quote>!</quote> do exist.
+</para>
+<para>
+<indexterm role="concept">
+<primary>NFS</primary>
+</indexterm>
+If <function>stat()</function> cannot determine whether a file exists or not, delivery of
+the message is deferred. This can happen when NFS-mounted filesystems are
+unavailable.
+</para>
+<para>
+This option is checked after the <option>domains</option>, <option>local_parts</option>, and <option>senders</option>
+options, so you cannot use it to check for the existence of a file in which to
+look up a domain, local part, or sender. (See section <xref linkend="SECTrouprecon"/> for a
+full list of the order in which preconditions are evaluated.) However, as
+these options are all expanded, you can use the <option>exists</option> expansion condition
+to make such tests. The <option>require_files</option> option is intended for checking files
+that the router may be going to use internally, or which are needed by a
+transport (e.g., <filename>.procmailrc</filename>).
+</para>
+<para>
+During delivery, the <function>stat()</function> function is run as root, but there is a
+facility for some checking of the accessibility of a file by another user.
+This is not a proper permissions check, but just a <quote>rough</quote> check that
+operates as follows:
+</para>
+<para>
+If an item in a <option>require_files</option> list does not contain any forward slash
+characters, it is taken to be the user (and optional group, separated by a
+comma) to be checked for subsequent files in the list. If no group is specified
+but the user is specified symbolically, the gid associated with the uid is
+used. For example:
+</para>
+<literallayout class="monospaced">
+require_files = mail:/some/file
+require_files = $local_part_data:$home/.procmailrc
+</literallayout>
+<para>
+If a user or group name in a <option>require_files</option> list does not exist, the
+<option>require_files</option> condition fails.
+</para>
+<para>
+Exim performs the check by scanning along the components of the file path, and
+checking the access for the given uid and gid. It checks for <quote>x</quote> access on
+directories, and <quote>r</quote> access on the final file. Note that this means that file
+access control lists, if the operating system has them, are ignored.
+</para>
+<para>
+<emphasis role="bold">Warning 1</emphasis>: When the router is being run to verify addresses for an
+incoming SMTP message, Exim is not running as root, but under its own uid. This
+may affect the result of a <option>require_files</option> check. In particular, <function>stat()</function>
+may yield the error EACCES (<quote>Permission denied</quote>). This means that the Exim
+user is not permitted to read one of the directories on the file’s path.
+</para>
+<para>
+<emphasis role="bold">Warning 2</emphasis>: Even when Exim is running as root while delivering a message,
+<function>stat()</function> can yield EACCES for a file in an NFS directory that is mounted
+without root access. In this case, if a check for access by a particular user
+is requested, Exim creates a subprocess that runs as that user, and tries the
+check again in that process.
+</para>
+<para>
+The default action for handling an unresolved EACCES is to consider it to
+be caused by a configuration error, and routing is deferred because the
+existence or non-existence of the file cannot be determined. However, in some
+circumstances it may be desirable to treat this condition as if the file did
+not exist. If the filename (or the exclamation mark that precedes the filename
+for non-existence) is preceded by a plus sign, the EACCES error is treated
+as if the file did not exist. For example:
+</para>
+<literallayout class="monospaced">
+require_files = +/some/file
+</literallayout>
+<para>
+If the router is not an essential part of verification (for example, it
+handles users’ <filename>.forward</filename> files), another solution is to set the <option>verify</option>
+option false so that the router is skipped when verifying.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>retry_use_local_part</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>retry_use_local_part</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>retry keys</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>in retry keys</secondary>
+</indexterm>
+When a delivery suffers a temporary routing failure, a retry record is created
+in Exim’s hints database. For addresses whose routing depends only on the
+domain, the key for the retry record should not involve the local part, but for
+other addresses, both the domain and the local part should be included.
+Usually, remote routing is of the former kind, and local routing is of the
+latter kind.
+</para>
+<para>
+This option controls whether the local part is used to form the key for retry
+hints for addresses that suffer temporary errors while being handled by this
+router. The default value is true for any router that has any of
+<option>check_local_user</option>,
+<option>local_parts</option>,
+<option>condition</option>,
+<option>local_part_prefix</option>,
+<option>local_part_suffix</option>,
+<option>senders</option> or
+<option>require_files</option>
+set, and false otherwise. Note that this option does not apply to hints keys
+for transport delays; they are controlled by a generic transport option of the
+same name.
+</para>
+<para>
+Failing to set this option when it is needed
+(because a remote router handles only some of the local-parts for a domain)
+can result in incorrect error messages being generated.
+</para>
+<para>
+The setting of <option>retry_use_local_part</option> applies only to the router on which it
+appears. If the router generates child addresses, they are routed
+independently; this setting does not become attached to them.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>router_home_directory</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>router_home_directory</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>home directory for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>home directory</primary>
+<secondary>for router</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$home</varname></primary>
+</indexterm>
+This option sets a home directory for use while the router is running. (Compare
+<option>transport_home_directory</option>, which sets a home directory for later
+transporting.) In particular, if used on a <command>redirect</command> router, this option
+sets a value for <varname>$home</varname> while a filter is running. The value is expanded;
+forced expansion failure causes the option to be ignored – other failures
+cause the router to defer.
+</para>
+<para>
+Expansion of <option>router_home_directory</option> happens immediately after the
+<option>check_local_user</option> test (if configured), before any further expansions take
+place.
+(See section <xref linkend="SECTrouprecon"/> for a list of the order in which preconditions
+are evaluated.)
+While the router is running, <option>router_home_directory</option> overrides the value of
+<varname>$home</varname> that came from <option>check_local_user</option>.
+</para>
+<para>
+When a router accepts an address and assigns it to a local transport (including
+the cases when a <command>redirect</command> router generates a pipe, file, or autoreply
+delivery), the home directory setting for the transport is taken from the first
+of these values that is set:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The <option>home_directory</option> option on the transport;
+</para>
+</listitem>
+<listitem>
+<para>
+The <option>transport_home_directory</option> option on the router;
+</para>
+</listitem>
+<listitem>
+<para>
+The password data if <option>check_local_user</option> is set on the router;
+</para>
+</listitem>
+<listitem>
+<para>
+The <option>router_home_directory</option> option on the router.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+In other words, <option>router_home_directory</option> overrides the password data for the
+router, but not for the transport.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>self</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>self</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>freeze</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>MX record</primary>
+<secondary>pointing to local host</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local host</primary>
+<secondary>MX pointing to</secondary>
+</indexterm>
+This option applies to those routers that use a recipient address to find a
+list of remote hosts. Currently, these are the <command>dnslookup</command>, <command>ipliteral</command>,
+and <command>manualroute</command> routers.
+Certain configurations of the <command>queryprogram</command> router can also specify a list
+of remote hosts.
+Usually such routers are configured to send the message to a remote host via an
+<command>smtp</command> transport. The <option>self</option> option specifies what happens when the first
+host on the list turns out to be the local host.
+The way in which Exim checks for the local host is described in section
+<xref linkend="SECTreclocipadd"/>.
+</para>
+<para>
+Normally this situation indicates either an error in Exim’s configuration (for
+example, the router should be configured not to process this domain), or an
+error in the DNS (for example, the MX should not point to this host). For this
+reason, the default action is to log the incident, defer the address, and
+freeze the message. The following alternatives are provided for use in special
+cases:
+</para>
+<variablelist>
+<varlistentry>
+<term><option>defer</option></term>
+<listitem>
+<para>
+Delivery of the message is tried again later, but the message is not frozen.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>reroute</option>: <<emphasis>domain</emphasis>></term>
+<listitem>
+<para>
+The domain is changed to the given domain, and the address is passed back to
+be reprocessed by the routers. No rewriting of headers takes place. This
+behaviour is essentially a redirection.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>reroute: rewrite:</option> <<emphasis>domain</emphasis>></term>
+<listitem>
+<para>
+The domain is changed to the given domain, and the address is passed back to be
+reprocessed by the routers. Any headers that contain the original domain are
+rewritten.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>pass</option></term>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>more</option></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$self_hostname</varname></primary>
+</indexterm>
+The router passes the address to the next router, or to the router named in the
+<option>pass_router</option> option if it is set. This overrides <option>no_more</option>. During
+subsequent routing and delivery, the variable <varname>$self_hostname</varname> contains the
+name of the local host that the router encountered. This can be used to
+distinguish between different cases for hosts with multiple names. The
+combination
+</para>
+<literallayout class="monospaced">
+self = pass
+no_more
+</literallayout>
+<para>
+ensures that only those addresses that routed to the local host are passed on.
+Without <option>no_more</option>, addresses that were declined for other reasons would also
+be passed to the next router.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>fail</option></term>
+<listitem>
+<para>
+Delivery fails and an error report is generated.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>send</option></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>local host</primary>
+<secondary>sending to</secondary>
+</indexterm>
+The anomaly is ignored and the address is queued for the transport. This
+setting should be used with extreme caution. For an <command>smtp</command> transport, it
+makes sense only in cases where the program that is listening on the SMTP port
+is not this version of Exim. That is, it must be some other MTA, or Exim with a
+different configuration file that handles the domain in another way.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+<indexterm role="option">
+<primary><option>senders</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>senders</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>address list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>checking senders</secondary>
+</indexterm>
+If this option is set, the router is skipped unless the message’s sender
+address matches something on the list.
+See section <xref linkend="SECTrouprecon"/> for a list of the order in which preconditions
+are evaluated.
+</para>
+<para>
+There are issues concerning verification when the running of routers is
+dependent on the sender. When Exim is verifying the address in an <option>errors_to</option>
+setting, it sets the sender to the null string. When using the <option>-bt</option> option
+to check a configuration file, it is necessary also to use the <option>-f</option> option to
+set an appropriate sender. For incoming mail, the sender is unset when
+verifying the sender, but is available when verifying any recipients. If the
+SMTP VRFY command is enabled, it must be used after MAIL if the sender address
+matters.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>set</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>set</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>variables</secondary>
+</indexterm>
+This option may be used multiple times on a router;
+because of this the list aspect is mostly irrelevant.
+The list separator is a semicolon but can be changed in the
+usual way.
+</para>
+<para>
+Each list-element given must be of the form <quote>name = value</quote>
+and the names used must start with the string <quote>r_</quote>.
+Values containing a list-separator should have them doubled.
+When a router runs, the strings are evaluated in order,
+to create variables which are added to the set associated with
+the address.
+The variable is set with the expansion of the value.
+The variables can be used by the router options
+(not including any preconditions)
+and by the transport.
+Later definitions of a given named variable will override former ones.
+Variable use is via the usual <varname>$r_...</varname> syntax.
+</para>
+<para>
+This is similar to the <option>address_data</option> option, except that
+many independent variables can be used, with choice of naming.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>translate_ip_address</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>translate_ip_address</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>IP address</primary>
+<secondary>translating</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>packet radio</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>IP address translation</secondary>
+</indexterm>
+There exist some rare networking situations (for example, packet radio) where
+it is helpful to be able to translate IP addresses generated by normal routing
+mechanisms into other IP addresses, thus performing a kind of manual IP
+routing. This should be done only if the normal IP routing of the TCP/IP stack
+is inadequate or broken. Because this is an extremely uncommon requirement, the
+code to support this option is not included in the Exim binary unless
+SUPPORT_TRANSLATE_IP_ADDRESS=yes is set in <filename>Local/Makefile</filename>.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$host_address</varname></primary>
+</indexterm>
+The <option>translate_ip_address</option> string is expanded for every IP address generated
+by the router, with the generated address set in <varname>$host_address</varname>. If the
+expansion is forced to fail, no action is taken.
+For any other expansion error, delivery of the message is deferred.
+If the result of the expansion is an IP address, that replaces the original
+address; otherwise the result is assumed to be a host name – this is looked
+up using <function>gethostbyname()</function> (or <function>getipnodebyname()</function> when available) to
+produce one or more replacement IP addresses. For example, to subvert all IP
+addresses in some specific networks, this could be added to a router:
+</para>
+<literallayout class="monospaced">
+translate_ip_address = \
+ ${lookup{${mask:$host_address/26}}lsearch{/some/file}\
+ {$value}fail}}
+</literallayout>
+<para>
+The file would contain lines like
+</para>
+<literallayout class="monospaced">
+10.2.3.128/26 some.host
+10.8.4.34/26 10.44.8.15
+</literallayout>
+<para>
+You should not make use of this facility unless you really understand what you
+are doing.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>transport</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>transport</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies the transport to be used when a router accepts an address
+and sets it up for delivery. A transport is never needed if a router is used
+only for verification. The value of the option is expanded at routing time,
+after the expansion of <option>errors_to</option>, <option>headers_add</option>, and <option>headers_remove</option>,
+and result must be the name of one of the configured transports. If it is not,
+delivery is deferred.
+</para>
+<para>
+The <option>transport</option> option is not used by the <command>redirect</command> router, but it does
+have some private options that set up transports for pipe and file deliveries
+(see chapter <xref linkend="CHAPredirect"/>).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>transport_current_directory</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>transport_current_directory</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>current directory for local transport</primary>
+</indexterm>
+This option associates a current directory with any address that is routed
+to a local transport. This can happen either because a transport is
+explicitly configured for the router, or because it generates a delivery to a
+file or a pipe. During the delivery process (that is, at transport time), this
+option string is expanded and is set as the current directory, unless
+overridden by a setting on the transport.
+If the expansion fails for any reason, including forced failure, an error is
+logged, and delivery is deferred.
+See chapter <xref linkend="CHAPenvironment"/> for details of the local delivery
+environment.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>transport_home_directory</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>transport_home_directory</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>home directory</primary>
+<secondary>for local transport</secondary>
+</indexterm>
+This option associates a home directory with any address that is routed to a
+local transport. This can happen either because a transport is explicitly
+configured for the router, or because it generates a delivery to a file or a
+pipe. During the delivery process (that is, at transport time), the option
+string is expanded and is set as the home directory, unless overridden by a
+setting of <option>home_directory</option> on the transport.
+If the expansion fails for any reason, including forced failure, an error is
+logged, and delivery is deferred.
+</para>
+<para>
+If the transport does not specify a home directory, and
+<option>transport_home_directory</option> is not set for the router, the home directory for
+the transport is taken from the password data if <option>check_local_user</option> is set for
+the router. Otherwise it is taken from <option>router_home_directory</option> if that option
+is set; if not, no home directory is set for the transport.
+</para>
+<para>
+See chapter <xref linkend="CHAPenvironment"/> for further details of the local delivery
+environment.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>unseen</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>unseen</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>carrying on after success</secondary>
+</indexterm>
+The result of string expansion for this option must be a valid boolean value,
+that is, one of the strings <quote>yes</quote>, <quote>no</quote>, <quote>true</quote>, or <quote>false</quote>. Any other
+result causes an error, and delivery is deferred. If the expansion is forced to
+fail, the default value for the option (false) is used. Other failures cause
+delivery to be deferred.
+</para>
+<para>
+When this option is set true, routing does not cease if the router accepts the
+address. Instead, a copy of the incoming address is passed to the next router,
+overriding a false setting of <option>more</option>. There is little point in setting
+<option>more</option> false if <option>unseen</option> is always true, but it may be useful in cases when
+the value of <option>unseen</option> contains expansion items (and therefore, presumably, is
+sometimes true and sometimes false).
+</para>
+<para>
+<indexterm role="concept">
+<primary>copy of message (<option>unseen</option> option)</primary>
+</indexterm>
+Setting the <option>unseen</option> option has a similar effect to the <option>unseen</option> command
+qualifier in filter files. It can be used to cause copies of messages to be
+delivered to some other destination, while also carrying out a normal delivery.
+In effect, the current address is made into a <quote>parent</quote> that has two children
+– one that is delivered as specified by this router, and a clone that goes on
+to be routed further. For this reason, <option>unseen</option> may not be combined with the
+<option>one_time</option> option in a <command>redirect</command> router.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: Header lines added to the address (or specified for removal) by
+this router or by previous routers affect the <quote>unseen</quote> copy of the message
+only. The clone that continues to be processed by further routers starts with
+no added headers and none specified for removal. For a <option>redirect</option> router, if
+a generated address is the same as the incoming address, this can lead to
+duplicate addresses with different header modifications. Exim does not do
+duplicate deliveries (except, in certain circumstances, to pipes -- see section
+<xref linkend="SECTdupaddr"/>), but it is undefined which of the duplicates is discarded,
+so this ambiguous situation should be avoided. The <option>repeat_use</option> option of the
+<option>redirect</option> router may be of help.
+</para>
+<para>
+Unlike the handling of header modifications, any data that was set by the
+<option>address_data</option> option in the current or previous routers <emphasis>is</emphasis> passed on to
+subsequent routers.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>user</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>user</option></entry>
+<entry>Use: <emphasis>routers</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>uid (user id)</primary>
+<secondary>local delivery</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local transports</primary>
+<secondary>uid and gid</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>local</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>user for filter processing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>user for processing</secondary>
+</indexterm>
+When a router queues an address for a transport, and the transport does not
+specify a user, the user given here is used when running the delivery process.
+The user may be specified numerically or by name. If expansion fails, the
+error is logged and delivery is deferred.
+This user is also used by the <command>redirect</command> router when running a filter file.
+The default is unset, except when <option>check_local_user</option> is set. In this case,
+the default is taken from the password information. If the user is specified as
+a name, and <option>group</option> is not set, the group associated with the user is used.
+See also <option>initgroups</option> and <option>group</option> and the discussion in chapter
+<xref linkend="CHAPenvironment"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>verify</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>verify</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Setting this option has the effect of setting <option>verify_sender</option> and
+<option>verify_recipient</option> to the same value.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>verify_only</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>verify_only</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>EXPN</primary>
+<secondary>with <option>verify_only</option></secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-bv</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>router</primary>
+<secondary>used only when verifying</secondary>
+</indexterm>
+If this option is set, the router is used only when verifying an address,
+delivering in cutthrough mode or
+testing with the <option>-bv</option> option, not when actually doing a delivery, testing
+with the <option>-bt</option> option, or running the SMTP EXPN command. It can be further
+restricted to verifying only senders or recipients by means of
+<option>verify_sender</option> and <option>verify_recipient</option>.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: When the router is being run to verify addresses for an incoming
+SMTP message, Exim is not running as root, but under its own uid. If the router
+accesses any files, you need to make sure that they are accessible to the Exim
+user or group.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>verify_recipient</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>verify_recipient</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is false, the router is skipped when verifying recipient
+addresses,
+delivering in cutthrough mode
+or testing recipient verification using <option>-bv</option>.
+See section <xref linkend="SECTrouprecon"/> for a list of the order in which preconditions
+are evaluated.
+See also the <varname>$verify_mode</varname> variable.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>verify_sender</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>verify_sender</option></entry>
+<entry>Use: <emphasis>routers</emphasis>‡<emphasis></emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is false, the router is skipped when verifying sender addresses
+or testing sender verification using <option>-bvs</option>.
+See section <xref linkend="SECTrouprecon"/> for a list of the order in which preconditions
+are evaluated.
+See also the <varname>$verify_mode</varname> variable.
+<indexterm role="concept" startref="IIDgenoprou1" class="endofrange"/>
+<indexterm role="concept" startref="IIDgenoprou2" class="endofrange"/>
+</para>
+</chapter>
+
+<chapter id="CHID4">
+<title>The accept router</title>
+<para>
+<indexterm role="concept">
+<primary><command>accept</command> router</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>routers</primary>
+<secondary><command>accept</command></secondary>
+</indexterm>
+The <command>accept</command> router has no private options of its own. Unless it is being
+used purely for verification (see <option>verify_only</option>) a transport is required to
+be defined by the generic <option>transport</option> option. If the preconditions that are
+specified by generic options are met, the router accepts the address and queues
+it for the given transport. The most common use of this router is for setting
+up deliveries to local mailboxes. For example:
+</para>
+<literallayout class="monospaced">
+localusers:
+ driver = accept
+ domains = mydomain.example
+ check_local_user
+ transport = local_delivery
+</literallayout>
+<para>
+The <option>domains</option> condition in this example checks the domain of the address, and
+<option>check_local_user</option> checks that the local part is the login of a local user.
+When both preconditions are met, the <command>accept</command> router runs, and queues the
+address for the <command>local_delivery</command> transport.
+</para>
+</chapter>
+
+<chapter id="CHAPdnslookup">
+<title>The dnslookup router</title>
+<para>
+<indexterm role="concept" id="IIDdnsrou1" class="startofrange">
+<primary><command>dnslookup</command> router</primary>
+</indexterm>
+<indexterm role="concept" id="IIDdnsrou2" class="startofrange">
+<primary>routers</primary>
+<secondary><command>dnslookup</command></secondary>
+</indexterm>
+The <command>dnslookup</command> router looks up the hosts that handle mail for the
+recipient’s domain in the DNS. A transport must always be set for this router,
+unless <option>verify_only</option> is set.
+</para>
+<para>
+If SRV support is configured (see <option>check_srv</option> below), Exim first searches for
+SRV records. If none are found, or if SRV support is not configured,
+MX records are looked up. If no MX records exist, address records are sought.
+However, <option>mx_domains</option> can be set to disable the direct use of address
+records.
+</para>
+<para>
+MX records of equal priority are sorted by Exim into a random order. Exim then
+looks for address records for the host names obtained from MX or SRV records.
+When a host has more than one IP address, they are sorted into a random order,
+except that IPv6 addresses are sorted before IPv4 addresses. If all the
+IP addresses found are discarded by a setting of the <option>ignore_target_hosts</option>
+generic option, the router declines.
+</para>
+<para>
+Unless they have the highest priority (lowest MX value), MX records that point
+to the local host, or to any host name that matches <option>hosts_treat_as_local</option>,
+are discarded, together with any other MX records of equal or lower priority.
+</para>
+<para>
+<indexterm role="concept">
+<primary>MX record</primary>
+<secondary>pointing to local host</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local host</primary>
+<secondary>MX pointing to</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>self</option></primary>
+<secondary>in <command>dnslookup</command> router</secondary>
+</indexterm>
+If the host pointed to by the highest priority MX record, or looked up as an
+address record, is the local host, or matches <option>hosts_treat_as_local</option>, what
+happens is controlled by the generic <option>self</option> option.
+</para>
+<section id="SECTprowitdnsloo">
+<title>Problems with DNS lookups</title>
+<para>
+There have been problems with DNS servers when SRV records are looked up.
+Some misbehaving servers return a DNS error or timeout when a non-existent
+SRV record is sought. Similar problems have in the past been reported for
+MX records. The global <option>dns_again_means_nonexist</option> option can help with this
+problem, but it is heavy-handed because it is a global option.
+</para>
+<para>
+For this reason, there are two options, <option>srv_fail_domains</option> and
+<option>mx_fail_domains</option>, that control what happens when a DNS lookup in a
+<command>dnslookup</command> router results in a DNS failure or a <quote>try again</quote> response. If
+an attempt to look up an SRV or MX record causes one of these results, and the
+domain matches the relevant list, Exim behaves as if the DNS had responded <quote>no
+such record</quote>. In the case of an SRV lookup, this means that the router
+proceeds to look for MX records; in the case of an MX lookup, it proceeds to
+look for A or AAAA records, unless the domain matches <option>mx_domains</option>, in which
+case routing fails.
+</para>
+</section>
+<section id="SECTdnslookupdecline">
+<title>Declining addresses by dnslookup</title>
+<para>
+<indexterm role="concept">
+<primary><command>dnslookup</command> router</primary>
+<secondary>declines</secondary>
+</indexterm>
+There are a few cases where a <command>dnslookup</command> router will decline to accept
+an address; if such a router is expected to handle "all remaining non-local
+domains", then it is important to set <option>no_more</option>.
+</para>
+<para>
+The router will defer rather than decline if the domain
+is found in the <option>fail_defer_domains</option> router option.
+</para>
+<para>
+Reasons for a <command>dnslookup</command> router to decline currently include:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The domain does not exist in DNS
+</para>
+</listitem>
+<listitem>
+<para>
+The domain exists but the MX record’s host part is just "."; this is a common
+convention (borrowed from SRV) used to indicate that there is no such service
+for this domain and to not fall back to trying A/AAAA records.
+</para>
+</listitem>
+<listitem>
+<para>
+Ditto, but for SRV records, when <option>check_srv</option> is set on this router.
+</para>
+</listitem>
+<listitem>
+<para>
+MX record points to a non-existent host.
+</para>
+</listitem>
+<listitem>
+<para>
+MX record points to an IP address and the main section option
+<option>allow_mx_to_ip</option> is not set.
+</para>
+</listitem>
+<listitem>
+<para>
+MX records exist and point to valid hosts, but all hosts resolve only to
+addresses blocked by the <option>ignore_target_hosts</option> generic option on this router.
+</para>
+</listitem>
+<listitem>
+<para>
+The domain is not syntactically valid (see also <option>allow_utf8_domains</option> and
+<option>dns_check_names_pattern</option> for handling one variant of this)
+</para>
+</listitem>
+<listitem>
+<para>
+<option>check_secondary_mx</option> is set on this router but the local host can
+not be found in the MX records (see below)
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID118">
+<title>Private options for dnslookup</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>dnslookup</command> router</secondary>
+</indexterm>
+The private options for the <command>dnslookup</command> router are as follows:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_secondary_mx</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_secondary_mx</option></entry>
+<entry>Use: <emphasis>dnslookup</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>MX record</primary>
+<secondary>checking for secondary</secondary>
+</indexterm>
+If this option is set, the router declines unless the local host is found in
+(and removed from) the list of hosts obtained by MX lookup. This can be used to
+process domains for which the local host is a secondary mail exchanger
+differently to other domains. The way in which Exim decides whether a host is
+the local host is described in section <xref linkend="SECTreclocipadd"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_srv</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_srv</option></entry>
+<entry>Use: <emphasis>dnslookup</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SRV record</primary>
+<secondary>enabling use of</secondary>
+</indexterm>
+The <command>dnslookup</command> router supports the use of SRV records (see RFC 2782) in
+addition to MX and address records. The support is disabled by default. To
+enable SRV support, set the <option>check_srv</option> option to the name of the service
+required. For example,
+</para>
+<literallayout class="monospaced">
+check_srv = smtp
+</literallayout>
+<para>
+looks for SRV records that refer to the normal smtp service. The option is
+expanded, so the service name can vary from message to message or address
+to address. This might be helpful if SRV records are being used for a
+submission service. If the expansion is forced to fail, the <option>check_srv</option>
+option is ignored, and the router proceeds to look for MX records in the
+normal way.
+</para>
+<para>
+When the expansion succeeds, the router searches first for SRV records for
+the given service (it assumes TCP protocol). A single SRV record with a
+host name that consists of just a single dot indicates <quote>no such service for
+this domain</quote>; if this is encountered, the router declines. If other kinds of
+SRV record are found, they are used to construct a host list for delivery
+according to the rules of RFC 2782. MX records are not sought in this case.
+</para>
+<para>
+When no SRV records are found, MX records (and address records) are sought in
+the traditional way. In other words, SRV records take precedence over MX
+records, just as MX records take precedence over address records. Note that
+this behaviour is not sanctioned by RFC 2782, though a previous draft RFC
+defined it. It is apparently believed that MX records are sufficient for email
+and that SRV records should not be used for this purpose. However, SRV records
+have an additional <quote>weight</quote> feature which some people might find useful when
+trying to split an SMTP load between hosts of different power.
+</para>
+<para>
+See section <xref linkend="SECTprowitdnsloo"/> above for a discussion of Exim’s behaviour
+when there is a DNS lookup error.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>fail_defer_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>fail_defer_domains</option></entry>
+<entry>Use: <emphasis>dnslookup</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>MX record</primary>
+<secondary>not found</secondary>
+</indexterm>
+DNS lookups for domains matching <option>fail_defer_domains</option>
+which find no matching record will cause the router to defer
+rather than the default behaviour of decline.
+This maybe be useful for queueing messages for a newly created
+domain while the DNS configuration is not ready.
+However, it will result in any message with mistyped domains
+also being queued.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ipv4_only</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ipv4_only</option></entry>
+<entry>Use: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Type: <emphasis>unset</emphasis></entry>
+<entry>Default: <emphasis></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>IPv6</primary>
+<secondary>disabling</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>IPv6 disabling</secondary>
+</indexterm>
+The string is expanded, and if the result is anything but a forced failure,
+or an empty string, or one of the strings “0” or “no” or “false”
+(checked without regard to the case of the letters),
+only A records are used.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ipv4_prefer</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ipv4_prefer</option></entry>
+<entry>Use: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Type: <emphasis>unset</emphasis></entry>
+<entry>Default: <emphasis></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>IPv4</primary>
+<secondary>preference</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>IPv4 preference</secondary>
+</indexterm>
+The string is expanded, and if the result is anything but a forced failure,
+or an empty string, or one of the strings “0” or “no” or “false”
+(checked without regard to the case of the letters),
+A records are sorted before AAAA records (inverting the default).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mx_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>mx_domains</option></entry>
+<entry>Use: <emphasis>dnslookup</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>MX record</primary>
+<secondary>required to exist</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SRV record</primary>
+<secondary>required to exist</secondary>
+</indexterm>
+A domain that matches <option>mx_domains</option> is required to have either an MX or an SRV
+record in order to be recognized. (The name of this option could be improved.)
+For example, if all the mail hosts in <emphasis>fict.example</emphasis> are known to have MX
+records, except for those in <emphasis>discworld.fict.example</emphasis>, you could use this
+setting:
+</para>
+<literallayout class="monospaced">
+mx_domains = ! *.discworld.fict.example : *.fict.example
+</literallayout>
+<para>
+This specifies that messages addressed to a domain that matches the list but
+has no MX record should be bounced immediately instead of being routed using
+the address record.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mx_fail_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>mx_fail_domains</option></entry>
+<entry>Use: <emphasis>dnslookup</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If the DNS lookup for MX records for one of the domains in this list causes a
+DNS lookup error, Exim behaves as if no MX records were found. See section
+<xref linkend="SECTprowitdnsloo"/> for more discussion.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>qualify_single</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>qualify_single</option></entry>
+<entry>Use: <emphasis>dnslookup</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>resolver options</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>qualifying single-component names</secondary>
+</indexterm>
+When this option is true, the resolver option RES_DEFNAMES is set for DNS
+lookups. Typically, but not standardly, this causes the resolver to qualify
+single-component names with the default domain. For example, on a machine
+called <emphasis>dictionary.ref.example</emphasis>, the domain <emphasis>thesaurus</emphasis> would be changed to
+<emphasis>thesaurus.ref.example</emphasis> inside the resolver. For details of what your
+resolver actually does, consult your man pages for <emphasis>resolver</emphasis> and
+<emphasis>resolv.conf</emphasis>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>rewrite_headers</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>rewrite_headers</option></entry>
+<entry>Use: <emphasis>dnslookup</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>header lines</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>rewriting</secondary>
+</indexterm>
+If the domain name in the address that is being processed is not fully
+qualified, it may be expanded to its full form by a DNS lookup. For example, if
+an address is specified as <emphasis>dormouse@teaparty</emphasis>, the domain might be
+expanded to <emphasis>teaparty.wonderland.fict.example</emphasis>. Domain expansion can also
+occur as a result of setting the <option>widen_domains</option> option. If
+<option>rewrite_headers</option> is true, all occurrences of the abbreviated domain name in
+any <emphasis>Bcc:</emphasis>, <emphasis>Cc:</emphasis>, <emphasis>From:</emphasis>, <emphasis>Reply-to:</emphasis>, <emphasis>Sender:</emphasis>, and <emphasis>To:</emphasis>
+header lines of the message are rewritten with the full domain name.
+</para>
+<para>
+This option should be turned off only when it is known that no message is
+ever going to be sent outside an environment where the abbreviation makes
+sense.
+</para>
+<para>
+When an MX record is looked up in the DNS and matches a wildcard record, name
+servers normally return a record containing the name that has been looked up,
+making it impossible to detect whether a wildcard was present or not. However,
+some name servers have recently been seen to return the wildcard entry. If the
+name returned by a DNS lookup begins with an asterisk, it is not used for
+header rewriting.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>same_domain_copy_routing</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>same_domain_copy_routing</option></entry>
+<entry>Use: <emphasis>dnslookup</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>address</primary>
+<secondary>copying routing</secondary>
+</indexterm>
+Addresses with the same domain are normally routed by the <command>dnslookup</command> router
+to the same list of hosts. However, this cannot be presumed, because the router
+options and preconditions may refer to the local part of the address. By
+default, therefore, Exim routes each address in a message independently. DNS
+servers run caches, so repeated DNS lookups are not normally expensive, and in
+any case, personal messages rarely have more than a few recipients.
+</para>
+<para>
+If you are running mailing lists with large numbers of subscribers at the same
+domain, and you are using a <command>dnslookup</command> router which is independent of the
+local part, you can set <option>same_domain_copy_routing</option> to bypass repeated DNS
+lookups for identical domains in one message. In this case, when <command>dnslookup</command>
+routes an address to a remote transport, any other unrouted addresses in the
+message that have the same domain are automatically given the same routing
+without processing them independently,
+provided the following conditions are met:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+No router that processed the address specified <option>headers_add</option> or
+<option>headers_remove</option>.
+</para>
+</listitem>
+<listitem>
+<para>
+The router did not change the address in any way, for example, by <quote>widening</quote>
+the domain.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+<indexterm role="option">
+<primary><option>search_parents</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>search_parents</option></entry>
+<entry>Use: <emphasis>dnslookup</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>resolver options</secondary>
+</indexterm>
+When this option is true, the resolver option RES_DNSRCH is set for DNS
+lookups. This is different from the <option>qualify_single</option> option in that it
+applies to domains containing dots. Typically, but not standardly, it causes
+the resolver to search for the name in the current domain and in parent
+domains. For example, on a machine in the <emphasis>fict.example</emphasis> domain, if looking
+up <emphasis>teaparty.wonderland</emphasis> failed, the resolver would try
+<emphasis>teaparty.wonderland.fict.example</emphasis>. For details of what your resolver
+actually does, consult your man pages for <emphasis>resolver</emphasis> and <emphasis>resolv.conf</emphasis>.
+</para>
+<para>
+Setting this option true can cause problems in domains that have a wildcard MX
+record, because any domain that does not have its own MX record matches the
+local wildcard.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>srv_fail_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>srv_fail_domains</option></entry>
+<entry>Use: <emphasis>dnslookup</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If the DNS lookup for SRV records for one of the domains in this list causes a
+DNS lookup error, Exim behaves as if no SRV records were found. See section
+<xref linkend="SECTprowitdnsloo"/> for more discussion.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>widen_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>widen_domains</option></entry>
+<entry>Use: <emphasis>dnslookup</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>domain</primary>
+<secondary>partial; widening</secondary>
+</indexterm>
+If a DNS lookup fails and this option is set, each of its strings in turn is
+added onto the end of the domain, and the lookup is tried again. For example,
+if
+</para>
+<literallayout class="monospaced">
+widen_domains = fict.example:ref.example
+</literallayout>
+<para>
+is set and a lookup of <emphasis>klingon.dictionary</emphasis> fails,
+<emphasis>klingon.dictionary.fict.example</emphasis> is looked up, and if this fails,
+<emphasis>klingon.dictionary.ref.example</emphasis> is tried. Note that the <option>qualify_single</option>
+and <option>search_parents</option> options can cause some widening to be undertaken inside
+the DNS resolver. <option>widen_domains</option> is not applied to sender addresses
+when verifying, unless <option>rewrite_headers</option> is false (not the default).
+</para>
+</section>
+<section id="SECID119">
+<title>Effect of qualify_single and search_parents</title>
+<para>
+When a domain from an envelope recipient is changed by the resolver as a result
+of the <option>qualify_single</option> or <option>search_parents</option> options, Exim rewrites the
+corresponding address in the message’s header lines unless <option>rewrite_headers</option>
+is set false. Exim then re-routes the address, using the full domain.
+</para>
+<para>
+These two options affect only the DNS lookup that takes place inside the router
+for the domain of the address that is being routed. They do not affect lookups
+such as that implied by
+</para>
+<literallayout class="monospaced">
+domains = @mx_any
+</literallayout>
+<para>
+that may happen while processing a router precondition before the router is
+entered. No widening ever takes place for these lookups.
+<indexterm role="concept" startref="IIDdnsrou1" class="endofrange"/>
+<indexterm role="concept" startref="IIDdnsrou2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHID5">
+<title>The ipliteral router</title>
+<para>
+<indexterm role="concept">
+<primary><command>ipliteral</command> router</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain literal</primary>
+<secondary>routing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>routers</primary>
+<secondary><command>ipliteral</command></secondary>
+</indexterm>
+This router has no private options. Unless it is being used purely for
+verification (see <option>verify_only</option>) a transport is required to be defined by the
+generic <option>transport</option> option. The router accepts the address if its domain part
+takes the form of an RFC 2822 domain literal. For example, the <command>ipliteral</command>
+router handles the address
+</para>
+<literallayout class="monospaced">
+root@[192.168.1.1]
+</literallayout>
+<para>
+by setting up delivery to the host with that IP address. IPv4 domain literals
+consist of an IPv4 address enclosed in square brackets. IPv6 domain literals
+are similar, but the address is preceded by <literal>ipv6:</literal>. For example:
+</para>
+<literallayout class="monospaced">
+postmaster@[ipv6:fe80::a00:20ff:fe86:a061.5678]
+</literallayout>
+<para>
+Exim allows <literal>ipv4:</literal> before IPv4 addresses, for consistency, and on the
+grounds that sooner or later somebody will try it.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>self</option></primary>
+<secondary>in <command>ipliteral</command> router</secondary>
+</indexterm>
+If the IP address matches something in <option>ignore_target_hosts</option>, the router
+declines. If an IP literal turns out to refer to the local host, the generic
+<option>self</option> option determines what happens.
+</para>
+<para>
+The RFCs require support for domain literals; however, their use is
+controversial in today’s Internet. If you want to use this router, you must
+also set the main configuration option <option>allow_domain_literals</option>. Otherwise,
+Exim will not recognize the domain literal syntax in addresses.
+</para>
+</chapter>
+
+<chapter id="CHID6">
+<title>The iplookup router</title>
+<para>
+<indexterm role="concept">
+<primary><command>iplookup</command> router</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>routers</primary>
+<secondary><command>iplookup</command></secondary>
+</indexterm>
+The <command>iplookup</command> router was written to fulfil a specific requirement in
+Cambridge University (which in fact no longer exists). For this reason, it is
+not included in the binary of Exim by default. If you want to include it, you
+must set
+</para>
+<literallayout class="monospaced">
+ROUTER_IPLOOKUP=yes
+</literallayout>
+<para>
+in your <filename>Local/Makefile</filename> configuration file.
+</para>
+<para>
+The <command>iplookup</command> router routes an address by sending it over a TCP or UDP
+connection to one or more specific hosts. The host can then return the same or
+a different address – in effect rewriting the recipient address in the
+message’s envelope. The new address is then passed on to subsequent routers. If
+this process fails, the address can be passed on to other routers, or delivery
+can be deferred. Since <command>iplookup</command> is just a rewriting router, a transport
+must not be specified for it.
+</para>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>iplookup</command> router</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts</option></entry>
+<entry>Use: <emphasis>iplookup</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option must be supplied. Its value is a colon-separated list of host
+names. The hosts are looked up using <function>gethostbyname()</function>
+(or <function>getipnodebyname()</function> when available)
+and are tried in order until one responds to the query. If none respond, what
+happens is controlled by <option>optional</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>optional</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>optional</option></entry>
+<entry>Use: <emphasis>iplookup</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If <option>optional</option> is true, if no response is obtained from any host, the address
+is passed to the next router, overriding <option>no_more</option>. If <option>optional</option> is false,
+delivery to the address is deferred.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>port</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>port</option></entry>
+<entry>Use: <emphasis>iplookup</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>0</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>port</primary>
+<secondary><command>iplookup</command> router</secondary>
+</indexterm>
+This option must be supplied. It specifies the port number for the TCP or UDP
+call.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>protocol</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>protocol</option></entry>
+<entry>Use: <emphasis>iplookup</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>udp</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option can be set to <quote>udp</quote> or <quote>tcp</quote> to specify which of the two
+protocols is to be used.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>query</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>query</option></entry>
+<entry>Use: <emphasis>iplookup</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This defines the content of the query that is sent to the remote hosts. The
+default value is:
+</para>
+<literallayout class="monospaced">
+$local_part@$domain $local_part@$domain
+</literallayout>
+<para>
+The repetition serves as a way of checking that a response is to the correct
+query in the default case (see <option>response_pattern</option> below).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>reroute</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>reroute</option></entry>
+<entry>Use: <emphasis>iplookup</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is not set, the rerouted address is precisely the byte string
+returned by the remote host, up to the first white space, if any. If set, the
+string is expanded to form the rerouted address. It can include parts matched
+in the response by <option>response_pattern</option> by means of numeric variables such as
+<varname>$1</varname>, <varname>$2</varname>, etc. The variable <varname>$0</varname> refers to the entire input string,
+whether or not a pattern is in use. In all cases, the rerouted address must end
+up in the form <emphasis>local_part@domain</emphasis>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>response_pattern</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>response_pattern</option></entry>
+<entry>Use: <emphasis>iplookup</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option can be set to a regular expression that is applied to the string
+returned from the remote host. If the pattern does not match the response, the
+router declines. If <option>response_pattern</option> is not set, no checking of the
+response is done, unless the query was defaulted, in which case there is a
+check that the text returned after the first white space is the original
+address. This checks that the answer that has been received is in response to
+the correct question. For example, if the response is just a new domain, the
+following could be used:
+</para>
+<literallayout class="monospaced">
+response_pattern = ^([^@]+)$
+reroute = $local_part@$1
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>timeout</option></entry>
+<entry>Use: <emphasis>iplookup</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>5s</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies the amount of time to wait for a response from the remote
+machine. The same timeout is used for the <function>connect()</function> function for a TCP
+call. It does not apply to UDP.
+</para>
+</chapter>
+
+<chapter id="CHID7">
+<title>The manualroute router</title>
+<para>
+<indexterm role="concept" id="IIDmanrou1" class="startofrange">
+<primary><command>manualroute</command> router</primary>
+</indexterm>
+<indexterm role="concept" id="IIDmanrou2" class="startofrange">
+<primary>routers</primary>
+<secondary><command>manualroute</command></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain</primary>
+<secondary>manually routing</secondary>
+</indexterm>
+The <command>manualroute</command> router is so-called because it provides a way of manually
+routing an address according to its domain. It is mainly used when you want to
+route addresses to remote hosts according to your own rules, bypassing the
+normal DNS routing that looks up MX records. However, <command>manualroute</command> can also
+route to local transports, a facility that may be useful if you want to save
+messages for dial-in hosts in local files.
+</para>
+<para>
+The <command>manualroute</command> router compares a list of domain patterns with the domain
+it is trying to route. If there is no match, the router declines. Each pattern
+has associated with it a list of hosts and some other optional data, which may
+include a transport. The combination of a pattern and its data is called a
+<quote>routing rule</quote>. For patterns that do not have an associated transport, the
+generic <option>transport</option> option must specify a transport, unless the router is
+being used purely for verification (see <option>verify_only</option>).
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+In the case of verification, matching the domain pattern is sufficient for the
+router to accept the address. When actually routing an address for delivery,
+an address that matches a domain pattern is queued for the associated
+transport. If the transport is not a local one, a host list must be associated
+with the pattern; IP addresses are looked up for the hosts, and these are
+passed to the transport along with the mail address. For local transports, a
+host list is optional. If it is present, it is passed in <varname>$host</varname> as a single
+text string.
+</para>
+<para>
+The list of routing rules can be provided as an inline string in
+<option>route_list</option>, or the data can be obtained by looking up the domain in a file
+or database by setting <option>route_data</option>. Only one of these settings may appear in
+any one instance of <command>manualroute</command>. The format of routing rules is described
+below, following the list of private options.
+</para>
+<section id="SECTprioptman">
+<title>Private options for manualroute</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>manualroute</command> router</secondary>
+</indexterm>
+The private options for the <command>manualroute</command> router are as follows:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>host_all_ignored</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>host_all_ignored</option></entry>
+<entry>Use: <emphasis>manualroute</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>defer</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>host_find_failed</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>host_find_failed</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>host_find_failed</option></entry>
+<entry>Use: <emphasis>manualroute</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>freeze</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option controls what happens when <command>manualroute</command> tries to find an IP
+address for a host, and the host does not exist. The option can be set to one
+of the following values:
+</para>
+<literallayout class="monospaced">
+decline
+defer
+fail
+freeze
+ignore
+pass
+</literallayout>
+<para>
+The default (<quote>freeze</quote>) assumes that this state is a serious configuration
+error. The difference between <quote>pass</quote> and <quote>decline</quote> is that the former
+forces the address to be passed to the next router (or the router defined by
+<option>pass_router</option>),
+<indexterm role="option">
+<primary><option>more</option></primary>
+</indexterm>
+overriding <option>no_more</option>, whereas the latter passes the address to the next
+router only if <option>more</option> is true.
+</para>
+<para>
+The value <quote>ignore</quote> causes Exim to completely ignore a host whose IP address
+cannot be found. If all the hosts in the list are ignored, the behaviour is
+controlled by the <option>host_all_ignored</option> option. This takes the same values
+as <option>host_find_failed</option>, except that it cannot be set to <quote>ignore</quote>.
+</para>
+<para>
+The <option>host_find_failed</option> option applies only to a definite <quote>does not exist</quote>
+state; if a host lookup gets a temporary error, delivery is deferred unless the
+generic <option>pass_on_timeout</option> option is set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_randomize</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_randomize</option></entry>
+<entry>Use: <emphasis>manualroute</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>randomized host list</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>list of; randomized</secondary>
+</indexterm>
+If this option is set, the order of the items in a host list in a routing rule
+is randomized each time the list is used, unless an option in the routing rule
+overrides (see below). Randomizing the order of a host list can be used to do
+crude load sharing. However, if more than one mail address is routed by the
+same router to the same host list, the host lists are considered to be the same
+(even though they may be randomized into different orders) for the purpose of
+deciding whether to batch the deliveries into a single SMTP transaction.
+</para>
+<para>
+When <option>hosts_randomize</option> is true, a host list may be split
+into groups whose order is separately randomized. This makes it possible to
+set up MX-like behaviour. The boundaries between groups are indicated by an
+item that is just <literal>+</literal> in the host list. For example:
+</para>
+<literallayout class="monospaced">
+route_list = * host1:host2:host3:+:host4:host5
+</literallayout>
+<para>
+The order of the first three hosts and the order of the last two hosts is
+randomized for each use, but the first three always end up before the last two.
+If <option>hosts_randomize</option> is not set, a <literal>+</literal> item in the list is ignored. If a
+randomized host list is passed to an <command>smtp</command> transport that also has
+<option>hosts_randomize set</option>, the list is not re-randomized.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>route_data</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>route_data</option></entry>
+<entry>Use: <emphasis>manualroute</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is set, it must expand to yield the data part of a routing rule.
+Typically, the expansion string includes a lookup based on the domain. For
+example:
+</para>
+<literallayout class="monospaced">
+route_data = ${lookup{$domain}dbm{/etc/routes}}
+</literallayout>
+<para>
+If the expansion is forced to fail, or the result is an empty string, the
+router declines. Other kinds of expansion failure cause delivery to be
+deferred.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>route_list</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>route_list</option></entry>
+<entry>Use: <emphasis>manualroute</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This string is a list of routing rules, in the form defined below. Note that,
+unlike most string lists, the items are separated by semicolons. This is so
+that they may contain colon-separated host lists.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>same_domain_copy_routing</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>same_domain_copy_routing</option></entry>
+<entry>Use: <emphasis>manualroute</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>address</primary>
+<secondary>copying routing</secondary>
+</indexterm>
+Addresses with the same domain are normally routed by the <command>manualroute</command>
+router to the same list of hosts. However, this cannot be presumed, because the
+router options and preconditions may refer to the local part of the address. By
+default, therefore, Exim routes each address in a message independently. DNS
+servers run caches, so repeated DNS lookups are not normally expensive, and in
+any case, personal messages rarely have more than a few recipients.
+</para>
+<para>
+If you are running mailing lists with large numbers of subscribers at the same
+domain, and you are using a <command>manualroute</command> router which is independent of the
+local part, you can set <option>same_domain_copy_routing</option> to bypass repeated DNS
+lookups for identical domains in one message. In this case, when
+<command>manualroute</command> routes an address to a remote transport, any other unrouted
+addresses in the message that have the same domain are automatically given the
+same routing without processing them independently. However, this is only done
+if <option>headers_add</option> and <option>headers_remove</option> are unset.
+</para>
+</section>
+<section id="SECID120">
+<title>Routing rules in route_list</title>
+<para>
+The value of <option>route_list</option> is a string consisting of a sequence of routing
+rules, separated by semicolons. If a semicolon is needed in a rule, it can be
+entered as two semicolons. Alternatively, the list separator can be changed as
+described (for colon-separated lists) in section <xref linkend="SECTlistconstruct"/>.
+Empty rules are ignored. The format of each rule is
+</para>
+<literallayout>
+<<emphasis>domain pattern</emphasis>> <<emphasis>list of hosts</emphasis>> <<emphasis>options</emphasis>>
+</literallayout>
+<para>
+The following example contains two rules, each with a simple domain pattern and
+no options:
+</para>
+<literallayout class="monospaced">
+route_list = \
+ dict.ref.example mail-1.ref.example:mail-2.ref.example ; \
+ thes.ref.example mail-3.ref.example:mail-4.ref.example
+</literallayout>
+<para>
+The three parts of a rule are separated by white space. The pattern and the
+list of hosts can be enclosed in quotes if necessary, and if they are, the
+usual quoting rules apply. Each rule in a <option>route_list</option> must start with a
+single domain pattern, which is the only mandatory item in the rule. The
+pattern is in the same format as one item in a domain list (see section
+<xref linkend="SECTdomainlist"/>),
+except that it may not be the name of an interpolated file.
+That is, it may be wildcarded, or a regular expression, or a file or database
+lookup (with semicolons doubled, because of the use of semicolon as a separator
+in a <option>route_list</option>).
+</para>
+<para>
+The rules in <option>route_list</option> are searched in order until one of the patterns
+matches the domain that is being routed. The list of hosts and then options are
+then used as described below. If there is no match, the router declines. When
+<option>route_list</option> is set, <option>route_data</option> must not be set.
+</para>
+</section>
+<section id="SECID121">
+<title>Routing rules in route_data</title>
+<para>
+The use of <option>route_list</option> is convenient when there are only a small number of
+routing rules. For larger numbers, it is easier to use a file or database to
+hold the routing information, and use the <option>route_data</option> option instead.
+The value of <option>route_data</option> is a list of hosts, followed by (optional) options.
+Most commonly, <option>route_data</option> is set as a string that contains an
+expansion lookup. For example, suppose we place two routing rules in a file
+like this:
+</para>
+<literallayout class="monospaced">
+dict.ref.example: mail-1.ref.example:mail-2.ref.example
+thes.ref.example: mail-3.ref.example:mail-4.ref.example
+</literallayout>
+<para>
+This data can be accessed by setting
+</para>
+<literallayout class="monospaced">
+route_data = ${lookup{$domain}lsearch{/the/file/name}}
+</literallayout>
+<para>
+Failure of the lookup results in an empty string, causing the router to
+decline. However, you do not have to use a lookup in <option>route_data</option>. The only
+requirement is that the result of expanding the string is a list of hosts,
+possibly followed by options, separated by white space. The list of hosts must
+be enclosed in quotes if it contains white space.
+</para>
+</section>
+<section id="SECID122">
+<title>Format of the list of hosts</title>
+<para>
+A list of hosts, whether obtained via <option>route_data</option> or <option>route_list</option>, is
+always separately expanded before use. If the expansion fails, the router
+declines. The result of the expansion must be a colon-separated list of names
+and/or IP addresses, optionally also including ports.
+If the list is written with spaces, it must be protected with quotes.
+The format of each item
+in the list is described in the next section. The list separator can be changed
+as described in section <xref linkend="SECTlistsepchange"/>.
+</para>
+<para>
+If the list of hosts was obtained from a <option>route_list</option> item, the following
+variables are set during its expansion:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>numerical variables (<varname>$1</varname> <varname>$2</varname> etc)</primary>
+<secondary>in <command>manualroute</command> router</secondary>
+</indexterm>
+If the domain was matched against a regular expression, the numeric variables
+<varname>$1</varname>, <varname>$2</varname>, etc. may be set. For example:
+</para>
+<literallayout class="monospaced">
+route_list = ^domain(\d+) host-$1.text.example
+</literallayout>
+</listitem>
+<listitem>
+<para>
+<varname>$0</varname> is always set to the entire domain.
+</para>
+</listitem>
+<listitem>
+<para>
+<varname>$1</varname> is also set when partial matching is done in a file lookup.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$value</varname></primary>
+</indexterm>
+If the pattern that matched the domain was a lookup item, the data that was
+looked up is available in the expansion variable <varname>$value</varname>. For example:
+</para>
+<literallayout class="monospaced">
+route_list = lsearch;;/some/file.routes $value
+</literallayout>
+</listitem>
+</itemizedlist>
+<para>
+Note the doubling of the semicolon in the pattern that is necessary because
+semicolon is the default route list separator.
+</para>
+</section>
+<section id="SECTformatonehostitem">
+<title>Format of one host item</title>
+<para>
+Each item in the list of hosts can be either a host name or an IP address,
+optionally with an attached port number, or it can be a single "+"
+(see <option>hosts_randomize</option>).
+When no port is given, an IP address
+is not enclosed in brackets. When a port is specified, it overrides the port
+specification on the transport. The port is separated from the name or address
+by a colon. This leads to some complications:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Because colon is the default separator for the list of hosts, either
+the colon that specifies a port must be doubled, or the list separator must
+be changed. The following two examples have the same effect:
+</para>
+<literallayout class="monospaced">
+route_list = * "host1.tld::1225 : host2.tld::1226"
+route_list = * "<+ host1.tld:1225 + host2.tld:1226"
+</literallayout>
+</listitem>
+<listitem>
+<para>
+When IPv6 addresses are involved, it gets worse, because they contain
+colons of their own. To make this case easier, it is permitted to
+enclose an IP address (either v4 or v6) in square brackets if a port
+number follows. For example:
+</para>
+<literallayout class="monospaced">
+route_list = * "</ [10.1.1.1]:1225 / [::1]:1226"
+</literallayout>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECThostshowused">
+<title>How the list of hosts is used</title>
+<para>
+When an address is routed to an <command>smtp</command> transport by <command>manualroute</command>, each of
+the hosts is tried, in the order specified, when carrying out the SMTP
+delivery. However, the order can be changed by setting the <option>hosts_randomize</option>
+option, either on the router (see section <xref linkend="SECTprioptman"/> above), or on the
+transport.
+</para>
+<para>
+Hosts may be listed by name or by IP address. An unadorned name in the list of
+hosts is interpreted as a host name. A name that is followed by <literal>/MX</literal> is
+interpreted as an indirection to a sublist of hosts obtained by looking up MX
+records in the DNS. For example:
+</para>
+<literallayout class="monospaced">
+route_list = * x.y.z:p.q.r/MX:e.f.g
+</literallayout>
+<para>
+If this feature is used with a port specifier, the port must come last. For
+example:
+</para>
+<literallayout class="monospaced">
+route_list = * dom1.tld/mx::1225
+</literallayout>
+<para>
+If the <option>hosts_randomize</option> option is set, the order of the items in the list is
+randomized before any lookups are done. Exim then scans the list; for any name
+that is not followed by <literal>/MX</literal> it looks up an IP address. If this turns out to
+be an interface on the local host and the item is not the first in the list,
+Exim discards it and any subsequent items. If it is the first item, what
+happens is controlled by the
+<indexterm role="option">
+<primary><option>self</option></primary>
+<secondary>in <command>manualroute</command> router</secondary>
+</indexterm>
+<option>self</option> option of the router.
+</para>
+<para>
+A name on the list that is followed by <literal>/MX</literal> is replaced with the list of
+hosts obtained by looking up MX records for the name. This is always a DNS
+lookup; the <option>bydns</option> and <option>byname</option> options (see section <xref linkend="SECThowoptused"/>
+below) are not relevant here. The order of these hosts is determined by the
+preference values in the MX records, according to the usual rules. Because
+randomizing happens before the MX lookup, it does not affect the order that is
+defined by MX preferences.
+</para>
+<para>
+If the local host is present in the sublist obtained from MX records, but is
+not the most preferred host in that list, it and any equally or less
+preferred hosts are removed before the sublist is inserted into the main list.
+</para>
+<para>
+If the local host is the most preferred host in the MX list, what happens
+depends on where in the original list of hosts the <literal>/MX</literal> item appears. If it
+is not the first item (that is, there are previous hosts in the main list),
+Exim discards this name and any subsequent items in the main list.
+</para>
+<para>
+If the MX item is first in the list of hosts, and the local host is the
+most preferred host, what happens is controlled by the <option>self</option> option of the
+router.
+</para>
+<para>
+DNS failures when lookup up the MX records are treated in the same way as DNS
+failures when looking up IP addresses: <option>pass_on_timeout</option> and
+<option>host_find_failed</option> are used when relevant.
+</para>
+<para>
+The generic <option>ignore_target_hosts</option> option applies to all hosts in the list,
+whether obtained from an MX lookup or not.
+</para>
+</section>
+<section id="SECThowoptused">
+<title>How the options are used</title>
+<para>
+The options are a sequence of words, space-separated.
+One of the words can be the name of a transport; this overrides the
+<option>transport</option> option on the router for this particular routing rule only. The
+other words (if present) control randomization of the list of hosts on a
+per-rule basis, and how the IP addresses of the hosts are to be found when
+routing to a remote transport. These options are as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<option>randomize</option>: randomize the order of the hosts in this list, overriding the
+setting of <option>hosts_randomize</option> for this routing rule only.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>no_randomize</option>: do not randomize the order of the hosts in this list,
+overriding the setting of <option>hosts_randomize</option> for this routing rule only.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>byname</option>: use <function>getipnodebyname()</function> (<function>gethostbyname()</function> on older systems) to
+find IP addresses. This function may ultimately cause a DNS lookup, but it may
+also look in <filename>/etc/hosts</filename> or other sources of information.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>bydns</option>: look up address records for the hosts directly in the DNS; fail if
+no address records are found. If there is a temporary DNS error (such as a
+timeout), delivery is deferred.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>ipv4_only</option>: in direct DNS lookups, look up only A records.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>ipv4_prefer</option>: in direct DNS lookups, sort A records before AAAA records.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+For example:
+</para>
+<literallayout class="monospaced">
+route_list = domain1 host1:host2:host3 randomize bydns;\
+ domain2 host4:host5
+</literallayout>
+<para>
+If neither <option>byname</option> nor <option>bydns</option> is given, Exim behaves as follows: First, a
+DNS lookup is done. If this yields anything other than HOST_NOT_FOUND, that
+result is used. Otherwise, Exim goes on to try a call to <function>getipnodebyname()</function>
+or <function>gethostbyname()</function>, and the result of the lookup is the result of that
+call.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: It has been discovered that on some systems, if a DNS lookup
+called via <function>getipnodebyname()</function> times out, HOST_NOT_FOUND is returned
+instead of TRY_AGAIN. That is why the default action is to try a DNS
+lookup first. Only if that gives a definite <quote>no such host</quote> is the local
+function called.
+</para>
+<para>
+<emphasis role="bold">Compatibility</emphasis>: From Exim 4.85 until fixed for 4.90, there was an
+inadvertent constraint that a transport name as an option had to be the last
+option specified.
+</para>
+<para>
+If no IP address for a host can be found, what happens is controlled by the
+<option>host_find_failed</option> option.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+When an address is routed to a local transport, IP addresses are not looked up.
+The host list is passed to the transport in the <varname>$host</varname> variable.
+</para>
+</section>
+<section id="SECID123">
+<title>Manualroute examples</title>
+<para>
+In some of the examples that follow, the presence of the <option>remote_smtp</option>
+transport, as defined in the default configuration file, is assumed:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>smart host</primary>
+<secondary>example router</secondary>
+</indexterm>
+The <command>manualroute</command> router can be used to forward all external mail to a
+<emphasis>smart host</emphasis>. If you have set up, in the main part of the configuration, a
+named domain list that contains your local domains, for example:
+</para>
+<literallayout class="monospaced">
+domainlist local_domains = my.domain.example
+</literallayout>
+<para>
+You can arrange for all other domains to be routed to a smart host by making
+your first router something like this:
+</para>
+<literallayout class="monospaced">
+smart_route:
+ driver = manualroute
+ domains = !+local_domains
+ transport = remote_smtp
+ route_list = * smarthost.ref.example
+</literallayout>
+<para>
+This causes all non-local addresses to be sent to the single host
+<emphasis>smarthost.ref.example</emphasis>. If a colon-separated list of smart hosts is given,
+they are tried in order
+(but you can use <option>hosts_randomize</option> to vary the order each time).
+Another way of configuring the same thing is this:
+</para>
+<literallayout class="monospaced">
+smart_route:
+ driver = manualroute
+ transport = remote_smtp
+ route_list = !+local_domains smarthost.ref.example
+</literallayout>
+<para>
+There is no difference in behaviour between these two routers as they stand.
+However, they behave differently if <option>no_more</option> is added to them. In the first
+example, the router is skipped if the domain does not match the <option>domains</option>
+precondition; the following router is always tried. If the router runs, it
+always matches the domain and so can never decline. Therefore, <option>no_more</option>
+would have no effect. In the second case, the router is never skipped; it
+always runs. However, if it doesn’t match the domain, it declines. In this case
+<option>no_more</option> would prevent subsequent routers from running.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>mail hub example</primary>
+</indexterm>
+A <emphasis>mail hub</emphasis> is a host which receives mail for a number of domains via MX
+records in the DNS and delivers it via its own private routing mechanism. Often
+the final destinations are behind a firewall, with the mail hub being the one
+machine that can connect to machines both inside and outside the firewall. The
+<command>manualroute</command> router is usually used on a mail hub to route incoming messages
+to the correct hosts. For a small number of domains, the routing can be inline,
+using the <option>route_list</option> option, but for a larger number a file or database
+lookup is easier to manage.
+</para>
+<para>
+If the domain names are in fact the names of the machines to which the mail is
+to be sent by the mail hub, the configuration can be quite simple. For
+example:
+</para>
+<literallayout class="monospaced">
+hub_route:
+ driver = manualroute
+ transport = remote_smtp
+ route_list = *.rhodes.tvs.example $domain
+</literallayout>
+<para>
+This configuration routes domains that match <literal>*.rhodes.tvs.example</literal> to hosts
+whose names are the same as the mail domains. A similar approach can be taken
+if the host name can be obtained from the domain name by a string manipulation
+that the expansion facilities can handle. Otherwise, a lookup based on the
+domain can be used to find the host:
+</para>
+<literallayout class="monospaced">
+through_firewall:
+ driver = manualroute
+ transport = remote_smtp
+ route_data = ${lookup {$domain} cdb {/internal/host/routes}}
+</literallayout>
+<para>
+The result of the lookup must be the name or IP address of the host (or
+hosts) to which the address is to be routed. If the lookup fails, the route
+data is empty, causing the router to decline. The address then passes to the
+next router.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>batched SMTP output example</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>batched outgoing; example</secondary>
+</indexterm>
+You can use <command>manualroute</command> to deliver messages to pipes or files in batched
+SMTP format for onward transportation by some other means. This is one way of
+storing mail for a dial-up host when it is not connected. The route list entry
+can be as simple as a single domain name in a configuration like this:
+</para>
+<literallayout class="monospaced">
+save_in_file:
+ driver = manualroute
+ transport = batchsmtp_appendfile
+ route_list = saved.domain.example
+</literallayout>
+<para>
+though often a pattern is used to pick up more than one domain. If there are
+several domains or groups of domains with different transport requirements,
+different transports can be listed in the routing information:
+</para>
+<literallayout class="monospaced">
+save_in_file:
+ driver = manualroute
+ route_list = \
+ *.saved.domain1.example $domain batch_appendfile; \
+ *.saved.domain2.example \
+ ${lookup{$domain}dbm{/domain2/hosts}{$value}fail} \
+ batch_pipe
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+The first of these just passes the domain in the <varname>$host</varname> variable, which
+doesn’t achieve much (since it is also in <varname>$domain</varname>), but the second does a
+file lookup to find a value to pass, causing the router to decline to handle
+the address if the lookup fails.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>UUCP</primary>
+<secondary>example of router for</secondary>
+</indexterm>
+Routing mail directly to UUCP software is a specific case of the use of
+<command>manualroute</command> in a gateway to another mail environment. This is an example of
+one way it can be done:
+</para>
+<literallayout class="monospaced">
+# Transport
+uucp:
+ driver = pipe
+ user = nobody
+ command = /usr/local/bin/uux -r - \
+ ${substr_-5:$host}!rmail ${local_part}
+ return_fail_output = true
+
+# Router
+uucphost:
+ transport = uucp
+ driver = manualroute
+ route_data = \
+ ${lookup{$domain}lsearch{/usr/local/exim/uucphosts}}
+</literallayout>
+<para>
+The file <filename>/usr/local/exim/uucphosts</filename> contains entries like
+</para>
+<literallayout class="monospaced">
+darksite.ethereal.example: darksite.UUCP
+</literallayout>
+<para>
+It can be set up more simply without adding and removing <quote>.UUCP</quote> but this way
+makes clear the distinction between the domain name
+<emphasis>darksite.ethereal.example</emphasis> and the UUCP host name <emphasis>darksite</emphasis>.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+<indexterm role="concept" startref="IIDmanrou1" class="endofrange"/>
+<indexterm role="concept" startref="IIDmanrou2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPdriverlast">
+<title>The queryprogram router</title>
+<para>
+<indexterm role="concept" id="IIDquerou1" class="startofrange">
+<primary><command>queryprogram</command> router</primary>
+</indexterm>
+<indexterm role="concept" id="IIDquerou2" class="startofrange">
+<primary>routers</primary>
+<secondary><command>queryprogram</command></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>routing</primary>
+<secondary>by external program</secondary>
+</indexterm>
+The <command>queryprogram</command> router routes an address by running an external command
+and acting on its output. This is an expensive way to route, and is intended
+mainly for use in lightly-loaded systems, or for performing experiments.
+However, if it is possible to use the precondition options (<option>domains</option>,
+<option>local_parts</option>, etc) to skip this router for most addresses, it could sensibly
+be used in special cases, even on a busy host. There are the following private
+options:
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>queryprogram</command> router</secondary>
+</indexterm>
+</para>
+<para>
+<indexterm role="option">
+<primary><option>command</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>command</option></entry>
+<entry>Use: <emphasis>queryprogram</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option must be set. It specifies the command that is to be run. The
+command is split up into a command name and arguments, and then each is
+expanded separately (exactly as for a <command>pipe</command> transport, described in chapter
+<xref linkend="CHAPpipetransport"/>).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>command_group</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>command_group</option></entry>
+<entry>Use: <emphasis>queryprogram</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>gid (group id)</primary>
+<secondary>in <command>queryprogram</command> router</secondary>
+</indexterm>
+This option specifies a gid to be set when running the command while routing an
+address for deliver. It must be set if <option>command_user</option> specifies a numerical
+uid. If it begins with a digit, it is interpreted as the numerical value of the
+gid. Otherwise it is looked up using <function>getgrnam()</function>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>command_user</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>command_user</option></entry>
+<entry>Use: <emphasis>queryprogram</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>uid (user id)</primary>
+<secondary>for <command>queryprogram</command></secondary>
+</indexterm>
+This option must be set. It specifies the uid which is set when running the
+command while routing an address for delivery. If the value begins with a digit,
+it is interpreted as the numerical value of the uid. Otherwise, it is looked up
+using <function>getpwnam()</function> to obtain a value for the uid and, if <option>command_group</option> is
+not set, a value for the gid also.
+</para>
+<para>
+<emphasis role="bold">Warning:</emphasis> Changing uid and gid is possible only when Exim is running as
+root, which it does during a normal delivery in a conventional configuration.
+However, when an address is being verified during message reception, Exim is
+usually running as the Exim user, not as root. If the <command>queryprogram</command> router
+is called from a non-root process, Exim cannot change uid or gid before running
+the command. In this circumstance the command runs under the current uid and
+gid.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>current_directory</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>current_directory</option></entry>
+<entry>Use: <emphasis>queryprogram</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>/</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies an absolute path which is made the current directory
+before running the command.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>timeout</option></entry>
+<entry>Use: <emphasis>queryprogram</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>1h</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If the command does not complete within the timeout period, its process group
+is killed and the message is frozen. A value of zero time specifies no
+timeout.
+</para>
+<para>
+The standard output of the command is connected to a pipe, which is read when
+the command terminates. It should consist of a single line of output,
+containing up to five fields, separated by white space. The maximum length of
+the line is 1023 characters. Longer lines are silently truncated. The first
+field is one of the following words (case-insensitive):
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<emphasis>Accept</emphasis>: routing succeeded; the remaining fields specify what to do (see
+below).
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>Decline</emphasis>: the router declines; pass the address to the next router, unless
+<option>no_more</option> is set.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>Fail</emphasis>: routing failed; do not pass the address to any more routers. Any
+subsequent text on the line is an error message. If the router is run as part
+of address verification during an incoming SMTP message, the message is
+included in the SMTP response.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>Defer</emphasis>: routing could not be completed at this time; try again later. Any
+subsequent text on the line is an error message which is logged. It is not
+included in any SMTP response.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>Freeze</emphasis>: the same as <emphasis>defer</emphasis>, except that the message is frozen.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>Pass</emphasis>: pass the address to the next router (or the router specified by
+<option>pass_router</option>), overriding <option>no_more</option>.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>Redirect</emphasis>: the message is redirected. The remainder of the line is a list of
+new addresses, which are routed independently, starting with the first router,
+or the router specified by <option>redirect_router</option>, if set.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+When the first word is <emphasis>accept</emphasis>, the remainder of the line consists of a
+number of keyed data values, as follows (split into two lines here, to fit on
+the page):
+</para>
+<literallayout class="monospaced">
+ACCEPT TRANSPORT=<transport> HOSTS=<list of hosts>
+LOOKUP=byname|bydns DATA=<text>
+</literallayout>
+<para>
+The data items can be given in any order, and all are optional. If no transport
+is included, the transport specified by the generic <option>transport</option> option is
+used. The list of hosts and the lookup type are needed only if the transport is
+an <command>smtp</command> transport that does not itself supply a list of hosts.
+</para>
+<para>
+The format of the list of hosts is the same as for the <command>manualroute</command> router.
+As well as host names and IP addresses with optional port numbers, as described
+in section <xref linkend="SECTformatonehostitem"/>, it may contain names followed by
+<literal>/MX</literal> to specify sublists of hosts that are obtained by looking up MX records
+(see section <xref linkend="SECThostshowused"/>).
+</para>
+<para>
+If the lookup type is not specified, Exim behaves as follows when trying to
+find an IP address for each host: First, a DNS lookup is done. If this yields
+anything other than HOST_NOT_FOUND, that result is used. Otherwise, Exim
+goes on to try a call to <function>getipnodebyname()</function> or <function>gethostbyname()</function>, and the
+result of the lookup is the result of that call.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$address_data</varname></primary>
+</indexterm>
+If the DATA field is set, its value is placed in the <varname>$address_data</varname>
+variable. For example, this return line
+</para>
+<literallayout class="monospaced">
+accept hosts=x1.y.example:x2.y.example data="rule1"
+</literallayout>
+<para>
+routes the address to the default transport, passing a list of two hosts. When
+the transport runs, the string <quote>rule1</quote> is in <varname>$address_data</varname>.
+<indexterm role="concept" startref="IIDquerou1" class="endofrange"/>
+<indexterm role="concept" startref="IIDquerou2" class="endofrange"/>
+</para>
+</chapter>
+
+<chapter id="CHAPredirect">
+<title>The redirect router</title>
+<para>
+<indexterm role="concept" id="IIDredrou1" class="startofrange">
+<primary><command>redirect</command> router</primary>
+</indexterm>
+<indexterm role="concept" id="IIDredrou2" class="startofrange">
+<primary>routers</primary>
+<secondary><command>redirect</command></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>alias file</primary>
+<secondary>in a <command>redirect</command> router</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary><command>redirect</command> router</secondary>
+</indexterm>
+The <command>redirect</command> router handles several kinds of address redirection. Its most
+common uses are for resolving local part aliases from a central alias file
+(usually called <filename>/etc/aliases</filename>) and for handling users’ personal <filename>.forward</filename>
+files, but it has many other potential uses. The incoming address can be
+redirected in several different ways:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+It can be replaced by one or more new addresses which are themselves routed
+independently.
+</para>
+</listitem>
+<listitem>
+<para>
+It can be routed to be delivered to a given file or directory.
+</para>
+</listitem>
+<listitem>
+<para>
+It can be routed to be delivered to a specified pipe command.
+</para>
+</listitem>
+<listitem>
+<para>
+It can cause an automatic reply to be generated.
+</para>
+</listitem>
+<listitem>
+<para>
+It can be forced to fail, optionally with a custom error message.
+</para>
+</listitem>
+<listitem>
+<para>
+It can be temporarily deferred, optionally with a custom message.
+</para>
+</listitem>
+<listitem>
+<para>
+It can be discarded.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The generic <option>transport</option> option must not be set for <command>redirect</command> routers.
+However, there are some private options which define transports for delivery to
+files and pipes, and for generating autoreplies. See the <option>file_transport</option>,
+<option>pipe_transport</option> and <option>reply_transport</option> descriptions below.
+</para>
+<para>
+If success DSNs have been requested
+<indexterm role="concept">
+<primary>DSN</primary>
+<secondary>success</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Delivery Status Notification</primary>
+<secondary>success</secondary>
+</indexterm>
+redirection triggers one and the DSN options are not passed any further.
+</para>
+<section id="SECID124">
+<title>Redirection data</title>
+<para>
+The router operates by interpreting a text string which it obtains either by
+expanding the contents of the <option>data</option> option, or by reading the entire
+contents of a file whose name is given in the <option>file</option> option. These two
+options are mutually exclusive. The first is commonly used for handling system
+aliases, in a configuration like this:
+</para>
+<literallayout class="monospaced">
+system_aliases:
+ driver = redirect
+ data = ${lookup{$local_part}lsearch{/etc/aliases}}
+</literallayout>
+<para>
+If the lookup fails, the expanded string in this example is empty. When the
+expansion of <option>data</option> results in an empty string, the router declines. A forced
+expansion failure also causes the router to decline; other expansion failures
+cause delivery to be deferred.
+</para>
+<para>
+A configuration using <option>file</option> is commonly used for handling users’
+<filename>.forward</filename> files, like this:
+</para>
+<literallayout class="monospaced">
+userforward:
+ driver = redirect
+ check_local_user
+ file = $home/.forward
+ no_verify
+</literallayout>
+<para>
+If the file does not exist, or causes no action to be taken (for example, it is
+empty or consists only of comments), the router declines. <emphasis role="bold">Warning</emphasis>: This
+is not the case when the file contains syntactically valid items that happen to
+yield empty addresses, for example, items containing only RFC 2822 address
+comments.
+</para>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>tainted data</primary>
+<secondary>in filenames</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>redirect</primary>
+<secondary>tainted data</secondary>
+</indexterm>
+Tainted data may not be used for a filename.
+</para>
+<para revisionflag="changed">
+<emphasis role="bold">Warning</emphasis>: It is unwise to use <varname>$local_part</varname> or <varname>$domain</varname>
+directly for redirection,
+as they are provided by a potential attacker.
+In the examples above, <varname>$local_part</varname> is used for looking up data held locally
+on the system, and not used directly (the second example derives <varname>$home</varname> via
+the passsword file or database, using <varname>$local_part</varname>).
+</para>
+</section>
+<section id="SECID125">
+<title>Forward files and address verification</title>
+<para>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>while verifying</secondary>
+</indexterm>
+It is usual to set <option>no_verify</option> on <command>redirect</command> routers which handle users’
+<filename>.forward</filename> files, as in the example above. There are two reasons for this:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+When Exim is receiving an incoming SMTP message from a remote host, it is
+running under the Exim uid, not as root. Exim is unable to change uid to read
+the file as the user, and it may not be able to read it as the Exim user. So in
+practice the router may not be able to operate.
+</para>
+</listitem>
+<listitem>
+<para>
+However, even when the router can operate, the existence of a <filename>.forward</filename> file
+is unimportant when verifying an address. What should be checked is whether the
+local part is a valid user name or not. Cutting out the redirection processing
+saves some resources.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID126">
+<title>Interpreting redirection data</title>
+<para>
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary>specifying in redirection data</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>specifying in redirection data</secondary>
+</indexterm>
+The contents of the data string, whether obtained from <option>data</option> or <option>file</option>,
+can be interpreted in two different ways:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If the <option>allow_filter</option> option is set true, and the data begins with the text
+<quote>#Exim filter</quote> or <quote>#Sieve filter</quote>, it is interpreted as a list of
+<emphasis>filtering</emphasis> instructions in the form of an Exim or Sieve filter file,
+respectively. Details of the syntax and semantics of filter files are described
+in a separate document entitled <emphasis>Exim’s interfaces to mail filtering</emphasis>; this
+document is intended for use by end users.
+</para>
+</listitem>
+<listitem>
+<para>
+Otherwise, the data must be a comma-separated list of redirection items, as
+described in the next section.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+When a message is redirected to a file (a <quote>mail folder</quote>), the filename given
+in a non-filter redirection list must always be an absolute path. A filter may
+generate a relative path – how this is handled depends on the transport’s
+configuration. See section <xref linkend="SECTfildiropt"/> for a discussion of this issue
+for the <command>appendfile</command> transport.
+</para>
+</section>
+<section id="SECTitenonfilred">
+<title>Items in a non-filter redirection list</title>
+<para>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>non-filter list items</secondary>
+</indexterm>
+When the redirection data is not an Exim or Sieve filter, for example, if it
+comes from a conventional alias or forward file, it consists of a list of
+addresses, filenames, pipe commands, or certain special items (see section
+<xref linkend="SECTspecitredli"/> below). The special items can be individually enabled or
+disabled by means of options whose names begin with <option>allow_</option> or <option>forbid_</option>,
+depending on their default values. The items in the list are separated by
+commas or newlines.
+If a comma is required in an item, the entire item must be enclosed in double
+quotes.
+</para>
+<para>
+Lines starting with a # character are comments, and are ignored, and # may
+also appear following a comma, in which case everything between the # and the
+next newline character is ignored.
+</para>
+<para>
+If an item is entirely enclosed in double quotes, these are removed. Otherwise
+double quotes are retained because some forms of mail address require their use
+(but never to enclose the entire address). In the following description,
+<quote>item</quote> refers to what remains after any surrounding double quotes have been
+removed.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+<emphasis role="bold">Warning</emphasis>: If you use an Exim expansion to construct a redirection address,
+and the expansion contains a reference to <varname>$local_part</varname>, you should make use
+of the <option>quote_local_part</option> expansion operator, in case the local part contains
+special characters. For example, to redirect all mail for the domain
+<emphasis>obsolete.example</emphasis>, retaining the existing local part, you could use this
+setting:
+</para>
+<literallayout class="monospaced">
+data = ${quote_local_part:$local_part}@newdomain.example
+</literallayout>
+</section>
+<section id="SECTredlocmai">
+<title>Redirecting to a local mailbox</title>
+<para>
+<indexterm role="concept">
+<primary>routing</primary>
+<secondary>loops in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>loop</primary>
+<secondary>while routing, avoidance of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>to local mailbox</secondary>
+</indexterm>
+A redirection item may safely be the same as the address currently under
+consideration. This does not cause a routing loop, because a router is
+automatically skipped if any ancestor of the address that is being processed
+is the same as the current address and was processed by the current router.
+Such an address is therefore passed to the following routers, so it is handled
+as if there were no redirection. When making this loop-avoidance test, the
+complete local part, including any prefix or suffix, is used.
+</para>
+<para>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>local part without domain</secondary>
+</indexterm>
+Specifying the same local part without a domain is a common usage in personal
+filter files when the user wants to have messages delivered to the local
+mailbox and also forwarded elsewhere. For example, the user whose login is
+<emphasis>cleo</emphasis> might have a <filename>.forward</filename> file containing this:
+</para>
+<literallayout class="monospaced">
+cleo, cleopatra@egypt.example
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>backslash in alias file</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>alias file</primary>
+<secondary>backslash in</secondary>
+</indexterm>
+For compatibility with other MTAs, such unqualified local parts may be
+preceded by <quote>\</quote>, but this is not a requirement for loop prevention. However,
+it does make a difference if more than one domain is being handled
+synonymously.
+</para>
+<para>
+If an item begins with <quote>\</quote> and the rest of the item parses as a valid RFC
+2822 address that does not include a domain, the item is qualified using the
+domain of the incoming address. In the absence of a leading <quote>\</quote>, unqualified
+addresses are qualified using the value in <option>qualify_recipient</option>, but you can
+force the incoming domain to be used by setting <option>qualify_preserve_domain</option>.
+</para>
+<para>
+Care must be taken if there are alias names for local users.
+Consider an MTA handling a single local domain where the system alias file
+contains:
+</para>
+<literallayout class="monospaced">
+Sam.Reman: spqr
+</literallayout>
+<para>
+Now suppose that Sam (whose login id is <emphasis>spqr</emphasis>) wants to save copies of
+messages in the local mailbox, and also forward copies elsewhere. He creates
+this forward file:
+</para>
+<literallayout class="monospaced">
+Sam.Reman, spqr@reme.elsewhere.example
+</literallayout>
+<para>
+With these settings, an incoming message addressed to <emphasis>Sam.Reman</emphasis> fails. The
+<command>redirect</command> router for system aliases does not process <emphasis>Sam.Reman</emphasis> the
+second time round, because it has previously routed it,
+and the following routers presumably cannot handle the alias. The forward file
+should really contain
+</para>
+<literallayout class="monospaced">
+spqr, spqr@reme.elsewhere.example
+</literallayout>
+<para>
+but because this is such a common error, the <option>check_ancestor</option> option (see
+below) exists to provide a way to get round it. This is normally set on a
+<command>redirect</command> router that is handling users’ <filename>.forward</filename> files.
+</para>
+</section>
+<section id="SECTspecitredli">
+<title>Special items in redirection lists</title>
+<para>
+In addition to addresses, the following types of item may appear in redirection
+lists (that is, in non-filter redirection data):
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>pipe</primary>
+<secondary>in redirection list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>to pipe</secondary>
+</indexterm>
+An item is treated as a pipe command if it begins with <quote>|</quote> and does not parse
+as a valid RFC 2822 address that includes a domain. A transport for running the
+command must be specified by the <option>pipe_transport</option> option.
+Normally, either the router or the transport specifies a user and a group under
+which to run the delivery. The default is to use the Exim user and group.
+</para>
+<para>
+Single or double quotes can be used for enclosing the individual arguments of
+the pipe command; no interpretation of escapes is done for single quotes. If
+the command contains a comma character, it is necessary to put the whole item
+in double quotes, for example:
+</para>
+<literallayout class="monospaced">
+"|/some/command ready,steady,go"
+</literallayout>
+<para>
+since items in redirection lists are terminated by commas. Do not, however,
+quote just the command. An item such as
+</para>
+<literallayout class="monospaced">
+|"/some/command ready,steady,go"
+</literallayout>
+<para>
+is interpreted as a pipe with a rather strange command name, and no arguments.
+</para>
+<para>
+Note that the above example assumes that the text comes from a lookup source
+of some sort, so that the quotes are part of the data. If composing a
+redirect router with a <option>data</option> option directly specifying this command, the
+quotes will be used by the configuration parser to define the extent of one
+string, but will not be passed down into the redirect router itself. There
+are two main approaches to get around this: escape quotes to be part of the
+data itself, or avoid using this mechanism and instead create a custom
+transport with the <option>command</option> option set and reference that transport from
+an <option>accept</option> router.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>in redirection list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>to file</secondary>
+</indexterm>
+An item is interpreted as a path name if it begins with <quote>/</quote> and does not
+parse as a valid RFC 2822 address that includes a domain. For example,
+</para>
+<literallayout class="monospaced">
+/home/world/minbari
+</literallayout>
+<para>
+is treated as a filename, but
+</para>
+<literallayout class="monospaced">
+/s=molari/o=babylon/@x400gate.way
+</literallayout>
+<para>
+is treated as an address. For a filename, a transport must be specified using
+the <option>file_transport</option> option. However, if the generated path name ends with a
+forward slash character, it is interpreted as a directory name rather than a
+filename, and <option>directory_transport</option> is used instead.
+</para>
+<para>
+Normally, either the router or the transport specifies a user and a group under
+which to run the delivery. The default is to use the Exim user and group.
+</para>
+<para>
+<indexterm role="concept">
+<primary><filename>/dev/null</filename></primary>
+</indexterm>
+However, if a redirection item is the path <filename>/dev/null</filename>, delivery to it is
+bypassed at a high level, and the log entry shows <quote>**bypassed**</quote>
+instead of a transport name. In this case the user and group are not used.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>included address list</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>included external list</secondary>
+</indexterm>
+If an item is of the form
+</para>
+<literallayout class="monospaced">
+:include:<path name>
+</literallayout>
+<para>
+a list of further items is taken from the given file and included at that
+point. <emphasis role="bold">Note</emphasis>: Such a file can not be a filter file; it is just an
+out-of-line addition to the list. The items in the included list are separated
+by commas or newlines and are not subject to expansion. If this is the first
+item in an alias list in an <command>lsearch</command> file, a colon must be used to terminate
+the alias name. This example is incorrect:
+</para>
+<literallayout class="monospaced">
+list1 :include:/opt/lists/list1
+</literallayout>
+<para>
+It must be given as
+</para>
+<literallayout class="monospaced">
+list1: :include:/opt/lists/list1
+</literallayout>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>tainted data</primary>
+<secondary>in filenames</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>redirect</primary>
+<secondary>tainted data</secondary>
+</indexterm>
+Tainted data may not be used for a filename.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>to black hole</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>discard</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>blackhole</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>black hole</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>abandoning mail</primary>
+</indexterm>
+Sometimes you want to throw away mail to a particular local part. Making the
+<option>data</option> option expand to an empty string does not work, because that causes
+the router to decline. Instead, the alias item
+</para>
+<literallayout class="monospaced">
+:blackhole:
+</literallayout>
+<para>
+can be used. It does what its name implies. No delivery is
+done, and no error message is generated. This has the same effect as specifying
+<filename>/dev/null</filename> as a destination, but it can be independently disabled.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: If <emphasis>:blackhole:</emphasis> appears anywhere in a redirection list, no
+delivery is done for the original local part, even if other redirection items
+are present. If you are generating a multi-item list (for example, by reading a
+database) and need the ability to provide a no-op item, you must use
+<filename>/dev/null</filename>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>forcing failure</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>forcing deferral</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>failing delivery</primary>
+<secondary>forcing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>deferred delivery, forcing</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>customizing</primary>
+<secondary>failure message</secondary>
+</indexterm>
+An attempt to deliver a particular address can be deferred or forced to fail by
+redirection items of the form
+</para>
+<literallayout class="monospaced">
+:defer:
+:fail:
+</literallayout>
+<para>
+respectively. When a redirection list contains such an item, it applies
+to the entire redirection; any other items in the list are ignored. Any
+text following <emphasis>:fail:</emphasis> or <emphasis>:defer:</emphasis> is placed in the error text
+associated with the failure. For example, an alias file might contain:
+</para>
+<literallayout class="monospaced">
+X.Employee: :fail: Gone away, no forwarding address
+</literallayout>
+<para>
+In the case of an address that is being verified from an ACL or as the subject
+of a
+<indexterm role="concept">
+<primary>VRFY</primary>
+<secondary>error text, display of</secondary>
+</indexterm>
+VRFY command, the text is included in the SMTP error response by
+default.
+<indexterm role="concept">
+<primary>EXPN</primary>
+<secondary>error text, display of</secondary>
+</indexterm>
+The text is not included in the response to an EXPN command. In non-SMTP cases
+the text is included in the error message that Exim generates.
+</para>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>error codes</secondary>
+</indexterm>
+By default, Exim sends a 451 SMTP code for a <emphasis>:defer:</emphasis>, and 550 for
+<emphasis>:fail:</emphasis>. However, if the message starts with three digits followed by a
+space, optionally followed by an extended code of the form <emphasis>n.n.n</emphasis>, also
+followed by a space, and the very first digit is the same as the default error
+code, the code from the message is used instead. If the very first digit is
+incorrect, a panic error is logged, and the default code is used. You can
+suppress the use of the supplied code in a redirect router by setting the
+<option>forbid_smtp_code</option> option true. In this case, any SMTP code is quietly
+ignored.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$acl_verify_message</varname></primary>
+</indexterm>
+In an ACL, an explicitly provided message overrides the default, but the
+default message is available in the variable <varname>$acl_verify_message</varname> and can
+therefore be included in a custom message if this is desired.
+</para>
+<para>
+Normally the error text is the rest of the redirection list – a comma does
+not terminate it – but a newline does act as a terminator. Newlines are not
+normally present in alias expansions. In <command>lsearch</command> lookups they are removed
+as part of the continuation process, but they may exist in other kinds of
+lookup and in <emphasis>:include:</emphasis> files.
+</para>
+<para>
+During routing for message delivery (as opposed to verification), a redirection
+containing <emphasis>:fail:</emphasis> causes an immediate failure of the incoming address,
+whereas <emphasis>:defer:</emphasis> causes the message to remain in the queue so that a
+subsequent delivery attempt can happen at a later time. If an address is
+deferred for too long, it will ultimately fail, because the normal retry
+rules still apply.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>alias file</primary>
+<secondary>exception to default</secondary>
+</indexterm>
+Sometimes it is useful to use a single-key search type with a default (see
+chapter <xref linkend="CHAPfdlookup"/>) to look up aliases. However, there may be a need
+for exceptions to the default. These can be handled by aliasing them to
+<emphasis>:unknown:</emphasis>. This differs from <emphasis>:fail:</emphasis> in that it causes the <command>redirect</command>
+router to decline, whereas <emphasis>:fail:</emphasis> forces routing to fail. A lookup which
+results in an empty redirection list has the same effect.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECTdupaddr">
+<title>Duplicate addresses</title>
+<para>
+<indexterm role="concept">
+<primary>duplicate addresses</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>address duplicate, discarding</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>pipe</primary>
+<secondary>duplicated</secondary>
+</indexterm>
+Exim removes duplicate addresses from the list to which it is delivering, so as
+to deliver just one copy to each address. This does not apply to deliveries
+routed to pipes by different immediate parent addresses, but an indirect
+aliasing scheme of the type
+</para>
+<literallayout class="monospaced">
+pipe: |/some/command $local_part
+localpart1: pipe
+localpart2: pipe
+</literallayout>
+<para>
+does not work with a message that is addressed to both local parts, because
+when the second is aliased to the intermediate local part <quote>pipe</quote> it gets
+discarded as being the same as a previously handled address. However, a scheme
+such as
+</para>
+<literallayout class="monospaced">
+localpart1: |/some/command $local_part
+localpart2: |/some/command $local_part
+</literallayout>
+<para>
+does result in two different pipe deliveries, because the immediate parents of
+the pipes are distinct.
+</para>
+</section>
+<section id="SECID128">
+<title>Repeated redirection expansion</title>
+<para>
+<indexterm role="concept">
+<primary>repeated redirection expansion</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>repeated for each delivery attempt</secondary>
+</indexterm>
+When a message cannot be delivered to all of its recipients immediately,
+leading to two or more delivery attempts, redirection expansion is carried out
+afresh each time for those addresses whose children were not all previously
+delivered. If redirection is being used as a mailing list, this can lead to new
+members of the list receiving copies of old messages. The <option>one_time</option> option
+can be used to avoid this.
+</para>
+</section>
+<section id="SECID129">
+<title>Errors in redirection lists</title>
+<para>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>errors</secondary>
+</indexterm>
+If <option>skip_syntax_errors</option> is set, a malformed address that causes a parsing
+error is skipped, and an entry is written to the main log. This may be useful
+for mailing lists that are automatically managed. Otherwise, if an error is
+detected while generating the list of new addresses, the original address is
+deferred. See also <option>syntax_errors_to</option>.
+</para>
+</section>
+<section id="SECID130">
+<title>Private options for the redirect router</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>redirect</command> router</secondary>
+</indexterm>
+The private options for the <command>redirect</command> router are as follows:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>allow_defer</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>allow_defer</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Setting this option allows the use of <emphasis>:defer:</emphasis> in non-filter redirection
+data, or the <option>defer</option> command in an Exim filter file.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>allow_fail</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>allow_fail</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>failing delivery</primary>
+<secondary>from filter</secondary>
+</indexterm>
+If this option is true, the <emphasis>:fail:</emphasis> item can be used in a redirection list,
+and the <option>fail</option> command may be used in an Exim filter file.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>allow_filter</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>allow_filter</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>enabling use of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary>enabling use of</secondary>
+</indexterm>
+Setting this option allows Exim to interpret redirection data that starts with
+<quote>#Exim filter</quote> or <quote>#Sieve filter</quote> as a set of filtering instructions. There
+are some features of Exim filter files that some administrators may wish to
+lock out; see the <option>forbid_filter_</option><emphasis>xxx</emphasis> options below.
+</para>
+<para>
+It is also possible to lock out Exim filters or Sieve filters while allowing
+the other type; see <option>forbid_exim_filter</option> and <option>forbid_sieve_filter</option>.
+</para>
+<para>
+The filter is run using the uid and gid set by the generic <option>user</option> and
+<option>group</option> options. These take their defaults from the password data if
+<option>check_local_user</option> is set, so in the normal case of users’ personal filter
+files, the filter is run as the relevant user. When <option>allow_filter</option> is set
+true, Exim insists that either <option>check_local_user</option> or <option>user</option> is set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>allow_freeze</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>allow_freeze</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>freezing messages</primary>
+<secondary>allowing in filter</secondary>
+</indexterm>
+Setting this option allows the use of the <option>freeze</option> command in an Exim filter.
+This command is more normally encountered in system filters, and is disabled by
+default for redirection filters because it isn’t something you usually want to
+let ordinary users do.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_ancestor</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_ancestor</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option is concerned with handling generated addresses that are the same
+as some address in the list of redirection ancestors of the current address.
+Although it is turned off by default in the code, it is set in the default
+configuration file for handling users’ <filename>.forward</filename> files. It is recommended
+for this use of the <command>redirect</command> router.
+</para>
+<para>
+When <option>check_ancestor</option> is set, if a generated address (including the domain)
+is the same as any ancestor of the current address, it is replaced by a copy of
+the current address. This helps in the case where local part A is aliased to B,
+and B has a <filename>.forward</filename> file pointing back to A. For example, within a single
+domain, the local part <quote>Joe.Bloggs</quote> is aliased to <quote>jb</quote> and
+<filename> jb/.forward</filename> contains:
+</para>
+<literallayout class="monospaced">
+\Joe.Bloggs, <other item(s)>
+</literallayout>
+<para>
+Without the <option>check_ancestor</option> setting, either local part (<quote>jb</quote> or
+<quote>joe.bloggs</quote>) gets processed once by each router and so ends up as it was
+originally. If <quote>jb</quote> is the real mailbox name, mail to <quote>jb</quote> gets delivered
+(having been turned into <quote>joe.bloggs</quote> by the <filename>.forward</filename> file and back to
+<quote>jb</quote> by the alias), but mail to <quote>joe.bloggs</quote> fails. Setting
+<option>check_ancestor</option> on the <command>redirect</command> router that handles the <filename>.forward</filename>
+file prevents it from turning <quote>jb</quote> back into <quote>joe.bloggs</quote> when that was the
+original address. See also the <option>repeat_use</option> option below.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_group</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_group</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+When the <option>file</option> option is used, the group owner of the file is checked only
+when this option is set. The permitted groups are those listed in the
+<option>owngroups</option> option, together with the user’s default group if
+<option>check_local_user</option> is set. If the file has the wrong group, routing is
+deferred. The default setting for this option is true if <option>check_local_user</option>
+is set and the <option>modemask</option> option permits the group write bit, or if the
+<option>owngroups</option> option is set. Otherwise it is false, and no group check occurs.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_owner</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_owner</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+When the <option>file</option> option is used, the owner of the file is checked only when
+this option is set. If <option>check_local_user</option> is set, the local user is
+permitted; otherwise the owner must be one of those listed in the <option>owners</option>
+option. The default value for this option is true if <option>check_local_user</option> or
+<option>owners</option> is set. Otherwise the default is false, and no owner check occurs.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>data</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>data</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option is mutually exclusive with <option>file</option>. One or other of them must be
+set, but not both. The contents of <option>data</option> are expanded, and then used as the
+list of forwarding items, or as a set of filtering instructions. If the
+expansion is forced to fail, or the result is an empty string or a string that
+has no effect (consists entirely of comments), the router declines.
+</para>
+<para>
+When filtering instructions are used, the string must begin with <quote>#Exim
+filter</quote>, and all comments in the string, including this initial one, must be
+terminated with newline characters. For example:
+</para>
+<literallayout class="monospaced">
+data = #Exim filter\n\
+ if $h_to: contains Exim then save $home/mail/exim endif
+</literallayout>
+<para>
+If you are reading the data from a database where newlines cannot be included,
+you can use the <varname>${sg}</varname> expansion item to turn the escape string of your
+choice into a newline.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>directory_transport</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>directory_transport</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+A <command>redirect</command> router sets up a direct delivery to a directory when a path name
+ending with a slash is specified as a new <quote>address</quote>. The transport used is
+specified by this option, which, after expansion, must be the name of a
+configured transport. This should normally be an <command>appendfile</command> transport.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>file</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies the name of a file that contains the redirection data. It
+is mutually exclusive with the <option>data</option> option. The string is expanded before
+use; if the expansion is forced to fail, the router declines. Other expansion
+failures cause delivery to be deferred. The result of a successful expansion
+must be an absolute path. The entire file is read and used as the redirection
+data. If the data is an empty string or a string that has no effect (consists
+entirely of comments), the router declines.
+</para>
+<para>
+<indexterm role="concept">
+<primary>NFS</primary>
+<secondary>checking for file existence</secondary>
+</indexterm>
+If the attempt to open the file fails with a <quote>does not exist</quote> error, Exim
+runs a check on the containing directory,
+unless <option>ignore_enotdir</option> is true (see below).
+If the directory does not appear to exist, delivery is deferred. This can
+happen when users’ <filename>.forward</filename> files are in NFS-mounted directories, and there
+is a mount problem. If the containing directory does exist, but the file does
+not, the router declines.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>file_transport</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>file_transport</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="variable">
+<primary><varname>$address_file</varname></primary>
+</indexterm>
+A <command>redirect</command> router sets up a direct delivery to a file when a path name not
+ending in a slash is specified as a new <quote>address</quote>. The transport used is
+specified by this option, which, after expansion, must be the name of a
+configured transport. This should normally be an <command>appendfile</command> transport. When
+it is running, the filename is in <varname>$address_file</varname>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>filter_prepend_home</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>filter_prepend_home</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+When this option is true, if a <command>save</command> command in an Exim filter specifies a
+relative path, and <varname>$home</varname> is defined, it is automatically prepended to the
+relative path. If this option is set false, this action does not happen. The
+relative path is then passed to the transport unmodified.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_blackhole</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_blackhole</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+If this option is true, the <emphasis>:blackhole:</emphasis> item may not appear in a
+redirection list.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_exim_filter</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_exim_filter</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+If this option is set true, only Sieve filters are permitted when
+<option>allow_filter</option> is true.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_file</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>to file; forbidding</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary>forbidding delivery to a file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary><quote>keep</quote> facility; disabling</secondary>
+</indexterm>
+If this option is true, this router may not generate a new address that
+specifies delivery to a local file or directory, either from a filter or from a
+conventional forward file. This option is forced to be true if <option>one_time</option> is
+set. It applies to Sieve filters as well as to Exim filters, but if true, it
+locks out the Sieve’s <quote>keep</quote> facility.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_filter_dlfunc</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_filter_dlfunc</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+If this option is true, string expansions in Exim filters are not allowed to
+make use of the <option>dlfunc</option> expansion facility to run dynamically loaded
+functions.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_filter_existstest</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_filter_existstest</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>statting a file</secondary>
+</indexterm>
+If this option is true, string expansions in Exim filters are not allowed to
+make use of the <option>exists</option> condition or the <option>stat</option> expansion item.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_filter_logwrite</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_filter_logwrite</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+If this option is true, use of the logging facility in Exim filters is not
+permitted. Logging is in any case available only if the filter is being run
+under some unprivileged uid (which is normally the case for ordinary users’
+<filename>.forward</filename> files).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_filter_lookup</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_filter_lookup</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+If this option is true, string expansions in Exim filter files are not allowed
+to make use of <option>lookup</option> items.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_filter_perl</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_filter_perl</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+This option has an effect only if Exim is built with embedded Perl support. If
+it is true, string expansions in Exim filter files are not allowed to make use
+of the embedded Perl support.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_filter_readfile</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_filter_readfile</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+If this option is true, string expansions in Exim filter files are not allowed
+to make use of <option>readfile</option> items.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_filter_readsocket</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_filter_readsocket</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+If this option is true, string expansions in Exim filter files are not allowed
+to make use of <option>readsocket</option> items.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_filter_reply</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_filter_reply</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+If this option is true, this router may not generate an automatic reply
+message. Automatic replies can be generated only from Exim or Sieve filter
+files, not from traditional forward files. This option is forced to be true if
+<option>one_time</option> is set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_filter_run</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_filter_run</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+If this option is true, string expansions in Exim filter files are not allowed
+to make use of <option>run</option> items.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_include</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_include</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+If this option is true, items of the form
+</para>
+<literallayout class="monospaced">
+:include:<path name>
+</literallayout>
+<para>
+are not permitted in non-filter redirection lists.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_pipe</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_pipe</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>to pipe; forbidding</secondary>
+</indexterm>
+If this option is true, this router may not generate a new address which
+specifies delivery to a pipe, either from an Exim filter or from a conventional
+forward file. This option is forced to be true if <option>one_time</option> is set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>forbid_sieve_filter</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_sieve_filter</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>restricting access to features</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>locking out certain features</secondary>
+</indexterm>
+If this option is set true, only Exim filters are permitted when
+<option>allow_filter</option> is true.
+</para>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>error codes</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>forbid_smtp_code</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>forbid_smtp_code</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is set true, any SMTP error codes that are present at the start
+of messages specified for <literal>:defer:</literal> or <literal>:fail:</literal> are quietly ignored, and
+the default codes (451 and 550, respectively) are always used.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hide_child_in_errmsg</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hide_child_in_errmsg</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>redirection details; suppressing</secondary>
+</indexterm>
+If this option is true, it prevents Exim from quoting a child address if it
+generates a bounce or delay message for it. Instead it says <quote>an address
+generated from <<emphasis>the top level address</emphasis>></quote>. Of course, this applies only to
+bounces generated locally. If a message is forwarded to another host, <emphasis>its</emphasis>
+bounce may well quote the generated address.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ignore_eacces</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ignore_eacces</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>EACCES</primary>
+</indexterm>
+If this option is set and an attempt to open a redirection file yields the
+EACCES error (permission denied), the <command>redirect</command> router behaves as if the
+file did not exist.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ignore_enotdir</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ignore_enotdir</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>ENOTDIR</primary>
+</indexterm>
+If this option is set and an attempt to open a redirection file yields the
+ENOTDIR error (something on the path is not a directory), the <command>redirect</command>
+router behaves as if the file did not exist.
+</para>
+<para>
+Setting <option>ignore_enotdir</option> has another effect as well: When a <command>redirect</command>
+router that has the <option>file</option> option set discovers that the file does not exist
+(the ENOENT error), it tries to <function>stat()</function> the parent directory, as a check
+against unmounted NFS directories. If the parent can not be statted, delivery
+is deferred. However, it seems wrong to do this check when <option>ignore_enotdir</option>
+is set, because that option tells Exim to ignore <quote>something on the path is not
+a directory</quote> (the ENOTDIR error). This is a confusing area, because it seems
+that some operating systems give ENOENT where others give ENOTDIR.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>include_directory</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>include_directory</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is set, the path names of any <emphasis>:include:</emphasis> items in a
+redirection list must start with this directory.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>modemask</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>modemask</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>octal integer</emphasis></entry>
+<entry>Default: <emphasis>022</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies mode bits which must not be set for a file specified by the
+<option>file</option> option. If any of the forbidden bits are set, delivery is deferred.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>one_time</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>one_time</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>one-time aliasing/forwarding expansion</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>alias file</primary>
+<secondary>one-time expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>forward file</primary>
+<secondary>one-time expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>mailing lists</primary>
+<secondary>one-time expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>one-time expansion</secondary>
+</indexterm>
+Sometimes the fact that Exim re-evaluates aliases and reprocesses redirection
+files each time it tries to deliver a message causes a problem when one or more
+of the generated addresses fails be delivered at the first attempt. The problem
+is not one of duplicate delivery – Exim is clever enough to handle that –
+but of what happens when the redirection list changes during the time that the
+message is on Exim’s queue. This is particularly true in the case of mailing
+lists, where new subscribers might receive copies of messages that were posted
+before they subscribed.
+</para>
+<para>
+If <option>one_time</option> is set and any addresses generated by the router fail to
+deliver at the first attempt, the failing addresses are added to the message as
+<quote>top level</quote> addresses, and the parent address that generated them is marked
+<quote>delivered</quote>. Thus, redirection does not happen again at the next delivery
+attempt.
+</para>
+<para>
+<emphasis role="bold">Warning 1</emphasis>: Any header line addition or removal that is specified by this
+router would be lost if delivery did not succeed at the first attempt. For this
+reason, the <option>headers_add</option> and <option>headers_remove</option> generic options are not
+permitted when <option>one_time</option> is set.
+</para>
+<para>
+<emphasis role="bold">Warning 2</emphasis>: To ensure that the router generates only addresses (as opposed
+to pipe or file deliveries or auto-replies) <option>forbid_file</option>, <option>forbid_pipe</option>,
+and <option>forbid_filter_reply</option> are forced to be true when <option>one_time</option> is set.
+</para>
+<para>
+<emphasis role="bold">Warning 3</emphasis>: The <option>unseen</option> generic router option may not be set with
+<option>one_time</option>.
+</para>
+<para>
+The original top-level address is remembered with each of the generated
+addresses, and is output in any log messages. However, any intermediate parent
+addresses are not recorded. This makes a difference to the log only if
+<option>all_parents</option> log selector is set. It is expected that <option>one_time</option> will
+typically be used for mailing lists, where there is normally just one level of
+expansion.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>owners</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>owners</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>ownership</primary>
+<secondary>alias file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ownership</primary>
+<secondary>forward file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>alias file</primary>
+<secondary>ownership</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>forward file</primary>
+<secondary>ownership</secondary>
+</indexterm>
+This specifies a list of permitted owners for the file specified by <option>file</option>.
+This list is in addition to the local user when <option>check_local_user</option> is set.
+See <option>check_owner</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>owngroups</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>owngroups</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies a list of permitted groups for the file specified by <option>file</option>.
+The list is in addition to the local user’s primary group when
+<option>check_local_user</option> is set. See <option>check_group</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>pipe_transport</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>pipe_transport</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="variable">
+<primary><varname>$address_pipe</varname></primary>
+</indexterm>
+A <command>redirect</command> router sets up a direct delivery to a pipe when a string
+starting with a vertical bar character is specified as a new <quote>address</quote>. The
+transport used is specified by this option, which, after expansion, must be the
+name of a configured transport. This should normally be a <command>pipe</command> transport.
+When the transport is run, the pipe command is in <varname>$address_pipe</varname>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>qualify_domain</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>qualify_domain</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="variable">
+<primary><varname>$qualify_recipient</varname></primary>
+</indexterm>
+If this option is set, and an unqualified address (one without a domain) is
+generated, and that address would normally be qualified by the global setting
+in <option>qualify_recipient</option>, it is instead qualified with the domain specified by
+expanding this string. If the expansion fails, the router declines. If you want
+to revert to the default, you can have the expansion generate
+<varname>$qualify_recipient</varname>.
+</para>
+<para>
+This option applies to all unqualified addresses generated by Exim filters,
+but for traditional <filename>.forward</filename> files, it applies only to addresses that are
+not preceded by a backslash. Sieve filters cannot generate unqualified
+addresses.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>qualify_preserve_domain</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>qualify_preserve_domain</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>domain</primary>
+<secondary>in redirection; preserving</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>preserving domain in redirection</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>domain; preserving</secondary>
+</indexterm>
+If this option is set, the router’s local <option>qualify_domain</option> option must not be
+set (a configuration error occurs if it is). If an unqualified address (one
+without a domain) is generated, it is qualified with the domain of the parent
+address (the immediately preceding ancestor) instead of the global
+<option>qualify_recipient</option> value. In the case of a traditional <filename>.forward</filename> file,
+this applies whether or not the address is preceded by a backslash.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>repeat_use</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>repeat_use</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is set false, the router is skipped for a child address that has
+any ancestor that was routed by this router. This test happens before any of
+the other preconditions are tested. Exim’s default anti-looping rules skip
+only when the ancestor is the same as the current address. See also
+<option>check_ancestor</option> above and the generic <option>redirect_router</option> option.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>reply_transport</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>reply_transport</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+A <command>redirect</command> router sets up an automatic reply when a <option>mail</option> or
+<option>vacation</option> command is used in a filter file. The transport used is specified
+by this option, which, after expansion, must be the name of a configured
+transport. This should normally be an <command>autoreply</command> transport. Other transports
+are unlikely to do anything sensible or useful.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>rewrite</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>rewrite</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>disabling rewriting</secondary>
+</indexterm>
+If this option is set false, addresses generated by the router are not
+subject to address rewriting. Otherwise, they are treated like new addresses
+and are rewritten according to the global rewriting rules.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>sieve_subaddress</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>sieve_subaddress</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+The value of this option is passed to a Sieve filter to specify the
+:subaddress part of an address.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>sieve_useraddress</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>sieve_useraddress</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+The value of this option is passed to a Sieve filter to specify the :user part
+of an address. However, if it is unset, the entire original local part
+(including any prefix or suffix) is used for :user.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>sieve_vacation_directory</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>sieve_vacation_directory</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary>vacation directory</secondary>
+</indexterm>
+To enable the <quote>vacation</quote> extension for Sieve filters, you must set
+<option>sieve_vacation_directory</option> to the directory where vacation databases are held
+(do not put anything else in that directory), and ensure that the
+<option>reply_transport</option> option refers to an <command>autoreply</command> transport. Each user
+needs their own directory; Exim will create it if necessary.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>skip_syntax_errors</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>skip_syntax_errors</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>forward file</primary>
+<secondary>broken</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>broken files</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>alias file</primary>
+<secondary>broken</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>broken alias or forward files</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>ignoring faulty addresses</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>skipping faulty addresses</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>error</primary>
+<secondary>skipping bad syntax</secondary>
+</indexterm>
+If <option>skip_syntax_errors</option> is set, syntactically malformed addresses in
+non-filter redirection data are skipped, and each failing address is logged. If
+<option>syntax_errors_to</option> is set, a message is sent to the address it defines,
+giving details of the failures. If <option>syntax_errors_text</option> is set, its contents
+are expanded and placed at the head of the error message generated by
+<option>syntax_errors_to</option>. Usually it is appropriate to set <option>syntax_errors_to</option> to
+be the same address as the generic <option>errors_to</option> option. The
+<option>skip_syntax_errors</option> option is often used when handling mailing lists.
+</para>
+<para>
+If all the addresses in a redirection list are skipped because of syntax
+errors, the router declines to handle the original address, and it is passed to
+the following routers.
+</para>
+<para>
+If <option>skip_syntax_errors</option> is set when an Exim filter is interpreted, any syntax
+error in the filter causes filtering to be abandoned without any action being
+taken. The incident is logged, and the router declines to handle the address,
+so it is passed to the following routers.
+</para>
+<para>
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary>syntax errors in</secondary>
+</indexterm>
+Syntax errors in a Sieve filter file cause the <quote>keep</quote> action to occur. This
+action is specified by RFC 3028. The values of <option>skip_syntax_errors</option>,
+<option>syntax_errors_to</option>, and <option>syntax_errors_text</option> are not used.
+</para>
+<para>
+<option>skip_syntax_errors</option> can be used to specify that errors in users’ forward
+lists or filter files should not prevent delivery. The <option>syntax_errors_to</option>
+option, used with an address that does not get redirected, can be used to
+notify users of these errors, by means of a router like this:
+</para>
+<literallayout class="monospaced">
+userforward:
+ driver = redirect
+ allow_filter
+ check_local_user
+ file = $home/.forward
+ file_transport = address_file
+ pipe_transport = address_pipe
+ reply_transport = address_reply
+ no_verify
+ skip_syntax_errors
+ syntax_errors_to = real-$local_part@$domain
+ syntax_errors_text = \
+ This is an automatically generated message. An error has\n\
+ been found in your .forward file. Details of the error are\n\
+ reported below. While this error persists, you will receive\n\
+ a copy of this message for every message that is addressed\n\
+ to you. If your .forward file is a filter file, or if it is\n\
+ a non-filter file containing no valid forwarding addresses,\n\
+ a copy of each incoming message will be put in your normal\n\
+ mailbox. If a non-filter file contains at least one valid\n\
+ forwarding address, forwarding to the valid addresses will\n\
+ happen, and those will be the only deliveries that occur.
+</literallayout>
+<para>
+You also need a router to ensure that local addresses that are prefixed by
+<literal>real-</literal> are recognized, but not forwarded or filtered. For example, you could
+put this immediately before the <command>userforward</command> router:
+</para>
+<literallayout class="monospaced">
+real_localuser:
+ driver = accept
+ check_local_user
+ local_part_prefix = real-
+ transport = local_delivery
+</literallayout>
+<para>
+For security, it would probably be a good idea to restrict the use of this
+router to locally-generated messages, using a condition such as this:
+</para>
+<literallayout class="monospaced">
+ condition = ${if match {$sender_host_address}\
+ {\N^(|127\.0\.0\.1)$\N}}
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>syntax_errors_text</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>syntax_errors_text</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>skip_syntax_errors</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>syntax_errors_to</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>syntax_errors_to</option></entry>
+<entry>Use: <emphasis>redirect</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>skip_syntax_errors</option> above.
+<indexterm role="concept" startref="IIDredrou1" class="endofrange"/>
+<indexterm role="concept" startref="IIDredrou2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPenvironment">
+<title>Environment for running local transports</title>
+<titleabbrev>Environment for local transports</titleabbrev>
+<para>
+<indexterm role="concept" id="IIDenvlotra1" class="startofrange">
+<primary>local transports</primary>
+<secondary>environment for</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDenvlotra2" class="startofrange">
+<primary>environment</primary>
+<secondary>local transports</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDenvlotra3" class="startofrange">
+<primary>transport</primary>
+<secondary>local; environment for</secondary>
+</indexterm>
+Local transports handle deliveries to files and pipes. (The <command>autoreply</command>
+transport can be thought of as similar to a pipe.) Exim always runs transports
+in subprocesses, under specified uids and gids. Typical deliveries to local
+mailboxes run under the uid and gid of the local user.
+</para>
+<para>
+Exim also sets a specific current directory while running the transport; for
+some transports a home directory setting is also relevant. The <command>pipe</command>
+transport is the only one that sets up environment variables; see section
+<xref linkend="SECTpipeenv"/> for details.
+</para>
+<para>
+The values used for the uid, gid, and the directories may come from several
+different places. In many cases, the router that handles the address associates
+settings with that address as a result of its <option>check_local_user</option>, <option>group</option>,
+or <option>user</option> options. However, values may also be given in the transport’s own
+configuration, and these override anything that comes from the router.
+</para>
+<section id="SECID131">
+<title>Concurrent deliveries</title>
+<para>
+<indexterm role="concept">
+<primary>concurrent deliveries</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>simultaneous deliveries</primary>
+</indexterm>
+If two different messages for the same local recipient arrive more or less
+simultaneously, the two delivery processes are likely to run concurrently. When
+the <command>appendfile</command> transport is used to write to a file, Exim applies locking
+rules to stop concurrent processes from writing to the same file at the same
+time.
+</para>
+<para>
+However, when you use a <command>pipe</command> transport, it is up to you to arrange any
+locking that is needed. Here is a silly example:
+</para>
+<literallayout class="monospaced">
+my_transport:
+ driver = pipe
+ command = /bin/sh -c 'cat >>/some/file'
+</literallayout>
+<para>
+This is supposed to write the message at the end of the file. However, if two
+messages arrive at the same time, the file will be scrambled. You can use the
+<option>exim_lock</option> utility program (see section <xref linkend="SECTmailboxmaint"/>) to lock a
+file using the same algorithm that Exim itself uses.
+</para>
+</section>
+<section id="SECTenvuidgid">
+<title>Uids and gids</title>
+<para>
+<indexterm role="concept">
+<primary>local transports</primary>
+<secondary>uid and gid</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>local; uid and gid</secondary>
+</indexterm>
+All transports have the options <option>group</option> and <option>user</option>. If <option>group</option> is set, it
+overrides any group that the router set in the address, even if <option>user</option> is not
+set for the transport. This makes it possible, for example, to run local mail
+delivery under the uid of the recipient (set by the router), but in a special
+group (set by the transport). For example:
+</para>
+<literallayout class="monospaced">
+# Routers ...
+# User/group are set by check_local_user in this router
+local_users:
+ driver = accept
+ check_local_user
+ transport = group_delivery
+
+# Transports ...
+# This transport overrides the group
+group_delivery:
+ driver = appendfile
+ file = /var/spool/mail/$local_part_data
+ group = mail
+</literallayout>
+<para>
+If <option>user</option> is set for a transport, its value overrides what is set in the
+address by the router. If <option>user</option> is non-numeric and <option>group</option> is not set, the
+gid associated with the user is used. If <option>user</option> is numeric, <option>group</option> must be
+set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>initgroups</option></primary>
+</indexterm>
+When the uid is taken from the transport’s configuration, the <function>initgroups()</function>
+function is called for the groups associated with that uid if the
+<option>initgroups</option> option is set for the transport. When the uid is not specified
+by the transport, but is associated with the address by a router, the option
+for calling <function>initgroups()</function> is taken from the router configuration.
+</para>
+<para>
+<indexterm role="concept">
+<primary><command>pipe</command> transport</primary>
+<secondary>uid for</secondary>
+</indexterm>
+The <command>pipe</command> transport contains the special option <option>pipe_as_creator</option>. If this
+is set and <option>user</option> is not set, the uid of the process that called Exim to
+receive the message is used, and if <option>group</option> is not set, the corresponding
+original gid is also used.
+</para>
+<para>
+This is the detailed preference order for obtaining a gid; the first of the
+following that is set is used:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+A <option>group</option> setting of the transport;
+</para>
+</listitem>
+<listitem>
+<para>
+A <option>group</option> setting of the router;
+</para>
+</listitem>
+<listitem>
+<para>
+A gid associated with a user setting of the router, either as a result of
+<option>check_local_user</option> or an explicit non-numeric <option>user</option> setting;
+</para>
+</listitem>
+<listitem>
+<para>
+The group associated with a non-numeric <option>user</option> setting of the transport;
+</para>
+</listitem>
+<listitem>
+<para>
+In a <command>pipe</command> transport, the creator’s gid if <option>deliver_as_creator</option> is set and
+the uid is the creator’s uid;
+</para>
+</listitem>
+<listitem>
+<para>
+The Exim gid if the Exim uid is being used as a default.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+If, for example, the user is specified numerically on the router and there are
+no group settings, no gid is available. In this situation, an error occurs.
+This is different for the uid, for which there always is an ultimate default.
+The first of the following that is set is used:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+A <option>user</option> setting of the transport;
+</para>
+</listitem>
+<listitem>
+<para>
+In a <command>pipe</command> transport, the creator’s uid if <option>deliver_as_creator</option> is set;
+</para>
+</listitem>
+<listitem>
+<para>
+A <option>user</option> setting of the router;
+</para>
+</listitem>
+<listitem>
+<para>
+A <option>check_local_user</option> setting of the router;
+</para>
+</listitem>
+<listitem>
+<para>
+The Exim uid.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Of course, an error will still occur if the uid that is chosen is on the
+<option>never_users</option> list.
+</para>
+</section>
+<section id="SECID132">
+<title>Current and home directories</title>
+<para>
+<indexterm role="concept">
+<primary>current directory for local transport</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>home directory</primary>
+<secondary>for local transport</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>local; home directory for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>local; current directory for</secondary>
+</indexterm>
+Routers may set current and home directories for local transports by means of
+the <option>transport_current_directory</option> and <option>transport_home_directory</option> options.
+However, if the transport’s <option>current_directory</option> or <option>home_directory</option> options
+are set, they override the router’s values. In detail, the home directory
+for a local transport is taken from the first of these values that is set:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The <option>home_directory</option> option on the transport;
+</para>
+</listitem>
+<listitem>
+<para>
+The <option>transport_home_directory</option> option on the router;
+</para>
+</listitem>
+<listitem>
+<para>
+The password data if <option>check_local_user</option> is set on the router;
+</para>
+</listitem>
+<listitem>
+<para>
+The <option>router_home_directory</option> option on the router.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The current directory is taken from the first of these values that is set:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The <option>current_directory</option> option on the transport;
+</para>
+</listitem>
+<listitem>
+<para>
+The <option>transport_current_directory</option> option on the router.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+If neither the router nor the transport sets a current directory, Exim uses the
+value of the home directory, if it is set. Otherwise it sets the current
+directory to <filename>/</filename> before running a local transport.
+</para>
+</section>
+<section id="SECID133">
+<title>Expansion variables derived from the address</title>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$original_domain</varname></primary>
+</indexterm>
+Normally a local delivery is handling a single address, and in that case the
+variables such as <varname>$domain</varname> and <varname>$local_part</varname> are set during local
+deliveries. However, in some circumstances more than one address may be handled
+at once (for example, while writing batch SMTP for onward transmission by some
+other means). In this case, the variables associated with the local part are
+never set, <varname>$domain</varname> is set only if all the addresses have the same domain,
+and <varname>$original_domain</varname> is never set.
+<indexterm role="concept" startref="IIDenvlotra1" class="endofrange"/>
+<indexterm role="concept" startref="IIDenvlotra2" class="endofrange"/>
+<indexterm role="concept" startref="IIDenvlotra3" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPtransportgeneric">
+<title>Generic options for transports</title>
+<para>
+<indexterm role="concept" id="IIDgenoptra1" class="startofrange">
+<primary>generic options</primary>
+<secondary>transport</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDgenoptra2" class="startofrange">
+<primary>options</primary>
+<secondary>generic; for transports</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDgenoptra3" class="startofrange">
+<primary>transport</primary>
+<secondary>generic options for</secondary>
+</indexterm>
+The following generic options apply to all transports:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>body_only</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>body_only</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>body only</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>transporting body only</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>body of message</primary>
+<secondary>transporting</secondary>
+</indexterm>
+If this option is set, the message’s headers are not transported. It is
+mutually exclusive with <option>headers_only</option>. If it is used with the <command>appendfile</command>
+or <command>pipe</command> transports, the settings of <option>message_prefix</option> and
+<option>message_suffix</option> should be checked, because this option does not
+automatically suppress them.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>current_directory</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>current_directory</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>current directory for</secondary>
+</indexterm>
+This specifies the current directory that is to be set while running the
+transport, overriding any value that may have been set by the router.
+If the expansion fails for any reason, including forced failure, an error is
+logged, and delivery is deferred.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>disable_logging</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>disable_logging</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is set true, nothing is logged for any
+deliveries by the transport or for any
+transport errors. You should not set this option unless you really, really know
+what you are doing.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>debug_print</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>debug_print</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>variables in drivers</secondary>
+</indexterm>
+If this option is set and debugging is enabled (see the <option>-d</option> command line
+option), the string is expanded and included in the debugging output when the
+transport is run.
+If expansion of the string fails, the error message is written to the debugging
+output, and Exim carries on processing.
+This facility is provided to help with checking out the values of variables and
+so on when debugging driver configurations. For example, if a <option>headers_add</option>
+option is not working properly, <option>debug_print</option> could be used to output the
+variables it references. A newline is added to the text if it does not end with
+one.
+The variables <varname>$transport_name</varname> and <varname>$router_name</varname> contain the name of the
+transport and the router that called it.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>delivery_date_add</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>delivery_date_add</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Delivery-date:</emphasis> header line</primary>
+</indexterm>
+If this option is true, a <emphasis>Delivery-date:</emphasis> header is added to the message.
+This gives the actual time the delivery was made. As this is not a standard
+header, Exim has a configuration option (<option>delivery_date_remove</option>) which
+requests its removal from incoming messages, so that delivered messages can
+safely be resent to other recipients.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>driver</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>driver</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies which of the available transport drivers is to be used.
+There is no default, and this option must be set for every transport.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>envelope_to_add</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>envelope_to_add</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Envelope-to:</emphasis> header line</primary>
+</indexterm>
+If this option is true, an <emphasis>Envelope-to:</emphasis> header is added to the message.
+This gives the original address(es) in the incoming envelope that caused this
+delivery to happen. More than one address may be present if the transport is
+configured to handle several addresses at once, or if more than one original
+address was redirected to the same final address. As this is not a standard
+header, Exim has a configuration option (<option>envelope_to_remove</option>) which requests
+its removal from incoming messages, so that delivered messages can safely be
+resent to other recipients.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>event_action</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>event_action</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>events</primary>
+</indexterm>
+This option declares a string to be expanded for Exim’s events mechanism.
+For details see chapter <xref linkend="CHAPevents"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>group</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>group</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>Exim group</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>group; specifying</secondary>
+</indexterm>
+This option specifies a gid for running the transport process, overriding any
+value that the router supplies, and also overriding any value associated with
+<option>user</option> (see below).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>headers_add</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>headers_add</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>adding in transport</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>header lines; adding</secondary>
+</indexterm>
+This option specifies a list of text headers,
+newline-separated (by default, changeable in the usual way <xref linkend="SECTlistsepchange"/>),
+which are (separately) expanded and added to the header
+portion of a message as it is transported, as described in section
+<xref linkend="SECTheadersaddrem"/>. Additional header lines can also be specified by
+routers. If the result of the expansion is an empty string, or if the expansion
+is forced to fail, no action is taken. Other expansion failures are treated as
+errors and cause the delivery to be deferred.
+</para>
+<para>
+Unlike most options, <option>headers_add</option> can be specified multiple times
+for a transport; all listed headers are added.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>headers_only</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>headers_only</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>header lines only</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>transporting headers only</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>transporting</secondary>
+</indexterm>
+If this option is set, the message’s body is not transported. It is mutually
+exclusive with <option>body_only</option>. If it is used with the <command>appendfile</command> or <command>pipe</command>
+transports, the settings of <option>message_prefix</option> and <option>message_suffix</option> should be
+checked, since this option does not automatically suppress them.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>headers_remove</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>headers_remove</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>removing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>header lines; removing</secondary>
+</indexterm>
+This option specifies a list of text headers,
+colon-separated (by default, changeable in the usual way <xref linkend="SECTlistsepchange"/>),
+to be removed from the message.
+However, the option has no effect when an address is just being verified.
+Each list item is separately expanded.
+If the result of the expansion is an empty string, or if the expansion
+is forced to fail, no action is taken. Other expansion failures are treated as
+errors and cause the delivery to be deferred.
+</para>
+<para revisionflag="changed">
+If an item ends in *, it will match any header with the given prefix.
+</para>
+<para>
+Matching headers are omitted from the message as it is transported, as described
+in section <xref linkend="SECTheadersaddrem"/>. Header removal can also be specified by
+routers.
+</para>
+<para>
+Unlike most options, <option>headers_remove</option> can be specified multiple times
+for a transport; all listed headers are removed.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: Because of the separate expansion of the list items,
+items that contain a list separator must have it doubled.
+To avoid this, change the list separator (<xref linkend="SECTlistsepchange"/>).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>headers_rewrite</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>headers_rewrite</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>header lines; rewriting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>at transport time</secondary>
+</indexterm>
+This option allows addresses in header lines to be rewritten at transport time,
+that is, as the message is being copied to its destination. The contents of the
+option are a colon-separated list of rewriting rules. Each rule is in exactly
+the same form as one of the general rewriting rules that are applied when a
+message is received. These are described in chapter <xref linkend="CHAPrewrite"/>. For
+example,
+</para>
+<literallayout class="monospaced">
+headers_rewrite = a@b c@d f : \
+ x@y w@z
+</literallayout>
+<para>
+changes <emphasis>a@b</emphasis> into <emphasis>c@d</emphasis> in <emphasis>From:</emphasis> header lines, and <emphasis>x@y</emphasis> into
+<emphasis>w@z</emphasis> in all address-bearing header lines. The rules are applied to the
+header lines just before they are written out at transport time, so they affect
+only those copies of the message that pass through the transport. However, only
+the message’s original header lines, and any that were added by a system
+filter, are rewritten. If a router or transport adds header lines, they are not
+affected by this option. These rewriting rules are <emphasis>not</emphasis> applied to the
+envelope. You can change the return path using <option>return_path</option>, but you cannot
+change envelope recipients at this time.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>home_directory</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>home_directory</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>home directory for</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$home</varname></primary>
+</indexterm>
+This option specifies a home directory setting for a local transport,
+overriding any value that may be set by the router. The home directory is
+placed in <varname>$home</varname> while expanding the transport’s private options. It is also
+used as the current directory if no current directory is set by the
+<option>current_directory</option> option on the transport or the
+<option>transport_current_directory</option> option on the router. If the expansion fails
+for any reason, including forced failure, an error is logged, and delivery is
+deferred.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>initgroups</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>initgroups</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>additional groups</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>groups</primary>
+<secondary>additional</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>group; additional</secondary>
+</indexterm>
+If this option is true and the uid for the delivery process is provided by the
+transport, the <function>initgroups()</function> function is called when running the transport
+to ensure that any additional groups associated with the uid are set up.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>max_parallel</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>max_parallel</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>transport parallelism</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>parallel processes</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>concurrency limit</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>parallelism for transport</secondary>
+</indexterm>
+If this option is set and expands to an integer greater than zero
+it limits the number of concurrent runs of the transport.
+The control does not apply to shadow transports.
+</para>
+<para>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>transport concurrency control</secondary>
+</indexterm>
+Exim implements this control by means of a hints database in which a record is
+incremented whenever a transport process is being created. The record
+is decremented and possibly removed when the process terminates.
+Obviously there is scope for
+records to get left lying around if there is a system or program crash. To
+guard against this, Exim ignores any records that are more than six hours old.
+</para>
+<para>
+If you use this option, you should also arrange to delete the
+relevant hints database whenever your system reboots. The names of the files
+start with <filename>misc</filename> and they are kept in the <filename>spool/db</filename> directory. There
+may be one or two files, depending on the type of DBM in use. The same files
+are used for ETRN and smtp transport serialization.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>message_size_limit</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>message_size_limit</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>0</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>message size per transport</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>size</primary>
+<secondary>of message, limit</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>message size; limiting</secondary>
+</indexterm>
+This option controls the size of messages passed through the transport. It is
+expanded before use; the result of the expansion must be a sequence of decimal
+digits, optionally followed by K or M. If the expansion fails for any reason,
+including forced failure, or if the result is not of the required form,
+delivery is deferred. If the value is greater than zero and the size of a
+message exceeds this limit, the address is failed. If there is any chance that
+the resulting bounce message could be routed to the same transport, you should
+ensure that <option>return_size_limit</option> is less than the transport’s
+<option>message_size_limit</option>, as otherwise the bounce message will fail to get
+delivered.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>rcpt_include_affixes</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>rcpt_include_affixes</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>prefix</primary>
+<secondary>for local part, including in envelope</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>suffix for local part</primary>
+<secondary>including in envelope</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>prefix</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>suffix</secondary>
+</indexterm>
+When this option is false (the default), and an address that has had any
+affixes (prefixes or suffixes) removed from the local part is delivered by any
+form of SMTP or LMTP, the affixes are not included. For example, if a router
+that contains
+</para>
+<literallayout class="monospaced">
+local_part_prefix = *-
+</literallayout>
+<para>
+routes the address <emphasis>abc-xyz@some.domain</emphasis> to an SMTP transport, the envelope
+is delivered with
+</para>
+<literallayout class="monospaced">
+RCPT TO:<xyz@some.domain>
+</literallayout>
+<para>
+This is also the case when an ACL-time callout is being used to verify a
+recipient address. However, if <option>rcpt_include_affixes</option> is set true, the
+whole local part is included in the RCPT command. This option applies to BSMTP
+deliveries by the <command>appendfile</command> and <command>pipe</command> transports as well as to the
+<command>lmtp</command> and <command>smtp</command> transports.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>retry_use_local_part</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>retry_use_local_part</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>retry keys</secondary>
+</indexterm>
+When a delivery suffers a temporary failure, a retry record is created
+in Exim’s hints database. For remote deliveries, the key for the retry record
+is based on the name and/or IP address of the failing remote host. For local
+deliveries, the key is normally the entire address, including both the local
+part and the domain. This is suitable for most common cases of local delivery
+temporary failure – for example, exceeding a mailbox quota should delay only
+deliveries to that mailbox, not to the whole domain.
+</para>
+<para>
+However, in some special cases you may want to treat a temporary local delivery
+as a failure associated with the domain, and not with a particular local part.
+(For example, if you are storing all mail for some domain in files.) You can do
+this by setting <option>retry_use_local_part</option> false.
+</para>
+<para>
+For all the local transports, its default value is true. For remote transports,
+the default value is false for tidiness, but changing the value has no effect
+on a remote transport in the current implementation.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>return_path</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>return_path</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>envelope sender</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope from</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>return path; changing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>return path</primary>
+<secondary>changing in transport</secondary>
+</indexterm>
+If this option is set, the string is expanded at transport time and replaces
+the existing return path (envelope sender) value in the copy of the message
+that is being delivered. An empty return path is permitted. This feature is
+designed for remote deliveries, where the value of this option is used in the
+SMTP MAIL command. If you set <option>return_path</option> for a local transport, the
+only effect is to change the address that is placed in the <emphasis>Return-path:</emphasis>
+header line, if one is added to the message (see the next option).
+</para>
+<para>
+<emphasis role="bold">Note:</emphasis> A changed return path is not logged unless you add
+<option>return_path_on_delivery</option> to the log selector.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$return_path</varname></primary>
+</indexterm>
+The expansion can refer to the existing value via <varname>$return_path</varname>. This is
+either the message’s envelope sender, or an address set by the
+<option>errors_to</option> option on a router. If the expansion is forced to fail, no
+replacement occurs; if it fails for another reason, delivery is deferred. This
+option can be used to support VERP (Variable Envelope Return Paths) – see
+section <xref linkend="SECTverp"/>.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: If a delivery error is detected locally, including the case when a
+remote server rejects a message at SMTP time, the bounce message is not sent to
+the value of this option. It is sent to the previously set errors address.
+This defaults to the incoming sender address, but can be changed by setting
+<option>errors_to</option> in a router.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>return_path_add</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>return_path_add</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Return-path:</emphasis> header line</primary>
+</indexterm>
+If this option is true, a <emphasis>Return-path:</emphasis> header is added to the message.
+Although the return path is normally available in the prefix line of BSD
+mailboxes, this is commonly not displayed by MUAs, and so the user does not
+have easy access to it.
+</para>
+<para>
+RFC 2821 states that the <emphasis>Return-path:</emphasis> header is added to a message <quote>when
+the delivery SMTP server makes the final delivery</quote>. This implies that this
+header should not be present in incoming messages. Exim has a configuration
+option, <option>return_path_remove</option>, which requests removal of this header from
+incoming messages, so that delivered messages can safely be resent to other
+recipients.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>shadow_condition</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>shadow_condition</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>shadow_transport</option> below.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>shadow_transport</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>shadow_transport</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>shadow transport</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>shadow</secondary>
+</indexterm>
+A local transport may set the <option>shadow_transport</option> option to the name of
+another local transport. Shadow remote transports are not supported.
+</para>
+<para>
+Whenever a delivery to the main transport succeeds, and either
+<option>shadow_condition</option> is unset, or its expansion does not result in the empty
+string or one of the strings <quote>0</quote> or <quote>no</quote> or <quote>false</quote>, the message is also
+passed to the shadow transport, with the same delivery address or addresses. If
+expansion fails, no action is taken except that non-forced expansion failures
+cause a log line to be written.
+</para>
+<para>
+The result of the shadow transport is discarded and does not affect the
+subsequent processing of the message. Only a single level of shadowing is
+provided; the <option>shadow_transport</option> option is ignored on any transport when it
+is running as a shadow. Options concerned with output from pipes are also
+ignored. The log line for the successful delivery has an item added on the end,
+of the form
+</para>
+<literallayout class="monospaced">
+ST=<shadow transport name>
+</literallayout>
+<para>
+If the shadow transport did not succeed, the error message is put in
+parentheses afterwards. Shadow transports can be used for a number of different
+purposes, including keeping more detailed log information than Exim normally
+provides, and implementing automatic acknowledgment policies based on message
+headers that some sites insist on.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>transport_filter</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>transport_filter</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>filter</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>transport filter</secondary>
+</indexterm>
+This option sets up a filtering (in the Unix shell sense) process for messages
+at transport time. It should not be confused with mail filtering as set up by
+individual users or via a system filter.
+If unset, or expanding to an empty string, no filtering is done.
+</para>
+<para>
+When the message is about to be written out, the command specified by
+<option>transport_filter</option> is started up in a separate, parallel process, and
+the entire message, including the header lines, is passed to it on its standard
+input (this in fact is done from a third process, to avoid deadlock). The
+command must be specified as an absolute path.
+</para>
+<para>
+The lines of the message that are written to the transport filter are
+terminated by newline (<quote>\n</quote>). The message is passed to the filter before any
+SMTP-specific processing, such as turning <quote>\n</quote> into <quote>\r\n</quote> and escaping
+lines beginning with a dot, and also before any processing implied by the
+settings of <option>check_string</option> and <option>escape_string</option> in the <command>appendfile</command> or
+<command>pipe</command> transports.
+</para>
+<para>
+The standard error for the filter process is set to the same destination as its
+standard output; this is read and written to the message’s ultimate
+destination. The process that writes the message to the filter, the
+filter itself, and the original process that reads the result and delivers it
+are all run in parallel, like a shell pipeline.
+</para>
+<para>
+The filter can perform any transformations it likes, but of course should take
+care not to break RFC 2822 syntax. Exim does not check the result, except to
+test for a final newline when SMTP is in use. All messages transmitted over
+SMTP must end with a newline, so Exim supplies one if it is missing.
+</para>
+<para>
+<indexterm role="concept">
+<primary>content scanning</primary>
+<secondary>per user</secondary>
+</indexterm>
+A transport filter can be used to provide content-scanning on a per-user basis
+at delivery time if the only required effect of the scan is to modify the
+message. For example, a content scan could insert a new header line containing
+a spam score. This could be interpreted by a filter in the user’s MUA. It is
+not possible to discard a message at this stage.
+</para>
+<para>
+<indexterm role="concept">
+<primary>SIZE</primary>
+<secondary>ESMTP extension</secondary>
+</indexterm>
+A problem might arise if the filter increases the size of a message that is
+being sent down an SMTP connection. If the receiving SMTP server has indicated
+support for the SIZE parameter, Exim will have sent the size of the message
+at the start of the SMTP session. If what is actually sent is substantially
+more, the server might reject the message. This can be worked round by setting
+the <option>size_addition</option> option on the <command>smtp</command> transport, either to allow for
+additions to the message, or to disable the use of SIZE altogether.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$pipe_addresses</varname></primary>
+</indexterm>
+The value of the <option>transport_filter</option> option is the command string for starting
+the filter, which is run directly from Exim, not under a shell. The string is
+parsed by Exim in the same way as a command string for the <command>pipe</command> transport:
+Exim breaks it up into arguments and then expands each argument separately (see
+section <xref linkend="SECThowcommandrun"/>). Any kind of expansion failure causes delivery
+to be deferred. The special argument <varname>$pipe_addresses</varname> is replaced by a number
+of arguments, one for each address that applies to this delivery. (This isn’t
+an ideal name for this feature here, but as it was already implemented for the
+<command>pipe</command> transport, it seemed sensible not to change it.)
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host_address</varname></primary>
+</indexterm>
+The expansion variables <varname>$host</varname> and <varname>$host_address</varname> are available when the
+transport is a remote one. They contain the name and IP address of the host to
+which the message is being sent. For example:
+</para>
+<literallayout class="monospaced">
+transport_filter = /some/directory/transport-filter.pl \
+ $host $host_address $sender_address $pipe_addresses
+</literallayout>
+<para>
+Two problems arise if you want to use more complicated expansion items to
+generate transport filter commands, both of which due to the fact that the
+command is split up <emphasis>before</emphasis> expansion.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If an expansion item contains white space, you must quote it, so that it is all
+part of the same command item. If the entire option setting is one such
+expansion item, you have to take care what kind of quoting you use. For
+example:
+</para>
+<literallayout class="monospaced">
+transport_filter = '/bin/cmd${if eq{$host}{a.b.c}{1}{2}}'
+</literallayout>
+<para>
+This runs the command <command>/bin/cmd1</command> if the host name is <emphasis>a.b.c</emphasis>, and
+<command>/bin/cmd2</command> otherwise. If double quotes had been used, they would have been
+stripped by Exim when it read the option’s value. When the value is used, if
+the single quotes were missing, the line would be split into two items,
+<literal>/bin/cmd${if</literal> and <literal>eq{$host}{a.b.c}{1}{2}</literal>, and an error would occur when
+Exim tried to expand the first one.
+</para>
+</listitem>
+<listitem>
+<para>
+Except for the special case of <varname>$pipe_addresses</varname> that is mentioned above, an
+expansion cannot generate multiple arguments, or a command name followed by
+arguments. Consider this example:
+</para>
+<literallayout class="monospaced">
+transport_filter = ${lookup{$host}lsearch{/a/file}\
+ {$value}{/bin/cat}}
+</literallayout>
+<para>
+The result of the lookup is interpreted as the name of the command, even
+if it contains white space. The simplest way round this is to use a shell:
+</para>
+<literallayout class="monospaced">
+transport_filter = /bin/sh -c ${lookup{$host}lsearch{/a/file}\
+ {$value}{/bin/cat}}
+</literallayout>
+</listitem>
+</itemizedlist>
+<para>
+The filter process is run under the same uid and gid as the normal delivery.
+For remote deliveries this is the Exim uid/gid by default. The command should
+normally yield a zero return code. Transport filters are not supposed to fail.
+A non-zero code is taken to mean that the transport filter encountered some
+serious problem. Delivery of the message is deferred; the message remains on
+the queue and is tried again later. It is not possible to cause a message to be
+bounced from a transport filter.
+</para>
+<para>
+If a transport filter is set on an autoreply transport, the original message is
+passed through the filter as it is being copied into the newly generated
+message, which happens if the <option>return_message</option> option is set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>transport_filter_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>transport_filter_timeout</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>5m</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>filter, timeout</secondary>
+</indexterm>
+When Exim is reading the output of a transport filter, it applies a timeout
+that can be set by this option. Exceeding the timeout is normally treated as a
+temporary delivery failure. However, if a transport filter is used with a
+<command>pipe</command> transport, a timeout in the transport filter is treated in the same
+way as a timeout in the pipe command itself. By default, a timeout is a hard
+error, but if the <command>pipe</command> transport’s <option>timeout_defer</option> option is set true, it
+becomes a temporary error.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>user</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>user</option></entry>
+<entry>Use: <emphasis>transports</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>Exim user</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>uid (user id)</primary>
+<secondary>local delivery</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>user, specifying</secondary>
+</indexterm>
+This option specifies the user under whose uid the delivery process is to be
+run, overriding any uid that may have been set by the router. If the user is
+given as a name, the uid is looked up from the password data, and the
+associated group is taken as the value of the gid to be used if the <option>group</option>
+option is not set.
+</para>
+<para>
+For deliveries that use local transports, a user and group are normally
+specified explicitly or implicitly (for example, as a result of
+<option>check_local_user</option>) by the router or transport.
+</para>
+<para>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>access by remote transport</secondary>
+</indexterm>
+For remote transports, you should leave this option unset unless you really are
+sure you know what you are doing. When a remote transport is running, it needs
+to be able to access Exim’s hints databases, because each host may have its own
+retry data.
+<indexterm role="concept" startref="IIDgenoptra1" class="endofrange"/>
+<indexterm role="concept" startref="IIDgenoptra2" class="endofrange"/>
+<indexterm role="concept" startref="IIDgenoptra3" class="endofrange"/>
+</para>
+</chapter>
+
+<chapter id="CHAPbatching">
+<title>Address batching in local transports</title>
+<titleabbrev>Address batching</titleabbrev>
+<para>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>local; address batching in</secondary>
+</indexterm>
+The only remote transport (<command>smtp</command>) is normally configured to handle more than
+one address at a time, so that when several addresses are routed to the same
+remote host, just one copy of the message is sent. Local transports, however,
+normally handle one address at a time. That is, a separate instance of the
+transport is run for each address that is routed to the transport. A separate
+copy of the message is delivered each time.
+</para>
+<para>
+<indexterm role="concept">
+<primary>batched local delivery</primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>batch_max</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>batch_id</option></primary>
+</indexterm>
+In special cases, it may be desirable to handle several addresses at once in a
+local transport, for example:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+In an <command>appendfile</command> transport, when storing messages in files for later
+delivery by some other means, a single copy of the message with multiple
+recipients saves space.
+</para>
+</listitem>
+<listitem>
+<para>
+In an <command>lmtp</command> transport, when delivering over <quote>local SMTP</quote> to some process,
+a single copy saves time, and is the normal way LMTP is expected to work.
+</para>
+</listitem>
+<listitem>
+<para>
+In a <command>pipe</command> transport, when passing the message
+to a scanner program or
+to some other delivery mechanism such as UUCP, multiple recipients may be
+acceptable.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+These three local transports all have the same options for controlling multiple
+(<quote>batched</quote>) deliveries, namely <option>batch_max</option> and <option>batch_id</option>. To save
+repeating the information for each transport, these options are described here.
+</para>
+<para>
+The <option>batch_max</option> option specifies the maximum number of addresses that can be
+delivered together in a single run of the transport. Its default value is one
+(no batching). When more than one address is routed to a transport that has a
+<option>batch_max</option> value greater than one, the addresses are delivered in a batch
+(that is, in a single run of the transport with multiple recipients), subject
+to certain conditions:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+If any of the transport’s options contain a reference to <varname>$local_part</varname>, no
+batching is possible.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+If any of the transport’s options contain a reference to <varname>$domain</varname>, only
+addresses with the same domain are batched.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>customizing</primary>
+<secondary>batching condition</secondary>
+</indexterm>
+If <option>batch_id</option> is set, it is expanded for each address, and only those
+addresses with the same expanded value are batched. This allows you to specify
+customized batching conditions. Failure of the expansion for any reason,
+including forced failure, disables batching, but it does not stop the delivery
+from taking place.
+</para>
+</listitem>
+<listitem>
+<para>
+Batched addresses must also have the same errors address (where to send
+delivery errors), the same header additions and removals, the same user and
+group for the transport, and if a host list is present, the first host must
+be the same.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+In the case of the <command>appendfile</command> and <command>pipe</command> transports, batching applies
+both when the file or pipe command is specified in the transport, and when it
+is specified by a <command>redirect</command> router, but all the batched addresses must of
+course be routed to the same file or pipe command. These two transports have an
+option called <option>use_bsmtp</option>, which causes them to deliver the message in
+<quote>batched SMTP</quote> format, with the envelope represented as SMTP commands. The
+<option>check_string</option> and <option>escape_string</option> options are forced to the values
+</para>
+<literallayout class="monospaced">
+check_string = "."
+escape_string = ".."
+</literallayout>
+<para>
+when batched SMTP is in use. A full description of the batch SMTP mechanism is
+given in section <xref linkend="SECTbatchSMTP"/>. The <command>lmtp</command> transport does not have a
+<option>use_bsmtp</option> option, because it always delivers using the SMTP protocol.
+</para>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Envelope-to:</emphasis> header line</primary>
+</indexterm>
+If the generic <option>envelope_to_add</option> option is set for a batching transport, the
+<emphasis>Envelope-to:</emphasis> header that is added to the message contains all the addresses
+that are being processed together. If you are using a batching <command>appendfile</command>
+transport without <option>use_bsmtp</option>, the only way to preserve the recipient
+addresses is to set the <option>envelope_to_add</option> option.
+</para>
+<para>
+<indexterm role="concept">
+<primary><command>pipe</command> transport</primary>
+<secondary>with multiple addresses</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$pipe_addresses</varname></primary>
+</indexterm>
+If you are using a <command>pipe</command> transport without BSMTP, and setting the
+transport’s <option>command</option> option, you can include <varname>$pipe_addresses</varname> as part of
+the command. This is not a true variable; it is a bit of magic that causes each
+of the recipient addresses to be inserted into the command as a separate
+argument. This provides a way of accessing all the addresses that are being
+delivered in the batch. <emphasis role="bold">Note:</emphasis> This is not possible for pipe commands that
+are specified by a <command>redirect</command> router.
+</para>
+</chapter>
+
+<chapter id="CHAPappendfile">
+<title>The appendfile transport</title>
+<para>
+<indexterm role="concept" id="IIDapptra1" class="startofrange">
+<primary><command>appendfile</command> transport</primary>
+</indexterm>
+<indexterm role="concept" id="IIDapptra2" class="startofrange">
+<primary>transports</primary>
+<secondary><command>appendfile</command></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>directory creation</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>creating directories</primary>
+</indexterm>
+The <command>appendfile</command> transport delivers a message by appending it to an existing
+file, or by creating an entirely new file in a specified directory. Single
+files to which messages are appended can be in the traditional Unix mailbox
+format, or optionally in the MBX format supported by the Pine MUA and
+University of Washington IMAP daemon, <emphasis>inter alia</emphasis>. When each message is
+being delivered as a separate file, <quote>maildir</quote> format can optionally be used
+to give added protection against failures that happen part-way through the
+delivery. A third form of separate-file delivery known as <quote>mailstore</quote> is also
+supported. For all file formats, Exim attempts to create as many levels of
+directory as necessary, provided that <option>create_directory</option> is set.
+</para>
+<para>
+The code for the optional formats is not included in the Exim binary by
+default. It is necessary to set SUPPORT_MBX, SUPPORT_MAILDIR and/or
+SUPPORT_MAILSTORE in <filename>Local/Makefile</filename> to have the appropriate code
+included.
+</para>
+<para>
+<indexterm role="concept">
+<primary>quota</primary>
+<secondary>system</secondary>
+</indexterm>
+Exim recognizes system quota errors, and generates an appropriate message. Exim
+also supports its own quota control within the transport, for use when the
+system facility is unavailable or cannot be used for some reason.
+</para>
+<para>
+If there is an error while appending to a file (for example, quota exceeded or
+partition filled), Exim attempts to reset the file’s length and last
+modification time back to what they were before. If there is an error while
+creating an entirely new file, the new file is removed.
+</para>
+<para>
+Before appending to a file, a number of security checks are made, and the
+file is locked. A detailed description is given below, after the list of
+private options.
+</para>
+<para>
+The <command>appendfile</command> transport is most commonly used for local deliveries to
+users’ mailboxes. However, it can also be used as a pseudo-remote transport for
+putting messages into files for remote delivery by some means other than Exim.
+<quote>Batch SMTP</quote> format is often used in this case (see the <option>use_bsmtp</option>
+option).
+</para>
+<section id="SECTfildiropt">
+<title>The file and directory options</title>
+<para>
+The <option>file</option> option specifies a single file, to which the message is appended;
+the <option>directory</option> option specifies a directory, in which a new file containing
+the message is created. Only one of these two options can be set, and for
+normal deliveries to mailboxes, one of them <emphasis>must</emphasis> be set.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$address_file</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+However, <command>appendfile</command> is also used for delivering messages to files or
+directories whose names (or parts of names) are obtained from alias,
+forwarding, or filtering operations (for example, a <option>save</option> command in a
+user’s Exim filter). When such a transport is running, <varname>$local_part</varname> contains
+the local part that was aliased or forwarded, and <varname>$address_file</varname> contains the
+name (or partial name) of the file or directory generated by the redirection
+operation. There are two cases:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If neither <option>file</option> nor <option>directory</option> is set, the redirection operation
+must specify an absolute path (one that begins with <literal>/</literal>). This is the most
+common case when users with local accounts use filtering to sort mail into
+different folders. See for example, the <command>address_file</command> transport in the
+default configuration. If the path ends with a slash, it is assumed to be the
+name of a directory. A delivery to a directory can also be forced by setting
+<option>maildir_format</option> or <option>mailstore_format</option>.
+</para>
+</listitem>
+<listitem>
+<para>
+If <option>file</option> or <option>directory</option> is set for a delivery from a redirection, it is
+used to determine the file or directory name for the delivery. Normally, the
+contents of <varname>$address_file</varname> are used in some way in the string expansion.
+</para>
+</listitem>
+</itemizedlist>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>tainted data</primary>
+<secondary>in filenames</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>appendfile</primary>
+<secondary>tainted data</secondary>
+</indexterm>
+Tainted data may not be used for a file or directory name.
+This means that, for instance, <varname>$local_part</varname> cannot be used directly
+as a component of a path. It can however be used as the key for a lookup
+which returns a path (or component).
+</para>
+<para>
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary>configuring <command>appendfile</command></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sieve filter</primary>
+<secondary>relative mailbox path handling</secondary>
+</indexterm>
+As an example of the second case, consider an environment where users do not
+have home directories. They may be permitted to use Exim filter commands of the
+form:
+</para>
+<literallayout class="monospaced">
+save folder23
+</literallayout>
+<para>
+or Sieve filter commands of the form:
+</para>
+<literallayout class="monospaced">
+require "fileinto";
+fileinto "folder23";
+</literallayout>
+<para>
+In this situation, the expansion of <option>file</option> or <option>directory</option> in the transport
+must transform the relative path into an appropriate absolute filename. In the
+case of Sieve filters, the name <emphasis>inbox</emphasis> must be handled. It is the name that
+is used as a result of a <quote>keep</quote> action in the filter. This example shows one
+way of handling this requirement:
+</para>
+<literallayout class="monospaced">
+file = ${if eq{$address_file}{inbox} \
+ {/var/mail/$local_part_data} \
+ {${if eq{${substr_0_1:$address_file}}{/} \
+ {$address_file} \
+ {$home/mail/$address_file} \
+ }} \
+ }
+</literallayout>
+<para>
+With this setting of <option>file</option>, <emphasis>inbox</emphasis> refers to the standard mailbox
+location, absolute paths are used without change, and other folders are in the
+<filename>mail</filename> directory within the home directory.
+</para>
+<para>
+<emphasis role="bold">Note 1</emphasis>: While processing an Exim filter, a relative path such as
+<filename>folder23</filename> is turned into an absolute path if a home directory is known to
+the router. In particular, this is the case if <option>check_local_user</option> is set. If
+you want to prevent this happening at routing time, you can set
+<option>router_home_directory</option> empty. This forces the router to pass the relative
+path to the transport.
+</para>
+<para>
+<emphasis role="bold">Note 2</emphasis>: An absolute path in <varname>$address_file</varname> is not treated specially;
+the <option>file</option> or <option>directory</option> option is still used if it is set.
+</para>
+</section>
+<section id="SECID134">
+<title>Private options for appendfile</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>appendfile</command> transport</secondary>
+</indexterm>
+</para>
+<para>
+<indexterm role="option">
+<primary><option>allow_fifo</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>allow_fifo</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>fifo (named pipe)</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>named pipe (fifo)</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>pipe</primary>
+<secondary>named (fifo)</secondary>
+</indexterm>
+Setting this option permits delivery to named pipes (FIFOs) as well as to
+regular files. If no process is reading the named pipe at delivery time, the
+delivery is deferred.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>allow_symlink</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>allow_symlink</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>symbolic link</primary>
+<secondary>to mailbox</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>mailbox</primary>
+<secondary>symbolic link</secondary>
+</indexterm>
+By default, <command>appendfile</command> will not deliver if the path name for the file is
+that of a symbolic link. Setting this option relaxes that constraint, but there
+are security issues involved in the use of symbolic links. Be sure you know
+what you are doing if you set this. Details of exactly what this option affects
+are included in the discussion which follows this list of options.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>batch_id</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>batch_id</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See the description of local delivery batching in chapter <xref linkend="CHAPbatching"/>.
+However, batching is automatically disabled for <command>appendfile</command> deliveries that
+happen as a result of forwarding or aliasing or other redirection directly to a
+file.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>batch_max</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>batch_max</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>1</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See the description of local delivery batching in chapter <xref linkend="CHAPbatching"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_group</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_group</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+When this option is set, the group owner of the file defined by the <option>file</option>
+option is checked to see that it is the same as the group under which the
+delivery process is running. The default setting is false because the default
+file mode is 0600, which means that the group is irrelevant.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_owner</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_owner</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+When this option is set, the owner of the file defined by the <option>file</option> option
+is checked to ensure that it is the same as the user under which the delivery
+process is running.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_string</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_string</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><quote>From</quote> line</primary>
+</indexterm>
+As <command>appendfile</command> writes the message, the start of each line is tested for
+matching <option>check_string</option>, and if it does, the initial matching characters are
+replaced by the contents of <option>escape_string</option>. The value of <option>check_string</option> is
+a literal string, not a regular expression, and the case of any letters it
+contains is significant.
+</para>
+<para>
+If <option>use_bsmtp</option> is set the values of <option>check_string</option> and <option>escape_string</option>
+are forced to <quote>.</quote> and <quote>..</quote> respectively, and any settings in the
+configuration are ignored. Otherwise, they default to <quote>From </quote> and
+<quote>>From </quote> when the <option>file</option> option is set, and unset when any of the
+<option>directory</option>, <option>maildir</option>, or <option>mailstore</option> options are set.
+</para>
+<para>
+The default settings, along with <option>message_prefix</option> and <option>message_suffix</option>, are
+suitable for traditional <quote>BSD</quote> mailboxes, where a line beginning with
+<quote>From </quote> indicates the start of a new message. All four options need changing
+if another format is used. For example, to deliver to mailboxes in MMDF format:
+<indexterm role="concept">
+<primary>MMDF format mailbox</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>mailbox</primary>
+<secondary>MMDF format</secondary>
+</indexterm>
+</para>
+<literallayout class="monospaced">
+check_string = "\1\1\1\1\n"
+escape_string = "\1\1\1\1 \n"
+message_prefix = "\1\1\1\1\n"
+message_suffix = "\1\1\1\1\n"
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>create_directory</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>create_directory</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>directory creation</primary>
+</indexterm>
+When this option is true, Exim attempts to create any missing superior
+directories for the file that it is about to write. A created directory’s mode
+is given by the <option>directory_mode</option> option.
+</para>
+<para>
+The group ownership of a newly created directory is highly dependent on the
+operating system (and possibly the file system) that is being used. For
+example, in Solaris, if the parent directory has the setgid bit set, its group
+is propagated to the child; if not, the currently set group is used. However,
+in FreeBSD, the parent’s group is always used.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>create_file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>create_file</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>anywhere</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option constrains the location of files and directories that are created
+by this transport. It applies to files defined by the <option>file</option> option and
+directories defined by the <option>directory</option> option. In the case of maildir
+delivery, it applies to the top level directory, not the maildir directories
+beneath.
+</para>
+<para>
+The option must be set to one of the words <quote>anywhere</quote>, <quote>inhome</quote>, or
+<quote>belowhome</quote>. In the second and third cases, a home directory must have been
+set for the transport. This option is not useful when an explicit filename is
+given for normal mailbox deliveries. It is intended for the case when filenames
+are generated from users’ <filename>.forward</filename> files. These are usually handled
+by an <command>appendfile</command> transport called <option>address_file</option>. See also
+<option>file_must_exist</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>directory</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>directory</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option is mutually exclusive with the <option>file</option> option, but one of <option>file</option>
+or <option>directory</option> must be set, unless the delivery is the direct result of a
+redirection (see section <xref linkend="SECTfildiropt"/>).
+</para>
+<para>
+When <option>directory</option> is set, the string is expanded, and the message is delivered
+into a new file or files in or below the given directory, instead of being
+appended to a single mailbox file. A number of different formats are provided
+(see <option>maildir_format</option> and <option>mailstore_format</option>), and see section
+<xref linkend="SECTopdir"/> for further details of this form of delivery.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>directory_file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>directory_file</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>base62</primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$inode</varname></primary>
+</indexterm>
+When <option>directory</option> is set, but neither <option>maildir_format</option> nor
+<option>mailstore_format</option> is set, <command>appendfile</command> delivers each message into a file
+whose name is obtained by expanding this string. The default value is:
+</para>
+<literallayout class="monospaced">
+q${base62:$tod_epoch}-$inode
+</literallayout>
+<para>
+This generates a unique name from the current time, in base 62 form, and the
+inode of the file. The variable <varname>$inode</varname> is available only when expanding this
+option.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>directory_mode</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>directory_mode</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>octal integer</emphasis></entry>
+<entry>Default: <emphasis>0700</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If <command>appendfile</command> creates any directories as a result of the
+<option>create_directory</option> option, their mode is specified by this option.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>escape_string</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>escape_string</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>see description</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>check_string</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>file</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option is mutually exclusive with the <option>directory</option> option, but one of
+<option>file</option> or <option>directory</option> must be set, unless the delivery is the direct result
+of a redirection (see section <xref linkend="SECTfildiropt"/>). The <option>file</option> option
+specifies a single file, to which the message is appended. One or more of
+<option>use_fcntl_lock</option>, <option>use_flock_lock</option>, or <option>use_lockfile</option> must be set with
+<option>file</option>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>NFS</primary>
+<secondary>lock file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>locking files</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lock files</primary>
+</indexterm>
+If you are using more than one host to deliver over NFS into the same
+mailboxes, you should always use lock files.
+</para>
+<para>
+The string value is expanded for each delivery, and must yield an absolute
+path. The most common settings of this option are variations on one of these
+examples:
+</para>
+<literallayout class="monospaced">
+file = /var/spool/mail/$local_part_data
+file = /home/$local_part_data/inbox
+file = $home/inbox
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary><quote>sticky</quote> bit</primary>
+</indexterm>
+In the first example, all deliveries are done into the same directory. If Exim
+is configured to use lock files (see <option>use_lockfile</option> below) it must be able to
+create a file in the directory, so the <quote>sticky</quote> bit must be turned on for
+deliveries to be possible, or alternatively the <option>group</option> option can be used to
+run the delivery under a group id which has write access to the directory.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>file_format</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>file_format</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>mailbox; checking existing format</secondary>
+</indexterm>
+This option requests the transport to check the format of an existing file
+before adding to it. The check consists of matching a specific string at the
+start of the file. The value of the option consists of an even number of
+colon-separated strings. The first of each pair is the test string, and the
+second is the name of a transport. If the transport associated with a matched
+string is not the current transport, control is passed over to the other
+transport. For example, suppose the standard <command>local_delivery</command> transport has
+this added to it:
+</para>
+<literallayout class="monospaced">
+file_format = "From : local_delivery :\
+ \1\1\1\1\n : local_mmdf_delivery"
+</literallayout>
+<para>
+Mailboxes that begin with <quote>From</quote> are still handled by this transport, but if
+a mailbox begins with four binary ones followed by a newline, control is passed
+to a transport called <option>local_mmdf_delivery</option>, which presumably is configured
+to do the delivery in MMDF format. If a mailbox does not exist or is empty, it
+is assumed to match the current transport. If the start of a mailbox doesn’t
+match any string, or if the transport named for a given string is not defined,
+delivery is deferred.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>file_must_exist</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>file_must_exist</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is true, the file specified by the <option>file</option> option must exist.
+A temporary error occurs if it does not, causing delivery to be deferred.
+If this option is false, the file is created if it does not exist.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>lock_fcntl_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>lock_fcntl_timeout</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>0s</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>mailbox locking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>mailbox</primary>
+<secondary>locking, blocking and non-blocking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>locking files</primary>
+</indexterm>
+By default, the <command>appendfile</command> transport uses non-blocking calls to <function>fcntl()</function>
+when locking an open mailbox file. If the call fails, the delivery process
+sleeps for <option>lock_interval</option> and tries again, up to <option>lock_retries</option> times.
+Non-blocking calls are used so that the file is not kept open during the wait
+for the lock; the reason for this is to make it as safe as possible for
+deliveries over NFS in the case when processes might be accessing an NFS
+mailbox without using a lock file. This should not be done, but
+misunderstandings and hence misconfigurations are not unknown.
+</para>
+<para>
+On a busy system, however, the performance of a non-blocking lock approach is
+not as good as using a blocking lock with a timeout. In this case, the waiting
+is done inside the system call, and Exim’s delivery process acquires the lock
+and can proceed as soon as the previous lock holder releases it.
+</para>
+<para>
+If <option>lock_fcntl_timeout</option> is set to a non-zero time, blocking locks, with that
+timeout, are used. There may still be some retrying: the maximum number of
+retries is
+</para>
+<literallayout class="monospaced">
+(lock_retries * lock_interval) / lock_fcntl_timeout
+</literallayout>
+<para>
+rounded up to the next whole number. In other words, the total time during
+which <command>appendfile</command> is trying to get a lock is roughly the same, unless
+<option>lock_fcntl_timeout</option> is set very large.
+</para>
+<para>
+You should consider setting this option if you are getting a lot of delayed
+local deliveries because of errors of the form
+</para>
+<literallayout class="monospaced">
+failed to lock mailbox /some/file (fcntl)
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>lock_flock_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>lock_flock_timeout</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>0s</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This timeout applies to file locking when using <function>flock()</function> (see
+<option>use_flock</option>); the timeout operates in a similar manner to
+<option>lock_fcntl_timeout</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>lock_interval</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>lock_interval</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>3s</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies the time to wait between attempts to lock the file. See below
+for details of locking.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>lock_retries</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>lock_retries</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>10</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies the maximum number of attempts to lock the file. A value of zero
+is treated as 1. See below for details of locking.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>lockfile_mode</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>lockfile_mode</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>octal integer</emphasis></entry>
+<entry>Default: <emphasis>0600</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies the mode of the created lock file, when a lock file is being
+used (see <option>use_lockfile</option> and <option>use_mbx_lock</option>).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>lockfile_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>lockfile_timeout</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>30m</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>mailbox locking</secondary>
+</indexterm>
+When a lock file is being used (see <option>use_lockfile</option>), if a lock file already
+exists and is older than this value, it is assumed to have been left behind by
+accident, and Exim attempts to remove it.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mailbox_filecount</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>mailbox_filecount</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>mailbox</primary>
+<secondary>specifying size of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>size</primary>
+<secondary>of mailbox</secondary>
+</indexterm>
+If this option is set, it is expanded, and the result is taken as the current
+number of files in the mailbox. It must be a decimal number, optionally
+followed by K or M. This provides a way of obtaining this information from an
+external source that maintains the data.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mailbox_size</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>mailbox_size</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>mailbox</primary>
+<secondary>specifying size of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>size</primary>
+<secondary>of mailbox</secondary>
+</indexterm>
+If this option is set, it is expanded, and the result is taken as the current
+size the mailbox. It must be a decimal number, optionally followed by K or M.
+This provides a way of obtaining this information from an external source that
+maintains the data. This is likely to be helpful for maildir deliveries where
+it is computationally expensive to compute the size of a mailbox.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>maildir_format</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>maildir_format</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>maildir format</primary>
+<secondary>specifying</secondary>
+</indexterm>
+If this option is set with the <option>directory</option> option, the delivery is into a new
+file, in the <quote>maildir</quote> format that is used by other mail software. When the
+transport is activated directly from a <command>redirect</command> router (for example, the
+<command>address_file</command> transport in the default configuration), setting
+<option>maildir_format</option> causes the path received from the router to be treated as a
+directory, whether or not it ends with <literal>/</literal>. This option is available only if
+SUPPORT_MAILDIR is present in <filename>Local/Makefile</filename>. See section
+<xref linkend="SECTmaildirdelivery"/> below for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>maildir_quota_directory_regex</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>maildir_quota_directory_regex</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>See below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>maildir format</primary>
+<secondary>quota; directories included in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>quota</primary>
+<secondary>maildir; directories included in</secondary>
+</indexterm>
+This option is relevant only when <option>maildir_use_size_file</option> is set. It defines
+a regular expression for specifying directories, relative to the quota
+directory (see <option>quota_directory</option>), that should be included in the quota
+calculation. The default value is:
+</para>
+<literallayout class="monospaced">
+maildir_quota_directory_regex = ^(?:cur|new|\..*)$
+</literallayout>
+<para>
+This includes the <filename>cur</filename> and <filename>new</filename> directories, and any maildir++ folders
+(directories whose names begin with a dot). If you want to exclude the
+<filename>Trash</filename>
+folder from the count (as some sites do), you need to change this setting to
+</para>
+<literallayout class="monospaced">
+maildir_quota_directory_regex = ^(?:cur|new|\.(?!Trash).*)$
+</literallayout>
+<para>
+This uses a negative lookahead in the regular expression to exclude the
+directory whose name is <filename>.Trash</filename>. When a directory is excluded from quota
+calculations, quota processing is bypassed for any messages that are delivered
+directly into that directory.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>maildir_retries</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>maildir_retries</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>10</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies the number of times to retry when writing a file in
+<quote>maildir</quote> format. See section <xref linkend="SECTmaildirdelivery"/> below.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>maildir_tag</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>maildir_tag</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option applies only to deliveries in maildir format, and is described in
+section <xref linkend="SECTmaildirdelivery"/> below.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>maildir_use_size_file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>maildir_use_size_file</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis>†<emphasis></emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>maildir format</primary>
+<secondary><filename>maildirsize</filename> file</secondary>
+</indexterm>
+The result of string expansion for this option must be a valid boolean value.
+If it is true, it enables support for <filename>maildirsize</filename> files. Exim
+creates a <filename>maildirsize</filename> file in a maildir if one does not exist, taking the
+quota from the <option>quota</option> option of the transport. If <option>quota</option> is unset, the
+value is zero. See <option>maildir_quota_directory_regex</option> above and section
+<xref linkend="SECTmaildirdelivery"/> below for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>maildirfolder_create_regex</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>maildirfolder_create_regex</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>maildir format</primary>
+<secondary><filename>maildirfolder</filename> file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><filename>maildirfolder</filename>, creating</primary>
+</indexterm>
+The value of this option is a regular expression. If it is unset, it has no
+effect. Otherwise, before a maildir delivery takes place, the pattern is
+matched against the name of the maildir directory, that is, the directory
+containing the <filename>new</filename> and <filename>tmp</filename> subdirectories that will be used for the
+delivery. If there is a match, Exim checks for the existence of a file called
+<filename>maildirfolder</filename> in the directory, and creates it if it does not exist.
+See section <xref linkend="SECTmaildirdelivery"/> for more details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mailstore_format</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>mailstore_format</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>mailstore format</primary>
+<secondary>specifying</secondary>
+</indexterm>
+If this option is set with the <option>directory</option> option, the delivery is into two
+new files in <quote>mailstore</quote> format. The option is available only if
+SUPPORT_MAILSTORE is present in <filename>Local/Makefile</filename>. See section <xref linkend="SECTopdir"/>
+below for further details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mailstore_prefix</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>mailstore_prefix</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option applies only to deliveries in mailstore format, and is described in
+section <xref linkend="SECTopdir"/> below.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mailstore_suffix</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>mailstore_suffix</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option applies only to deliveries in mailstore format, and is described in
+section <xref linkend="SECTopdir"/> below.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mbx_format</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>mbx_format</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>locking files</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>locking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>MBX format</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>MBX format, specifying</primary>
+</indexterm>
+This option is available only if Exim has been compiled with SUPPORT_MBX
+set in <filename>Local/Makefile</filename>. If <option>mbx_format</option> is set with the <option>file</option> option,
+the message is appended to the mailbox file in MBX format instead of
+traditional Unix format. This format is supported by Pine4 and its associated
+IMAP and POP daemons, by means of the <emphasis>c-client</emphasis> library that they all use.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: The <option>message_prefix</option> and <option>message_suffix</option> options are not
+automatically changed by the use of <option>mbx_format</option>. They should normally be set
+empty when using MBX format, so this option almost always appears in this
+combination:
+</para>
+<literallayout class="monospaced">
+mbx_format = true
+message_prefix =
+message_suffix =
+</literallayout>
+<para>
+If none of the locking options are mentioned in the configuration,
+<option>use_mbx_lock</option> is assumed and the other locking options default to false. It
+is possible to specify the other kinds of locking with <option>mbx_format</option>, but
+<option>use_fcntl_lock</option> and <option>use_mbx_lock</option> are mutually exclusive. MBX locking
+interworks with <emphasis>c-client</emphasis>, providing for shared access to the mailbox. It
+should not be used if any program that does not use this form of locking is
+going to access the mailbox, nor should it be used if the mailbox file is NFS
+mounted, because it works only when the mailbox is accessed from a single host.
+</para>
+<para>
+If you set <option>use_fcntl_lock</option> with an MBX-format mailbox, you cannot use
+the standard version of <emphasis>c-client</emphasis>, because as long as it has a mailbox open
+(this means for the whole of a Pine or IMAP session), Exim will not be able to
+append messages to it.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>message_prefix</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>message_prefix</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><quote>From</quote> line</primary>
+</indexterm>
+The string specified here is expanded and output at the start of every message.
+The default is unset unless <option>file</option> is specified and <option>use_bsmtp</option> is not set,
+in which case it is:
+</para>
+<literallayout class="monospaced">
+message_prefix = "From ${if def:return_path{$return_path}\
+ {MAILER-DAEMON}} $tod_bsdinbox\n"
+</literallayout>
+<para>
+<emphasis role="bold">Note:</emphasis> If you set <option>use_crlf</option> true, you must change any occurrences of
+<literal>\n</literal> to <literal>\r\n</literal> in <option>message_prefix</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>message_suffix</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>message_suffix</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+The string specified here is expanded and output at the end of every message.
+The default is unset unless <option>file</option> is specified and <option>use_bsmtp</option> is not set,
+in which case it is a single newline character. The suffix can be suppressed by
+setting
+</para>
+<literallayout class="monospaced">
+message_suffix =
+</literallayout>
+<para>
+<emphasis role="bold">Note:</emphasis> If you set <option>use_crlf</option> true, you must change any occurrences of
+<literal>\n</literal> to <literal>\r\n</literal> in <option>message_suffix</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mode</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>mode</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>octal integer</emphasis></entry>
+<entry>Default: <emphasis>0600</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If the output file is created, it is given this mode. If it already exists and
+has wider permissions, they are reduced to this mode. If it has narrower
+permissions, an error occurs unless <option>mode_fail_narrower</option> is false. However,
+if the delivery is the result of a <option>save</option> command in a filter file specifying
+a particular mode, the mode of the output file is always forced to take that
+value, and this option is ignored.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mode_fail_narrower</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>mode_fail_narrower</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option applies in the case when an existing mailbox file has a narrower
+mode than that specified by the <option>mode</option> option. If <option>mode_fail_narrower</option> is
+true, the delivery is deferred (<quote>mailbox has the wrong mode</quote>); otherwise Exim
+continues with the delivery attempt, using the existing mode of the file.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>notify_comsat</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>notify_comsat</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is true, the <emphasis>comsat</emphasis> daemon is notified after every
+successful delivery to a user mailbox. This is the daemon that notifies logged
+on users about incoming mail.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>quota</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>quota</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>quota</primary>
+<secondary>imposed by Exim</secondary>
+</indexterm>
+This option imposes a limit on the size of the file to which Exim is appending,
+or to the total space used in the directory tree when the <option>directory</option> option
+is set. In the latter case, computation of the space used is expensive, because
+all the files in the directory (and any sub-directories) have to be
+individually inspected and their sizes summed. (See <option>quota_size_regex</option> and
+<option>maildir_use_size_file</option> for ways to avoid this in environments where users
+have no shell access to their mailboxes).
+</para>
+<para>
+As there is no interlock against two simultaneous deliveries into a
+multi-file mailbox, it is possible for the quota to be overrun in this case.
+For single-file mailboxes, of course, an interlock is a necessity.
+</para>
+<para>
+A file’s size is taken as its <emphasis>used</emphasis> value. Because of blocking effects, this
+may be a lot less than the actual amount of disk space allocated to the file.
+If the sizes of a number of files are being added up, the rounding effect can
+become quite noticeable, especially on systems that have large block sizes.
+Nevertheless, it seems best to stick to the <emphasis>used</emphasis> figure, because this is
+the obvious value which users understand most easily.
+</para>
+<para>
+The value of the option is expanded, and must then be a numerical value
+(decimal point allowed), optionally followed by one of the letters K, M, or G,
+for kilobytes, megabytes, or gigabytes, optionally followed by a slash
+and further option modifiers. If Exim is running on a system with
+large file support (Linux and FreeBSD have this), mailboxes larger than 2G can
+be handled.
+</para>
+<para>
+The option modifier <option>no_check</option> can be used to force delivery even if the over
+quota condition is met. The quota gets updated as usual.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: A value of zero is interpreted as <quote>no quota</quote>.
+</para>
+<para>
+The expansion happens while Exim is running as root, before it changes uid for
+the delivery. This means that files that are inaccessible to the end user can
+be used to hold quota values that are looked up in the expansion. When delivery
+fails because this quota is exceeded, the handling of the error is as for
+system quota failures.
+</para>
+<para>
+By default, Exim’s quota checking mimics system quotas, and restricts the
+mailbox to the specified maximum size, though the value is not accurate to the
+last byte, owing to separator lines and additional headers that may get added
+during message delivery. When a mailbox is nearly full, large messages may get
+refused even though small ones are accepted, because the size of the current
+message is added to the quota when the check is made. This behaviour can be
+changed by setting <option>quota_is_inclusive</option> false. When this is done, the check
+for exceeding the quota does not include the current message. Thus, deliveries
+continue until the quota has been exceeded; thereafter, no further messages are
+delivered. See also <option>quota_warn_threshold</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>quota_directory</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>quota_directory</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option defines the directory to check for quota purposes when delivering
+into individual files. The default is the delivery directory, or, if a file
+called <filename>maildirfolder</filename> exists in a maildir directory, the parent of the
+delivery directory.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>quota_filecount</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>quota_filecount</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>0</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option applies when the <option>directory</option> option is set. It limits the total
+number of files in the directory (compare the inode limit in system quotas). It
+can only be used if <option>quota</option> is also set. The value is expanded; an expansion
+failure causes delivery to be deferred. A value of zero is interpreted as
+<quote>no quota</quote>.
+</para>
+<para>
+The option modifier <option>no_check</option> can be used to force delivery even if the over
+quota condition is met. The quota gets updated as usual.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>quota_is_inclusive</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>quota_is_inclusive</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>quota</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>quota_size_regex</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>quota_size_regex</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option applies when one of the delivery modes that writes a separate file
+for each message is being used. When Exim wants to find the size of one of
+these files in order to test the quota, it first checks <option>quota_size_regex</option>.
+If this is set to a regular expression that matches the filename, and it
+captures one string, that string is interpreted as a representation of the
+file’s size. The value of <option>quota_size_regex</option> is not expanded.
+</para>
+<para>
+This feature is useful only when users have no shell access to their mailboxes
+– otherwise they could defeat the quota simply by renaming the files. This
+facility can be used with maildir deliveries, by setting <option>maildir_tag</option> to add
+the file length to the filename. For example:
+</para>
+<literallayout class="monospaced">
+maildir_tag = ,S=$message_size
+quota_size_regex = ,S=(\d+)
+</literallayout>
+<para>
+An alternative to <varname>$message_size</varname> is <varname>$message_linecount</varname>, which contains the
+number of lines in the message.
+</para>
+<para>
+The regular expression should not assume that the length is at the end of the
+filename (even though <option>maildir_tag</option> puts it there) because maildir MUAs
+sometimes add other information onto the ends of message filenames.
+</para>
+<para>
+Section <xref linkend="SECID136"/> contains further information.
+</para>
+<para>
+This option should not be used when other message-handling software
+may duplicate messages by making hardlinks to the files. When that is done Exim
+will count the message size once for each filename, in contrast with the actual
+disk usage. When the option is not set, calculating total usage requires
+a system-call per file to get the size; the number of links is then available also
+as is used to adjust the effective size.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>quota_warn_message</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>quota_warn_message</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See below for the use of this option. If it is not set when
+<option>quota_warn_threshold</option> is set, it defaults to
+</para>
+<literallayout class="monospaced">
+quota_warn_message = "\
+ To: $local_part@$domain\n\
+ Subject: Your mailbox\n\n\
+ This message is automatically created \
+ by mail delivery software.\n\n\
+ The size of your mailbox has exceeded \
+ a warning threshold that is\n\
+ set by the system administrator.\n"
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>quota_warn_threshold</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>quota_warn_threshold</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>0</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>quota</primary>
+<secondary>warning threshold</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>mailbox</primary>
+<secondary>size warning</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>size</primary>
+<secondary>of mailbox</secondary>
+</indexterm>
+This option is expanded in the same way as <option>quota</option> (see above). If the
+resulting value is greater than zero, and delivery of the message causes the
+size of the file or total space in the directory tree to cross the given
+threshold, a warning message is sent. If <option>quota</option> is also set, the threshold
+may be specified as a percentage of it by following the value with a percent
+sign. For example:
+</para>
+<literallayout class="monospaced">
+quota = 10M
+quota_warn_threshold = 75%
+</literallayout>
+<para>
+If <option>quota</option> is not set, a setting of <option>quota_warn_threshold</option> that ends with a
+percent sign is ignored.
+</para>
+<para>
+The warning message itself is specified by the <option>quota_warn_message</option> option,
+and it must start with a <emphasis>To:</emphasis> header line containing the recipient(s) of the
+warning message. These do not necessarily have to include the recipient(s) of
+the original message. A <emphasis>Subject:</emphasis> line should also normally be supplied. You
+can include any other header lines that you want. If you do not include a
+<emphasis>From:</emphasis> line, the default is:
+</para>
+<literallayout class="monospaced">
+From: Mail Delivery System <mailer-daemon@$qualify_domain_sender>
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>errors_reply_to</option></primary>
+</indexterm>
+If you supply a <emphasis>Reply-To:</emphasis> line, it overrides the global <option>errors_reply_to</option>
+option.
+</para>
+<para>
+The <option>quota</option> option does not have to be set in order to use this option; they
+are independent of one another except when the threshold is specified as a
+percentage.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>use_bsmtp</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>use_bsmtp</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>envelope from</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope sender</primary>
+</indexterm>
+If this option is set true, <command>appendfile</command> writes messages in <quote>batch SMTP</quote>
+format, with the envelope sender and recipient(s) included as SMTP commands. If
+you want to include a leading HELO command with such messages, you can do
+so by setting the <option>message_prefix</option> option. See section <xref linkend="SECTbatchSMTP"/>
+for details of batch SMTP.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>use_crlf</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>use_crlf</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>carriage return</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>linefeed</primary>
+</indexterm>
+This option causes lines to be terminated with the two-character CRLF sequence
+(carriage return, linefeed) instead of just a linefeed character. In the case
+of batched SMTP, the byte sequence written to the file is then an exact image
+of what would be sent down a real SMTP connection.
+</para>
+<para>
+<emphasis role="bold">Note:</emphasis> The contents of the <option>message_prefix</option> and <option>message_suffix</option> options
+(which are used to supply the traditional <quote>From </quote> and blank line separators
+in Berkeley-style mailboxes) are written verbatim, so must contain their own
+carriage return characters if these are needed. In cases where these options
+have non-empty defaults, the values end with a single linefeed, so they must be
+changed to end with <literal>\r\n</literal> if <option>use_crlf</option> is set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>use_fcntl_lock</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>use_fcntl_lock</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option controls the use of the <function>fcntl()</function> function to lock a file for
+exclusive use when a message is being appended. It is set by default unless
+<option>use_flock_lock</option> is set. Otherwise, it should be turned off only if you know
+that all your MUAs use lock file locking. When both <option>use_fcntl_lock</option> and
+<option>use_flock_lock</option> are unset, <option>use_lockfile</option> must be set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>use_flock_lock</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>use_flock_lock</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option is provided to support the use of <function>flock()</function> for file locking, for
+the few situations where it is needed. Most modern operating systems support
+<function>fcntl()</function> and <function>lockf()</function> locking, and these two functions interwork with
+each other. Exim uses <function>fcntl()</function> locking by default.
+</para>
+<para>
+This option is required only if you are using an operating system where
+<function>flock()</function> is used by programs that access mailboxes (typically MUAs), and
+where <function>flock()</function> does not correctly interwork with <function>fcntl()</function>. You can use
+both <function>fcntl()</function> and <function>flock()</function> locking simultaneously if you want.
+</para>
+<para>
+<indexterm role="concept">
+<primary>Solaris</primary>
+<secondary><function>flock()</function> support</secondary>
+</indexterm>
+Not all operating systems provide <function>flock()</function>. Some versions of Solaris do not
+have it (and some, I think, provide a not quite right version built on top of
+<function>lockf()</function>). If the OS does not have <function>flock()</function>, Exim will be built without
+the ability to use it, and any attempt to do so will cause a configuration
+error.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: <function>flock()</function> locks do not work on NFS files (unless <function>flock()</function>
+is just being mapped onto <function>fcntl()</function> by the OS).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>use_lockfile</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>use_lockfile</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is turned off, Exim does not attempt to create a lock file when
+appending to a mailbox file. In this situation, the only locking is by
+<function>fcntl()</function>. You should only turn <option>use_lockfile</option> off if you are absolutely
+sure that every MUA that is ever going to look at your users’ mailboxes uses
+<function>fcntl()</function> rather than a lock file, and even then only when you are not
+delivering over NFS from more than one host.
+</para>
+<para>
+<indexterm role="concept">
+<primary>NFS</primary>
+<secondary>lock file</secondary>
+</indexterm>
+In order to append to an NFS file safely from more than one host, it is
+necessary to take out a lock <emphasis>before</emphasis> opening the file, and the lock file
+achieves this. Otherwise, even with <function>fcntl()</function> locking, there is a risk of
+file corruption.
+</para>
+<para>
+The <option>use_lockfile</option> option is set by default unless <option>use_mbx_lock</option> is set.
+It is not possible to turn both <option>use_lockfile</option> and <option>use_fcntl_lock</option> off,
+except when <option>mbx_format</option> is set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>use_mbx_lock</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>use_mbx_lock</option></entry>
+<entry>Use: <emphasis>appendfile</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option is available only if Exim has been compiled with SUPPORT_MBX
+set in <filename>Local/Makefile</filename>. Setting the option specifies that special MBX
+locking rules be used. It is set by default if <option>mbx_format</option> is set and none
+of the locking options are mentioned in the configuration. The locking rules
+are the same as are used by the <emphasis>c-client</emphasis> library that underlies Pine and
+the IMAP4 and POP daemons that come with it (see the discussion below). The
+rules allow for shared access to the mailbox. However, this kind of locking
+does not work when the mailbox is NFS mounted.
+</para>
+<para>
+You can set <option>use_mbx_lock</option> with either (or both) of <option>use_fcntl_lock</option> and
+<option>use_flock_lock</option> to control what kind of locking is used in implementing the
+MBX locking rules. The default is to use <function>fcntl()</function> if <option>use_mbx_lock</option> is set
+without <option>use_fcntl_lock</option> or <option>use_flock_lock</option>.
+</para>
+</section>
+<section id="SECTopappend">
+<title>Operational details for appending</title>
+<para>
+<indexterm role="concept">
+<primary>appending to a file</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>appending</secondary>
+</indexterm>
+Before appending to a file, the following preparations are made:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If the name of the file is <filename>/dev/null</filename>, no action is taken, and a success
+return is given.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>directory creation</primary>
+</indexterm>
+If any directories on the file’s path are missing, Exim creates them if the
+<option>create_directory</option> option is set. A created directory’s mode is given by the
+<option>directory_mode</option> option.
+</para>
+</listitem>
+<listitem>
+<para>
+If <option>file_format</option> is set, the format of an existing file is checked. If this
+indicates that a different transport should be used, control is passed to that
+transport.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>locking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>locking files</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>NFS</primary>
+<secondary>lock file</secondary>
+</indexterm>
+If <option>use_lockfile</option> is set, a lock file is built in a way that will work
+reliably over NFS, as follows:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+Create a <quote>hitching post</quote> file whose name is that of the lock file with the
+current time, primary host name, and process id added, by opening for writing
+as a new file. If this fails with an access error, delivery is deferred.
+</para>
+</listitem>
+<listitem>
+<para>
+Close the hitching post file, and hard link it to the lock filename.
+</para>
+</listitem>
+<listitem>
+<para>
+If the call to <function>link()</function> succeeds, creation of the lock file has succeeded.
+Unlink the hitching post name.
+</para>
+</listitem>
+<listitem>
+<para>
+Otherwise, use <function>stat()</function> to get information about the hitching post file, and
+then unlink hitching post name. If the number of links is exactly two, creation
+of the lock file succeeded but something (for example, an NFS server crash and
+restart) caused this fact not to be communicated to the <function>link()</function> call.
+</para>
+</listitem>
+<listitem>
+<para>
+If creation of the lock file failed, wait for <option>lock_interval</option> and try again,
+up to <option>lock_retries</option> times. However, since any program that writes to a
+mailbox should complete its task very quickly, it is reasonable to time out old
+lock files that are normally the result of user agent and system crashes. If an
+existing lock file is older than <option>lockfile_timeout</option> Exim attempts to unlink
+it before trying again.
+</para>
+</listitem>
+</orderedlist>
+</listitem>
+<listitem>
+<para>
+A call is made to <function>lstat()</function> to discover whether the main file exists, and if
+so, what its characteristics are. If <function>lstat()</function> fails for any reason other
+than non-existence, delivery is deferred.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>symbolic link</primary>
+<secondary>to mailbox</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>mailbox</primary>
+<secondary>symbolic link</secondary>
+</indexterm>
+If the file does exist and is a symbolic link, delivery is deferred, unless the
+<option>allow_symlink</option> option is set, in which case the ownership of the link is
+checked, and then <function>stat()</function> is called to find out about the real file, which
+is then subjected to the checks below. The check on the top-level link
+ownership prevents one user creating a link for another’s mailbox in a sticky
+directory, though allowing symbolic links in this case is definitely not a good
+idea. If there is a chain of symbolic links, the intermediate ones are not
+checked.
+</para>
+</listitem>
+<listitem>
+<para>
+If the file already exists but is not a regular file, or if the file’s owner
+and group (if the group is being checked – see <option>check_group</option> above) are
+different from the user and group under which the delivery is running,
+delivery is deferred.
+</para>
+</listitem>
+<listitem>
+<para>
+If the file’s permissions are more generous than specified, they are reduced.
+If they are insufficient, delivery is deferred, unless <option>mode_fail_narrower</option>
+is set false, in which case the delivery is tried using the existing
+permissions.
+</para>
+</listitem>
+<listitem>
+<para>
+The file’s inode number is saved, and the file is then opened for appending.
+If this fails because the file has vanished, <command>appendfile</command> behaves as if it
+hadn’t existed (see below). For any other failures, delivery is deferred.
+</para>
+</listitem>
+<listitem>
+<para>
+If the file is opened successfully, check that the inode number hasn’t
+changed, that it is still a regular file, and that the owner and permissions
+have not changed. If anything is wrong, defer delivery and freeze the message.
+</para>
+</listitem>
+<listitem>
+<para>
+If the file did not exist originally, defer delivery if the <option>file_must_exist</option>
+option is set. Otherwise, check that the file is being created in a permitted
+directory if the <option>create_file</option> option is set (deferring on failure), and then
+open for writing as a new file, with the O_EXCL and O_CREAT options,
+except when dealing with a symbolic link (the <option>allow_symlink</option> option must be
+set). In this case, which can happen if the link points to a non-existent file,
+the file is opened for writing using O_CREAT but not O_EXCL, because
+that prevents link following.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>loop</primary>
+<secondary>while file testing</secondary>
+</indexterm>
+If opening fails because the file exists, obey the tests given above for
+existing files. However, to avoid looping in a situation where the file is
+being continuously created and destroyed, the exists/not-exists loop is broken
+after 10 repetitions, and the message is then frozen.
+</para>
+</listitem>
+<listitem>
+<para>
+If opening fails with any other error, defer delivery.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>file</primary>
+<secondary>locking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>locking files</primary>
+</indexterm>
+Once the file is open, unless both <option>use_fcntl_lock</option> and <option>use_flock_lock</option>
+are false, it is locked using <function>fcntl()</function> or <function>flock()</function> or both. If
+<option>use_mbx_lock</option> is false, an exclusive lock is requested in each case.
+However, if <option>use_mbx_lock</option> is true, Exim takes out a shared lock on the open
+file, and an exclusive lock on the file whose name is
+</para>
+<literallayout class="monospaced">
+/tmp/.<device-number>.<inode-number>
+</literallayout>
+<para>
+using the device and inode numbers of the open mailbox file, in accordance with
+the MBX locking rules. This file is created with a mode that is specified by
+the <option>lockfile_mode</option> option.
+</para>
+<para>
+If Exim fails to lock the file, there are two possible courses of action,
+depending on the value of the locking timeout. This is obtained from
+<option>lock_fcntl_timeout</option> or <option>lock_flock_timeout</option>, as appropriate.
+</para>
+<para>
+If the timeout value is zero, the file is closed, Exim waits for
+<option>lock_interval</option>, and then goes back and re-opens the file as above and tries
+to lock it again. This happens up to <option>lock_retries</option> times, after which the
+delivery is deferred.
+</para>
+<para>
+If the timeout has a value greater than zero, blocking calls to <function>fcntl()</function> or
+<function>flock()</function> are used (with the given timeout), so there has already been some
+waiting involved by the time locking fails. Nevertheless, Exim does not give up
+immediately. It retries up to
+</para>
+<literallayout class="monospaced">
+(lock_retries * lock_interval) / <timeout>
+</literallayout>
+<para>
+times (rounded up).
+</para>
+</listitem>
+</itemizedlist>
+<para>
+At the end of delivery, Exim closes the file (which releases the <function>fcntl()</function>
+and/or <function>flock()</function> locks) and then deletes the lock file if one was created.
+</para>
+</section>
+<section id="SECTopdir">
+<title>Operational details for delivery to a new file</title>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>to single file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><quote>From</quote> line</primary>
+</indexterm>
+When the <option>directory</option> option is set instead of <option>file</option>, each message is
+delivered into a newly-created file or set of files. When <command>appendfile</command> is
+activated directly from a <command>redirect</command> router, neither <option>file</option> nor
+<option>directory</option> is normally set, because the path for delivery is supplied by the
+router. (See for example, the <command>address_file</command> transport in the default
+configuration.) In this case, delivery is to a new file if either the path name
+ends in <literal>/</literal>, or the <option>maildir_format</option> or <option>mailstore_format</option> option is set.
+</para>
+<para>
+No locking is required while writing the message to a new file, so the various
+locking options of the transport are ignored. The <quote>From</quote> line that by default
+separates messages in a single file is not normally needed, nor is the escaping
+of message lines that start with <quote>From</quote>, and there is no need to ensure a
+newline at the end of each message. Consequently, the default values for
+<option>check_string</option>, <option>message_prefix</option>, and <option>message_suffix</option> are all unset when
+any of <option>directory</option>, <option>maildir_format</option>, or <option>mailstore_format</option> is set.
+</para>
+<para>
+If Exim is required to check a <option>quota</option> setting, it adds up the sizes of all
+the files in the delivery directory by default. However, you can specify a
+different directory by setting <option>quota_directory</option>. Also, for maildir
+deliveries (see below) the <filename>maildirfolder</filename> convention is honoured.
+</para>
+<para>
+<indexterm role="concept">
+<primary>maildir format</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>mailstore format</primary>
+</indexterm>
+There are three different ways in which delivery to individual files can be
+done, controlled by the settings of the <option>maildir_format</option> and
+<option>mailstore_format</option> options. Note that code to support maildir or mailstore
+formats is not included in the binary unless SUPPORT_MAILDIR or
+SUPPORT_MAILSTORE, respectively, is set in <filename>Local/Makefile</filename>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>directory creation</primary>
+</indexterm>
+In all three cases an attempt is made to create the directory and any necessary
+sub-directories if they do not exist, provided that the <option>create_directory</option>
+option is set (the default). The location of a created directory can be
+constrained by setting <option>create_file</option>. A created directory’s mode is given by
+the <option>directory_mode</option> option. If creation fails, or if the
+<option>create_directory</option> option is not set when creation is required, delivery is
+deferred.
+</para>
+</section>
+<section id="SECTmaildirdelivery">
+<title>Maildir delivery</title>
+<para>
+<indexterm role="concept">
+<primary>maildir format</primary>
+<secondary>description of</secondary>
+</indexterm>
+If the <option>maildir_format</option> option is true, Exim delivers each message by writing
+it to a file whose name is <filename>tmp/<stime>.H<mtime>P<pid>.<host></filename> in the
+directory that is defined by the <option>directory</option> option (the <quote>delivery
+directory</quote>). If the delivery is successful, the file is renamed into the
+<filename>new</filename> subdirectory.
+</para>
+<para>
+In the filename, <<emphasis>stime</emphasis>> is the current time of day in seconds, and
+<<emphasis>mtime</emphasis>> is the microsecond fraction of the time. After a maildir delivery,
+Exim checks that the time-of-day clock has moved on by at least one microsecond
+before terminating the delivery process. This guarantees uniqueness for the
+filename. However, as a precaution, Exim calls <function>stat()</function> for the file before
+opening it. If any response other than ENOENT (does not exist) is given,
+Exim waits 2 seconds and tries again, up to <option>maildir_retries</option> times.
+</para>
+<para>
+Before Exim carries out a maildir delivery, it ensures that subdirectories
+called <filename>new</filename>, <filename>cur</filename>, and <filename>tmp</filename> exist in the delivery directory. If they
+do not exist, Exim tries to create them and any superior directories in their
+path, subject to the <option>create_directory</option> and <option>create_file</option> options. If the
+<option>maildirfolder_create_regex</option> option is set, and the regular expression it
+contains matches the delivery directory, Exim also ensures that a file called
+<filename>maildirfolder</filename> exists in the delivery directory. If a missing directory or
+<filename>maildirfolder</filename> file cannot be created, delivery is deferred.
+</para>
+<para>
+These features make it possible to use Exim to create all the necessary files
+and directories in a maildir mailbox, including subdirectories for maildir++
+folders. Consider this example:
+</para>
+<literallayout class="monospaced">
+maildir_format = true
+directory = /var/mail/$local_part_data\
+ ${if eq{$local_part_suffix}{}{}\
+ {/.${substr_1:$local_part_suffix}}}
+maildirfolder_create_regex = /\.[^/]+$
+</literallayout>
+<para>
+If <varname>$local_part_suffix</varname> is empty (there was no suffix for the local part),
+delivery is into a toplevel maildir with a name like <filename>/var/mail/pimbo</filename> (for
+the user called <emphasis>pimbo</emphasis>). The pattern in <option>maildirfolder_create_regex</option> does
+not match this name, so Exim will not look for or create the file
+<filename>/var/mail/pimbo/maildirfolder</filename>, though it will create
+<filename>/var/mail/pimbo/{cur,new,tmp}</filename> if necessary.
+</para>
+<para>
+However, if <varname>$local_part_suffix</varname> contains <literal>-eximusers</literal> (for example),
+delivery is into the maildir++ folder <filename>/var/mail/pimbo/.eximusers</filename>, which
+does match <option>maildirfolder_create_regex</option>. In this case, Exim will create
+<filename>/var/mail/pimbo/.eximusers/maildirfolder</filename> as well as the three maildir
+directories <filename>/var/mail/pimbo/.eximusers/{cur,new,tmp}</filename>.
+</para>
+<para>
+<emphasis role="bold">Warning:</emphasis> Take care when setting <option>maildirfolder_create_regex</option> that it does
+not inadvertently match the toplevel maildir directory, because a
+<filename>maildirfolder</filename> file at top level would completely break quota calculations.
+</para>
+<para>
+<indexterm role="concept">
+<primary>quota</primary>
+<secondary>in maildir delivery</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>maildir++</primary>
+</indexterm>
+If Exim is required to check a <option>quota</option> setting before a maildir delivery, and
+<option>quota_directory</option> is not set, it looks for a file called <filename>maildirfolder</filename> in
+the maildir directory (alongside <filename>new</filename>, <filename>cur</filename>, <filename>tmp</filename>). If this exists,
+Exim assumes the directory is a maildir++ folder directory, which is one level
+down from the user’s top level mailbox directory. This causes it to start at
+the parent directory instead of the current directory when calculating the
+amount of space used.
+</para>
+<para>
+One problem with delivering into a multi-file mailbox is that it is
+computationally expensive to compute the size of the mailbox for quota
+checking. Various approaches have been taken to reduce the amount of work
+needed. The next two sections describe two of them. A third alternative is to
+use some external process for maintaining the size data, and use the expansion
+of the <option>mailbox_size</option> option as a way of importing it into Exim.
+</para>
+</section>
+<section id="SECID135">
+<title>Using tags to record message sizes</title>
+<para>
+If <option>maildir_tag</option> is set, the string is expanded for each delivery.
+When the maildir file is renamed into the <filename>new</filename> sub-directory, the
+tag is added to its name. However, if adding the tag takes the length of the
+name to the point where the test <function>stat()</function> call fails with ENAMETOOLONG,
+the tag is dropped and the maildir file is created with no tag.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$message_size</varname></primary>
+</indexterm>
+Tags can be used to encode the size of files in their names; see
+<option>quota_size_regex</option> above for an example. The expansion of <option>maildir_tag</option>
+happens after the message has been written. The value of the <varname>$message_size</varname>
+variable is set to the number of bytes actually written. If the expansion is
+forced to fail, the tag is ignored, but a non-forced failure causes delivery to
+be deferred. The expanded tag may contain any printing characters except <quote>/</quote>.
+Non-printing characters in the string are ignored; if the resulting string is
+empty, it is ignored. If it starts with an alphanumeric character, a leading
+colon is inserted; this default has not proven to be the path that popular
+maildir implementations have chosen (but changing it in Exim would break
+backwards compatibility).
+</para>
+<para>
+For one common implementation, you might set:
+</para>
+<literallayout class="monospaced">
+maildir_tag = ,S=${message_size}
+</literallayout>
+<para>
+but you should check the documentation of the other software to be sure.
+</para>
+<para>
+It is advisable to also set <option>quota_size_regex</option> when setting <option>maildir_tag</option>
+as this allows Exim to extract the size from your tag, instead of having to
+<function>stat()</function> each message file.
+</para>
+</section>
+<section id="SECID136">
+<title>Using a maildirsize file</title>
+<para>
+<indexterm role="concept">
+<primary>quota</primary>
+<secondary>in maildir delivery</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>maildir format</primary>
+<secondary><filename>maildirsize</filename> file</secondary>
+</indexterm>
+If <option>maildir_use_size_file</option> is true, Exim implements the maildir++ rules for
+storing quota and message size information in a file called <filename>maildirsize</filename>
+within the toplevel maildir directory. If this file does not exist, Exim
+creates it, setting the quota from the <option>quota</option> option of the transport. If
+the maildir directory itself does not exist, it is created before any attempt
+to write a <filename>maildirsize</filename> file.
+</para>
+<para>
+The <filename>maildirsize</filename> file is used to hold information about the sizes of
+messages in the maildir, thus speeding up quota calculations. The quota value
+in the file is just a cache; if the quota is changed in the transport, the new
+value overrides the cached value when the next message is delivered. The cache
+is maintained for the benefit of other programs that access the maildir and
+need to know the quota.
+</para>
+<para>
+If the <option>quota</option> option in the transport is unset or zero, the <filename>maildirsize</filename>
+file is maintained (with a zero quota setting), but no quota is imposed.
+</para>
+<para>
+A regular expression is available for controlling which directories in the
+maildir participate in quota calculations when a <filename>maildirsizefile</filename> is in use.
+See the description of the <option>maildir_quota_directory_regex</option> option above for
+details.
+</para>
+</section>
+<section id="SECID137">
+<title>Mailstore delivery</title>
+<para>
+<indexterm role="concept">
+<primary>mailstore format</primary>
+<secondary>description of</secondary>
+</indexterm>
+If the <option>mailstore_format</option> option is true, each message is written as two
+files in the given directory. A unique base name is constructed from the
+message id and the current delivery process, and the files that are written use
+this base name plus the suffixes <filename>.env</filename> and <filename>.msg</filename>. The <filename>.env</filename> file
+contains the message’s envelope, and the <filename>.msg</filename> file contains the message
+itself. The base name is placed in the variable <varname>$mailstore_basename</varname>.
+</para>
+<para>
+During delivery, the envelope is first written to a file with the suffix
+<filename>.tmp</filename>. The <filename>.msg</filename> file is then written, and when it is complete, the
+<filename>.tmp</filename> file is renamed as the <filename>.env</filename> file. Programs that access messages in
+mailstore format should wait for the presence of both a <filename>.msg</filename> and a <filename>.env</filename>
+file before accessing either of them. An alternative approach is to wait for
+the absence of a <filename>.tmp</filename> file.
+</para>
+<para>
+The envelope file starts with any text defined by the <option>mailstore_prefix</option>
+option, expanded and terminated by a newline if there isn’t one. Then follows
+the sender address on one line, then all the recipient addresses, one per line.
+There can be more than one recipient only if the <option>batch_max</option> option is set
+greater than one. Finally, <option>mailstore_suffix</option> is expanded and the result
+appended to the file, followed by a newline if it does not end with one.
+</para>
+<para>
+If expansion of <option>mailstore_prefix</option> or <option>mailstore_suffix</option> ends with a forced
+failure, it is ignored. Other expansion errors are treated as serious
+configuration errors, and delivery is deferred. The variable
+<varname>$mailstore_basename</varname> is available for use during these expansions.
+</para>
+</section>
+<section id="SECID138">
+<title>Non-special new file delivery</title>
+<para>
+If neither <option>maildir_format</option> nor <option>mailstore_format</option> is set, a single new
+file is created directly in the named directory. For example, when delivering
+messages into files in batched SMTP format for later delivery to some host (see
+section <xref linkend="SECTbatchSMTP"/>), a setting such as
+</para>
+<literallayout class="monospaced">
+directory = /var/bsmtp/$host
+</literallayout>
+<para>
+might be used. A message is written to a file with a temporary name, which is
+then renamed when the delivery is complete. The final name is obtained by
+expanding the contents of the <option>directory_file</option> option.
+<indexterm role="concept" startref="IIDapptra1" class="endofrange"/>
+<indexterm role="concept" startref="IIDapptra2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHID8">
+<title>The autoreply transport</title>
+<para>
+<indexterm role="concept" id="IIDauttra1" class="startofrange">
+<primary>transports</primary>
+<secondary><command>autoreply</command></secondary>
+</indexterm>
+<indexterm role="concept" id="IIDauttra2" class="startofrange">
+<primary><command>autoreply</command> transport</primary>
+</indexterm>
+The <command>autoreply</command> transport is not a true transport in that it does not cause
+the message to be transmitted. Instead, it generates a new mail message as an
+automatic reply to the incoming message. <emphasis>References:</emphasis> and
+<emphasis>Auto-Submitted:</emphasis> header lines are included. These are constructed according
+to the rules in RFCs 2822 and 3834, respectively.
+</para>
+<para>
+If the router that passes the message to this transport does not have the
+<option>unseen</option> option set, the original message (for the current recipient) is not
+delivered anywhere. However, when the <option>unseen</option> option is set on the router
+that passes the message to this transport, routing of the address continues, so
+another router can set up a normal message delivery.
+</para>
+<para>
+The <command>autoreply</command> transport is usually run as the result of mail filtering, a
+<quote>vacation</quote> message being the standard example. However, it can also be run
+directly from a router like any other transport. To reduce the possibility of
+message cascades, messages created by the <command>autoreply</command> transport always have
+empty envelope sender addresses, like bounce messages.
+</para>
+<para>
+The parameters of the message to be sent can be specified in the configuration
+by options described below. However, these are used only when the address
+passed to the transport does not contain its own reply information. When the
+transport is run as a consequence of a
+<option>mail</option>
+or <option>vacation</option> command in a filter file, the parameters of the message are
+supplied by the filter, and passed with the address. The transport’s options
+that define the message are then ignored (so they are not usually set in this
+case). The message is specified entirely by the filter or by the transport; it
+is never built from a mixture of options. However, the <option>file_optional</option>,
+<option>mode</option>, and <option>return_message</option> options apply in all cases.
+</para>
+<para>
+<command>Autoreply</command> is implemented as a local transport. When used as a result of a
+command in a user’s filter file, <command>autoreply</command> normally runs under the uid and
+gid of the user, and with appropriate current and home directories (see chapter
+<xref linkend="CHAPenvironment"/>).
+</para>
+<para>
+There is a subtle difference between routing a message to a <command>pipe</command> transport
+that generates some text to be returned to the sender, and routing it to an
+<command>autoreply</command> transport. This difference is noticeable only if more than one
+address from the same message is so handled. In the case of a pipe, the
+separate outputs from the different addresses are gathered up and returned to
+the sender in a single message, whereas if <command>autoreply</command> is used, a separate
+message is generated for each address that is passed to it.
+</para>
+<para>
+Non-printing characters are not permitted in the header lines generated for the
+message that <command>autoreply</command> creates, with the exception of newlines that are
+immediately followed by white space. If any non-printing characters are found,
+the transport defers.
+Whether characters with the top bit set count as printing characters or not is
+controlled by the <option>print_topbitchars</option> global option.
+</para>
+<para>
+If any of the generic options for manipulating headers (for example,
+<option>headers_add</option>) are set on an <command>autoreply</command> transport, they apply to the copy
+of the original message that is included in the generated message when
+<option>return_message</option> is set. They do not apply to the generated message itself.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_address</varname></primary>
+</indexterm>
+If the <command>autoreply</command> transport receives return code 2 from Exim when it submits
+the message, indicating that there were no recipients, it does not treat this
+as an error. This means that autoreplies sent to <varname>$sender_address</varname> when this
+is empty (because the incoming message is a bounce message) do not cause
+problems. They are just discarded.
+</para>
+<section id="SECID139">
+<title>Private options for autoreply</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>autoreply</command> transport</secondary>
+</indexterm>
+</para>
+<para>
+<indexterm role="option">
+<primary><option>bcc</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>bcc</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies the addresses that are to receive <quote>blind carbon copies</quote> of the
+message when the message is specified by the transport.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>cc</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>cc</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies recipients of the message and the contents of the <emphasis>Cc:</emphasis> header
+when the message is specified by the transport.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>file</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>file</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+The contents of the file are sent as the body of the message when the message
+is specified by the transport. If both <option>file</option> and <option>text</option> are set, the text
+string comes first.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>file_expand</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>file_expand</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this is set, the contents of the file named by the <option>file</option> option are
+subjected to string expansion as they are added to the message.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>file_optional</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>file_optional</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is true, no error is generated if the file named by the <option>file</option>
+option or passed with the address does not exist or cannot be read.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>from</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>from</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies the contents of the <emphasis>From:</emphasis> header when the message is
+specified by the transport.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>headers</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>headers</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies additional RFC 2822 headers that are to be added to the message
+when the message is specified by the transport. Several can be given by using
+<quote>\n</quote> to separate them. There is no check on the format.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>log</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>log</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option names a file in which a record of every message sent is logged when
+the message is specified by the transport.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mode</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>mode</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>octal integer</emphasis></entry>
+<entry>Default: <emphasis>0600</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If either the log file or the <quote>once</quote> file has to be created, this mode is
+used.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>never_mail</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>never_mail</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>address list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If any run of the transport creates a message with a recipient that matches any
+item in the list, that recipient is quietly discarded. If all recipients are
+discarded, no message is created. This applies both when the recipients are
+generated by a filter and when they are specified in the transport.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>once</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>once</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option names a file or DBM database in which a record of each <emphasis>To:</emphasis>
+recipient is kept when the message is specified by the transport. <emphasis role="bold">Note</emphasis>:
+This does not apply to <emphasis>Cc:</emphasis> or <emphasis>Bcc:</emphasis> recipients.
+</para>
+<para>
+If <option>once</option> is unset, or is set to an empty string, the message is always sent.
+By default, if <option>once</option> is set to a non-empty filename, the message
+is not sent if a potential recipient is already listed in the database.
+However, if the <option>once_repeat</option> option specifies a time greater than zero, the
+message is sent if that much time has elapsed since a message was last sent to
+this recipient. A setting of zero time for <option>once_repeat</option> (the default)
+prevents a message from being sent a second time – in this case, zero means
+infinity.
+</para>
+<para>
+If <option>once_file_size</option> is zero, a DBM database is used to remember recipients,
+and it is allowed to grow as large as necessary. If <option>once_file_size</option> is set
+greater than zero, it changes the way Exim implements the <option>once</option> option.
+Instead of using a DBM file to record every recipient it sends to, it uses a
+regular file, whose size will never get larger than the given value.
+</para>
+<para>
+In the file, Exim keeps a linear list of recipient addresses and the times at
+which they were sent messages. If the file is full when a new address needs to
+be added, the oldest address is dropped. If <option>once_repeat</option> is not set, this
+means that a given recipient may receive multiple messages, but at
+unpredictable intervals that depend on the rate of turnover of addresses in the
+file. If <option>once_repeat</option> is set, it specifies a maximum time between repeats.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>once_file_size</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>once_file_size</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>0</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>once</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>once_repeat</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>once_repeat</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>0s</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>once</option> above.
+After expansion, the value of this option must be a valid time value.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>reply_to</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>reply_to</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies the contents of the <emphasis>Reply-To:</emphasis> header when the message is
+specified by the transport.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>return_message</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>return_message</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this is set, a copy of the original message is returned with the new
+message, subject to the maximum size set in the <option>return_size_limit</option> global
+configuration option.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>subject</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>subject</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies the contents of the <emphasis>Subject:</emphasis> header when the message is
+specified by the transport. It is tempting to quote the original subject in
+automatic responses. For example:
+</para>
+<literallayout class="monospaced">
+subject = Re: $h_subject:
+</literallayout>
+<para>
+There is a danger in doing this, however. It may allow a third party to
+subscribe your users to an opt-in mailing list, provided that the list accepts
+bounce messages as subscription confirmations. Well-managed lists require a
+non-bounce message to confirm a subscription, so the danger is relatively
+small.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>text</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>text</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies a single string to be used as the body of the message when the
+message is specified by the transport. If both <option>text</option> and <option>file</option> are set,
+the text comes first.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>to</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>to</option></entry>
+<entry>Use: <emphasis>autoreply</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies recipients of the message and the contents of the <emphasis>To:</emphasis> header
+when the message is specified by the transport.
+<indexterm role="concept" startref="IIDauttra1" class="endofrange"/>
+<indexterm role="concept" startref="IIDauttra2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPLMTP">
+<title>The lmtp transport</title>
+<para>
+<indexterm role="concept">
+<primary>transports</primary>
+<secondary><command>lmtp</command></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><command>lmtp</command> transport</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>LMTP</primary>
+<secondary>over a pipe</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>LMTP</primary>
+<secondary>over a socket</secondary>
+</indexterm>
+The <command>lmtp</command> transport runs the LMTP protocol (RFC 2033) over a pipe to a
+specified command
+or by interacting with a Unix domain socket.
+This transport is something of a cross between the <command>pipe</command> and <command>smtp</command>
+transports. Exim also has support for using LMTP over TCP/IP; this is
+implemented as an option for the <command>smtp</command> transport. Because LMTP is expected
+to be of minority interest, the default build-time configure in <filename>src/EDITME</filename>
+has it commented out. You need to ensure that
+</para>
+<literallayout class="monospaced">
+TRANSPORT_LMTP=yes
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>lmtp</command> transport</secondary>
+</indexterm>
+is present in your <filename>Local/Makefile</filename> in order to have the <command>lmtp</command> transport
+included in the Exim binary. The private options of the <command>lmtp</command> transport are
+as follows:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>batch_id</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>batch_id</option></entry>
+<entry>Use: <emphasis>lmtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See the description of local delivery batching in chapter <xref linkend="CHAPbatching"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>batch_max</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>batch_max</option></entry>
+<entry>Use: <emphasis>lmtp</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>1</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This limits the number of addresses that can be handled in a single delivery.
+Most LMTP servers can handle several addresses at once, so it is normally a
+good idea to increase this value. See the description of local delivery
+batching in chapter <xref linkend="CHAPbatching"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>command</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>command</option></entry>
+<entry>Use: <emphasis>lmtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option must be set if <option>socket</option> is not set. The string is a command which
+is run in a separate process. It is split up into a command name and list of
+arguments, each of which is separately expanded (so expansion cannot change the
+number of arguments). The command is run directly, not via a shell. The message
+is passed to the new process using the standard input and output to operate the
+LMTP protocol.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ignore_quota</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ignore_quota</option></entry>
+<entry>Use: <emphasis>lmtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>LMTP</primary>
+<secondary>ignoring quota errors</secondary>
+</indexterm>
+If this option is set true, the string <literal>IGNOREQUOTA</literal> is added to RCPT
+commands, provided that the LMTP server has advertised support for IGNOREQUOTA
+in its response to the LHLO command.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>socket</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>socket</option></entry>
+<entry>Use: <emphasis>lmtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option must be set if <option>command</option> is not set. The result of expansion must
+be the name of a Unix domain socket. The transport connects to the socket and
+delivers the message to it using the LMTP protocol.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>timeout</option></entry>
+<entry>Use: <emphasis>lmtp</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>5m</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+The transport is aborted if the created process or Unix domain socket does not
+respond to LMTP commands or message input within this timeout. Delivery
+is deferred, and will be tried again later. Here is an example of a typical
+LMTP transport:
+</para>
+<literallayout class="monospaced">
+lmtp:
+ driver = lmtp
+ command = /some/local/lmtp/delivery/program
+ batch_max = 20
+ user = exim
+</literallayout>
+<para>
+This delivers up to 20 addresses at a time, in a mixture of domains if
+necessary, running as the user <emphasis>exim</emphasis>.
+</para>
+</chapter>
+
+<chapter id="CHAPpipetransport">
+<title>The pipe transport</title>
+<para>
+<indexterm role="concept" id="IIDpiptra1" class="startofrange">
+<primary>transports</primary>
+<secondary><command>pipe</command></secondary>
+</indexterm>
+<indexterm role="concept" id="IIDpiptra2" class="startofrange">
+<primary><command>pipe</command> transport</primary>
+</indexterm>
+The <command>pipe</command> transport is used to deliver messages via a pipe to a command
+running in another process. One example is the use of <command>pipe</command> as a
+pseudo-remote transport for passing messages to some other delivery mechanism
+(such as UUCP). Another is the use by individual users to automatically process
+their incoming messages. The <command>pipe</command> transport can be used in one of the
+following ways:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+A router routes one address to a transport in the normal way, and the
+transport is configured as a <command>pipe</command> transport. In this case, <varname>$local_part</varname>
+contains the local part of the address (as usual), and the command that is run
+is specified by the <option>command</option> option on the transport.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$pipe_addresses</varname></primary>
+</indexterm>
+If the <option>batch_max</option> option is set greater than 1 (the default is 1), the
+transport can handle more than one address in a single run. In this case, when
+more than one address is routed to the transport, <varname>$local_part</varname> is not set
+(because it is not unique). However, the pseudo-variable <varname>$pipe_addresses</varname>
+(described in section <xref linkend="SECThowcommandrun"/> below) contains all the addresses
+that are routed to the transport.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$address_pipe</varname></primary>
+</indexterm>
+A router redirects an address directly to a pipe command (for example, from an
+alias or forward file). In this case, <varname>$address_pipe</varname> contains the text of the
+pipe command, and the <option>command</option> option on the transport is ignored unless
+<option>force_command</option> is set. If only one address is being transported
+(<option>batch_max</option> is not greater than one, or only one address was redirected to
+this pipe command), <varname>$local_part</varname> contains the local part that was redirected.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The <command>pipe</command> transport is a non-interactive delivery method. Exim can also
+deliver messages over pipes using the LMTP interactive protocol. This is
+implemented by the <command>lmtp</command> transport.
+</para>
+<para>
+In the case when <command>pipe</command> is run as a consequence of an entry in a local user’s
+<filename>.forward</filename> file, the command runs under the uid and gid of that user. In
+other cases, the uid and gid have to be specified explicitly, either on the
+transport or on the router that handles the address. Current and <quote>home</quote>
+directories are also controllable. See chapter <xref linkend="CHAPenvironment"/> for
+details of the local delivery environment and chapter <xref linkend="CHAPbatching"/>
+for a discussion of local delivery batching.
+</para>
+<para revisionflag="changed">
+<indexterm role="concept">
+<primary>tainted data</primary>
+<secondary>in pipe command</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>pipe</primary>
+<secondary>tainted data</secondary>
+</indexterm>
+Tainted data may not be used for the command name.
+</para>
+<section id="SECID140">
+<title>Concurrent delivery</title>
+<para>
+If two messages arrive at almost the same time, and both are routed to a pipe
+delivery, the two pipe transports may be run concurrently. You must ensure that
+any pipe commands you set up are robust against this happening. If the commands
+write to a file, the <option>exim_lock</option> utility might be of use.
+Alternatively the <option>max_parallel</option> option could be used with a value
+of "1" to enforce serialization.
+</para>
+</section>
+<section id="SECID141">
+<title>Returned status and data</title>
+<para>
+<indexterm role="concept">
+<primary><command>pipe</command> transport</primary>
+<secondary>returned data</secondary>
+</indexterm>
+If the command exits with a non-zero return code, the delivery is deemed to
+have failed, unless either the <option>ignore_status</option> option is set (in which case
+the return code is treated as zero), or the return code is one of those listed
+in the <option>temp_errors</option> option, which are interpreted as meaning <quote>try again
+later</quote>. In this case, delivery is deferred. Details of a permanent failure are
+logged, but are not included in the bounce message, which merely contains
+<quote>local delivery failed</quote>.
+</para>
+<para>
+If the command exits on a signal and the <option>freeze_signal</option> option is set then
+the message will be frozen in the queue. If that option is not set, a bounce
+will be sent as normal.
+</para>
+<para>
+If the return code is greater than 128 and the command being run is a shell
+script, it normally means that the script was terminated by a signal whose
+value is the return code minus 128. The <option>freeze_signal</option> option does not
+apply in this case.
+</para>
+<para>
+If Exim is unable to run the command (that is, if <function>execve()</function> fails), the
+return code is set to 127. This is the value that a shell returns if it is
+asked to run a non-existent command. The wording for the log line suggests that
+a non-existent command may be the problem.
+</para>
+<para>
+The <option>return_output</option> option can affect the result of a pipe delivery. If it is
+set and the command produces any output on its standard output or standard
+error streams, the command is considered to have failed, even if it gave a zero
+return code or if <option>ignore_status</option> is set. The output from the command is
+included as part of the bounce message. The <option>return_fail_output</option> option is
+similar, except that output is returned only when the command exits with a
+failure return code, that is, a value other than zero or a code that matches
+<option>temp_errors</option>.
+</para>
+</section>
+<section id="SECThowcommandrun">
+<title>How the command is run</title>
+<para>
+<indexterm role="concept">
+<primary><command>pipe</command> transport</primary>
+<secondary>path for command</secondary>
+</indexterm>
+The command line is (by default) broken down into a command name and arguments
+by the <command>pipe</command> transport itself. The <option>allow_commands</option> and
+<option>restrict_to_path</option> options can be used to restrict the commands that may be
+run.
+</para>
+<para>
+<indexterm role="concept">
+<primary>quoting</primary>
+<secondary>in pipe command</secondary>
+</indexterm>
+Unquoted arguments are delimited by white space. If an argument appears in
+double quotes, backslash is interpreted as an escape character in the usual
+way. If an argument appears in single quotes, no escaping is done.
+</para>
+<para>
+String expansion is applied to the command line except when it comes from a
+traditional <filename>.forward</filename> file (commands from a filter file are expanded). The
+expansion is applied to each argument in turn rather than to the whole line.
+For this reason, any string expansion item that contains white space must be
+quoted so as to be contained within a single argument. A setting such as
+</para>
+<literallayout class="monospaced">
+command = /some/path ${if eq{$local_part}{postmaster}{xx}{yy}}
+</literallayout>
+<para>
+will not work, because the expansion item gets split between several
+arguments. You have to write
+</para>
+<literallayout class="monospaced">
+command = /some/path "${if eq{$local_part}{postmaster}{xx}{yy}}"
+</literallayout>
+<para>
+to ensure that it is all in one argument. The expansion is done in this way,
+argument by argument, so that the number of arguments cannot be changed as a
+result of expansion, and quotes or backslashes in inserted variables do not
+interact with external quoting. However, this leads to problems if you want to
+generate multiple arguments (or the command name plus arguments) from a single
+expansion. In this situation, the simplest solution is to use a shell. For
+example:
+</para>
+<literallayout class="monospaced">
+command = /bin/sh -c ${lookup{$local_part}lsearch{/some/file}}
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>filter</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>transport filter</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$pipe_addresses</varname></primary>
+</indexterm>
+Special handling takes place when an argument consists of precisely the text
+<literal>$pipe_addresses</literal> (no quotes).
+This is not a general expansion variable; the only
+place this string is recognized is when it appears as an argument for a pipe or
+transport filter command. It causes each address that is being handled to be
+inserted in the argument list at that point <emphasis>as a separate argument</emphasis>. This
+avoids any problems with spaces or shell metacharacters, and is of use when a
+<command>pipe</command> transport is handling groups of addresses in a batch.
+</para>
+<para>
+If <option>force_command</option> is enabled on the transport, special handling takes place
+for an argument that consists of precisely the text <literal>$address_pipe</literal>. It
+is handled similarly to <varname>$pipe_addresses</varname> above. It is expanded and each
+argument is inserted in the argument list at that point
+<emphasis>as a separate argument</emphasis>. The <literal>$address_pipe</literal> item does not need to be
+the only item in the argument; in fact, if it were then <option>force_command</option>
+should behave as a no-op. Rather, it should be used to adjust the command
+run while preserving the argument vector separation.
+</para>
+<para>
+After splitting up into arguments and expansion, the resulting command is run
+in a subprocess directly from the transport, <emphasis>not</emphasis> under a shell. The
+message that is being delivered is supplied on the standard input, and the
+standard output and standard error are both connected to a single pipe that is
+read by Exim. The <option>max_output</option> option controls how much output the command
+may produce, and the <option>return_output</option> and <option>return_fail_output</option> options
+control what is done with it.
+</para>
+<para>
+Not running the command under a shell (by default) lessens the security risks
+in cases when a command from a user’s filter file is built out of data that was
+taken from an incoming message. If a shell is required, it can of course be
+explicitly specified as the command to be run. However, there are circumstances
+where existing commands (for example, in <filename>.forward</filename> files) expect to be run
+under a shell and cannot easily be modified. To allow for these cases, there is
+an option called <option>use_shell</option>, which changes the way the <command>pipe</command> transport
+works. Instead of breaking up the command line as just described, it expands it
+as a single string and passes the result to <filename>/bin/sh</filename>. The
+<option>restrict_to_path</option> option and the <varname>$pipe_addresses</varname> facility cannot be used
+with <option>use_shell</option>, and the whole mechanism is inherently less secure.
+</para>
+</section>
+<section id="SECTpipeenv">
+<title>Environment variables</title>
+<para>
+<indexterm role="concept">
+<primary><command>pipe</command> transport</primary>
+<secondary>environment for command</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>environment</primary>
+<secondary><command>pipe</command> transport</secondary>
+</indexterm>
+The environment variables listed below are set up when the command is invoked.
+This list is a compromise for maximum compatibility with other MTAs. Note that
+the <option>environment</option> option can be used to add additional variables to this
+environment. The environment for the <command>pipe</command> transport is not subject
+to the <option>add_environment</option> and <option>keep_environment</option> main config options.
+</para>
+<literallayout>
+<literal>DOMAIN </literal> the domain of the address
+<literal>HOME </literal> the home directory, if set
+<literal>HOST </literal> the host name when called from a router (see below)
+<literal>LOCAL_PART </literal> see below
+<literal>LOCAL_PART_PREFIX </literal> see below
+<literal>LOCAL_PART_SUFFIX </literal> see below
+<literal>LOGNAME </literal> see below
+<literal>MESSAGE_ID </literal> Exim’s local ID for the message
+<literal>PATH </literal> as specified by the <option>path</option> option below
+<literal>QUALIFY_DOMAIN </literal> the sender qualification domain
+<literal>RECIPIENT </literal> the complete recipient address
+<literal>SENDER </literal> the sender of the message (empty if a bounce)
+<literal>SHELL </literal> <literal>/bin/sh</literal>
+<literal>TZ </literal> the value of the <option>timezone</option> option, if set
+<literal>USER </literal> see below
+</literallayout>
+<para>
+When a <command>pipe</command> transport is called directly from (for example) an <command>accept</command>
+router, LOCAL_PART is set to the local part of the address. When it is
+called as a result of a forward or alias expansion, LOCAL_PART is set to
+the local part of the address that was expanded. In both cases, any affixes are
+removed from the local part, and made available in LOCAL_PART_PREFIX and
+LOCAL_PART_SUFFIX, respectively. LOGNAME and USER are set to the
+same value as LOCAL_PART for compatibility with other MTAs.
+</para>
+<para>
+<indexterm role="concept">
+<primary>HOST</primary>
+</indexterm>
+HOST is set only when a <command>pipe</command> transport is called from a router that
+associates hosts with an address, typically when using <command>pipe</command> as a
+pseudo-remote transport. HOST is set to the first host name specified by
+the router.
+</para>
+<para>
+<indexterm role="concept">
+<primary>HOME</primary>
+</indexterm>
+If the transport’s generic <option>home_directory</option> option is set, its value is used
+for the HOME environment variable. Otherwise, a home directory may be set
+by the router’s <option>transport_home_directory</option> option, which defaults to the
+user’s home directory if <option>check_local_user</option> is set.
+</para>
+</section>
+<section id="SECID142">
+<title>Private options for pipe</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>pipe</command> transport</secondary>
+</indexterm>
+</para>
+<para>
+<indexterm role="option">
+<primary><option>allow_commands</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>allow_commands</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><command>pipe</command> transport</primary>
+<secondary>permitted commands</secondary>
+</indexterm>
+The string is expanded, and is then interpreted as a colon-separated list of
+permitted commands. If <option>restrict_to_path</option> is not set, the only commands
+permitted are those in the <option>allow_commands</option> list. They need not be absolute
+paths; the <option>path</option> option is still used for relative paths. If
+<option>restrict_to_path</option> is set with <option>allow_commands</option>, the command must either be
+in the <option>allow_commands</option> list, or a name without any slashes that is found on
+the path. In other words, if neither <option>allow_commands</option> nor
+<option>restrict_to_path</option> is set, there is no restriction on the command, but
+otherwise only commands that are permitted by one or the other are allowed. For
+example, if
+</para>
+<literallayout class="monospaced">
+allow_commands = /usr/bin/vacation
+</literallayout>
+<para>
+and <option>restrict_to_path</option> is not set, the only permitted command is
+<filename>/usr/bin/vacation</filename>. The <option>allow_commands</option> option may not be set if
+<option>use_shell</option> is set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>batch_id</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>batch_id</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See the description of local delivery batching in chapter <xref linkend="CHAPbatching"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>batch_max</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>batch_max</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>1</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This limits the number of addresses that can be handled in a single delivery.
+See the description of local delivery batching in chapter <xref linkend="CHAPbatching"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>check_string</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>check_string</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+As <command>pipe</command> writes the message, the start of each line is tested for matching
+<option>check_string</option>, and if it does, the initial matching characters are replaced
+by the contents of <option>escape_string</option>, provided both are set. The value of
+<option>check_string</option> is a literal string, not a regular expression, and the case of
+any letters it contains is significant. When <option>use_bsmtp</option> is set, the contents
+of <option>check_string</option> and <option>escape_string</option> are forced to values that implement
+the SMTP escaping protocol. Any settings made in the configuration file are
+ignored.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>command</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>command</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option need not be set when <command>pipe</command> is being used to deliver to pipes
+obtained directly from address redirections. In other cases, the option must be
+set, to provide a command to be run. It need not yield an absolute path (see
+the <option>path</option> option below). The command is split up into separate arguments by
+Exim, and each argument is separately expanded, as described in section
+<xref linkend="SECThowcommandrun"/> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>environment</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>environment</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><command>pipe</command> transport</primary>
+<secondary>environment for command</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>environment</primary>
+<secondary><command>pipe</command> transport</secondary>
+</indexterm>
+This option is used to add additional variables to the environment in which the
+command runs (see section <xref linkend="SECTpipeenv"/> for the default list). Its value is
+a string which is expanded, and then interpreted as a colon-separated list of
+environment settings of the form <<emphasis>name</emphasis>>=<<emphasis>value</emphasis>>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>escape_string</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>escape_string</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+See <option>check_string</option> above.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>freeze_exec_fail</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>freeze_exec_fail</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>exec failure</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>failure of exec</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><command>pipe</command> transport</primary>
+<secondary>failure of exec</secondary>
+</indexterm>
+Failure to exec the command in a pipe transport is by default treated like
+any other failure while running the command. However, if <option>freeze_exec_fail</option>
+is set, failure to exec is treated specially, and causes the message to be
+frozen, whatever the setting of <option>ignore_status</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>freeze_signal</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>freeze_signal</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>signal exit</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><command>pipe</command> transport</primary>
+<secondary>,</secondary>
+</indexterm>
+Normally if the process run by a command in a pipe transport exits on a signal,
+a bounce message is sent. If <option>freeze_signal</option> is set, the message will be
+frozen in Exim’s queue instead.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>force_command</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>force_command</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>force command</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><command>pipe</command> transport</primary>
+<secondary>,</secondary>
+</indexterm>
+Normally when a router redirects an address directly to a pipe command
+the <option>command</option> option on the transport is ignored. If <option>force_command</option>
+is set, the <option>command</option> option will used. This is especially
+useful for forcing a wrapper or additional argument to be added to the
+command. For example:
+</para>
+<literallayout class="monospaced">
+command = /usr/bin/remote_exec myhost -- $address_pipe
+force_command
+</literallayout>
+<para>
+Note that <varname>$address_pipe</varname> is handled specially in <option>command</option> when
+<option>force_command</option> is set, expanding out to the original argument vector as
+separate items, similarly to a Unix shell <literal>"$@"</literal> construct.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>ignore_status</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>ignore_status</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is true, the status returned by the subprocess that is set up to
+run the command is ignored, and Exim behaves as if zero had been returned.
+Otherwise, a non-zero status or termination by signal causes an error return
+from the transport unless the status value is one of those listed in
+<option>temp_errors</option>; these cause the delivery to be deferred and tried again later.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: This option does not apply to timeouts, which do not return a status.
+See the <option>timeout_defer</option> option for how timeouts are handled.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>log_defer_output</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>log_defer_output</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><command>pipe</command> transport</primary>
+<secondary>logging output</secondary>
+</indexterm>
+If this option is set, and the status returned by the command is
+one of the codes listed in <option>temp_errors</option> (that is, delivery was deferred),
+and any output was produced on stdout or stderr, the first line of it is
+written to the main log.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>log_fail_output</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>log_fail_output</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is set, and the command returns any output on stdout or
+stderr, and also ends with a return code that is neither zero nor one of
+the return codes listed in <option>temp_errors</option> (that is, the delivery
+failed), the first line of output is written to the main log. This
+option and <option>log_output</option> are mutually exclusive. Only one of them may
+be set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>log_output</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>log_output</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is set and the command returns any output on stdout or
+stderr, the first line of output is written to the main log, whatever
+the return code. This option and <option>log_fail_output</option> are mutually
+exclusive. Only one of them may be set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>max_output</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>max_output</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>20K</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies the maximum amount of output that the command may produce on its
+standard output and standard error file combined. If the limit is exceeded, the
+process running the command is killed. This is intended as a safety measure to
+catch runaway processes. The limit is applied independently of the settings of
+the options that control what is done with such output (for example,
+<option>return_output</option>). Because of buffering effects, the amount of output may
+exceed the limit by a small amount before Exim notices.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>message_prefix</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>message_prefix</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+The string specified here is expanded and output at the start of every message.
+The default is unset if <option>use_bsmtp</option> is set. Otherwise it is
+</para>
+<literallayout class="monospaced">
+message_prefix = \
+ From ${if def:return_path{$return_path}{MAILER-DAEMON}}\
+ ${tod_bsdinbox}\n
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>Cyrus</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>tmail</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary><quote>From</quote> line</primary>
+</indexterm>
+This is required by the commonly used <filename>/usr/bin/vacation</filename> program.
+However, it must <emphasis>not</emphasis> be present if delivery is to the Cyrus IMAP server,
+or to the <option>tmail</option> local delivery agent. The prefix can be suppressed by
+setting
+</para>
+<literallayout class="monospaced">
+message_prefix =
+</literallayout>
+<para>
+<emphasis role="bold">Note:</emphasis> If you set <option>use_crlf</option> true, you must change any occurrences of
+<literal>\n</literal> to <literal>\r\n</literal> in <option>message_prefix</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>message_suffix</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>message_suffix</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+The string specified here is expanded and output at the end of every message.
+The default is unset if <option>use_bsmtp</option> is set. Otherwise it is a single newline.
+The suffix can be suppressed by setting
+</para>
+<literallayout class="monospaced">
+message_suffix =
+</literallayout>
+<para>
+<emphasis role="bold">Note:</emphasis> If you set <option>use_crlf</option> true, you must change any occurrences of
+<literal>\n</literal> to <literal>\r\n</literal> in <option>message_suffix</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>path</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>path</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>/bin:/usr/bin</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option is expanded and
+specifies the string that is set up in the PATH environment
+variable of the subprocess.
+If the <option>command</option> option does not yield an absolute path name, the command is
+sought in the PATH directories, in the usual way. <emphasis role="bold">Warning</emphasis>: This does not
+apply to a command specified as a transport filter.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>permit_coredump</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>permit_coredump</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Normally Exim inhibits core-dumps during delivery. If you have a need to get
+a core-dump of a pipe command, enable this command. This enables core-dumps
+during delivery and affects both the Exim binary and the pipe command run.
+It is recommended that this option remain off unless and until you have a need
+for it and that this only be enabled when needed, as the risk of excessive
+resource consumption can be quite high. Note also that Exim is typically
+installed as a setuid binary and most operating systems will inhibit coredumps
+of these by default, so further OS-specific action may be required.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>pipe_as_creator</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>pipe_as_creator</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>uid (user id)</primary>
+<secondary>local delivery</secondary>
+</indexterm>
+If the generic <option>user</option> option is not set and this option is true, the delivery
+process is run under the uid that was in force when Exim was originally called
+to accept the message. If the group id is not otherwise set (via the generic
+<option>group</option> option), the gid that was in force when Exim was originally called to
+accept the message is used.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>restrict_to_path</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>restrict_to_path</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+When this option is set, any command name not listed in <option>allow_commands</option> must
+contain no slashes. The command is searched for only in the directories listed
+in the <option>path</option> option. This option is intended for use in the case when a pipe
+command has been generated from a user’s <filename>.forward</filename> file. This is usually
+handled by a <command>pipe</command> transport called <option>address_pipe</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>return_fail_output</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>return_fail_output</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is true, and the command produced any output and ended with a
+return code other than zero or one of the codes listed in <option>temp_errors</option> (that
+is, the delivery failed), the output is returned in the bounce message.
+However, if the message has a null sender (that is, it is itself a bounce
+message), output from the command is discarded. This option and
+<option>return_output</option> are mutually exclusive. Only one of them may be set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>return_output</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>return_output</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is true, and the command produced any output, the delivery is
+deemed to have failed whatever the return code from the command, and the output
+is returned in the bounce message. Otherwise, the output is just discarded.
+However, if the message has a null sender (that is, it is a bounce message),
+output from the command is always discarded, whatever the setting of this
+option. This option and <option>return_fail_output</option> are mutually exclusive. Only one
+of them may be set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>temp_errors</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>temp_errors</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary><command>pipe</command> transport</primary>
+<secondary>temporary failure</secondary>
+</indexterm>
+This option contains either a colon-separated list of numbers, or a single
+asterisk. If <option>ignore_status</option> is false
+and <option>return_output</option> is not set,
+and the command exits with a non-zero return code, the failure is treated as
+temporary and the delivery is deferred if the return code matches one of the
+numbers, or if the setting is a single asterisk. Otherwise, non-zero return
+codes are treated as permanent errors. The default setting contains the codes
+defined by EX_TEMPFAIL and EX_CANTCREAT in <filename>sysexits.h</filename>. If Exim is
+compiled on a system that does not define these macros, it assumes values of 75
+and 73, respectively.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>timeout</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>1h</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If the command fails to complete within this time, it is killed. This normally
+causes the delivery to fail (but see <option>timeout_defer</option>). A zero time interval
+specifies no timeout. In order to ensure that any subprocesses created by the
+command are also killed, Exim makes the initial process a process group leader,
+and kills the whole process group on a timeout. However, this can be defeated
+if one of the processes starts a new process group.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>timeout_defer</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>timeout_defer</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+A timeout in a <command>pipe</command> transport, either in the command that the transport
+runs, or in a transport filter that is associated with it, is by default
+treated as a hard error, and the delivery fails. However, if <option>timeout_defer</option>
+is set true, both kinds of timeout become temporary errors, causing the
+delivery to be deferred.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>umask</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>umask</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>octal integer</emphasis></entry>
+<entry>Default: <emphasis>022</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies the umask setting for the subprocess that runs the command.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>use_bsmtp</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>use_bsmtp</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>envelope sender</primary>
+</indexterm>
+If this option is set true, the <command>pipe</command> transport writes messages in <quote>batch
+SMTP</quote> format, with the envelope sender and recipient(s) included as SMTP
+commands. If you want to include a leading HELO command with such messages,
+you can do so by setting the <option>message_prefix</option> option. See section
+<xref linkend="SECTbatchSMTP"/> for details of batch SMTP.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>use_classresources</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>use_classresources</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>class resources (BSD)</primary>
+</indexterm>
+This option is available only when Exim is running on FreeBSD, NetBSD, or
+BSD/OS. If it is set true, the <function>setclassresources()</function> function is used to set
+resource limits when a <command>pipe</command> transport is run to perform a delivery. The
+limits for the uid under which the pipe is to run are obtained from the login
+class database.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>use_crlf</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>use_crlf</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>carriage return</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>linefeed</primary>
+</indexterm>
+This option causes lines to be terminated with the two-character CRLF sequence
+(carriage return, linefeed) instead of just a linefeed character. In the case
+of batched SMTP, the byte sequence written to the pipe is then an exact image
+of what would be sent down a real SMTP connection.
+</para>
+<para>
+The contents of the <option>message_prefix</option> and <option>message_suffix</option> options are
+written verbatim, so must contain their own carriage return characters if these
+are needed. When <option>use_bsmtp</option> is not set, the default values for both
+<option>message_prefix</option> and <option>message_suffix</option> end with a single linefeed, so their
+values must be changed to end with <literal>\r\n</literal> if <option>use_crlf</option> is set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>use_shell</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>use_shell</option></entry>
+<entry>Use: <emphasis>pipe</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="variable">
+<primary><varname>$pipe_addresses</varname></primary>
+</indexterm>
+If this option is set, it causes the command to be passed to <filename>/bin/sh</filename>
+instead of being run directly from the transport, as described in section
+<xref linkend="SECThowcommandrun"/>. This is less secure, but is needed in some situations
+where the command is expected to be run under a shell and cannot easily be
+modified. The <option>allow_commands</option> and <option>restrict_to_path</option> options, and the
+<literal>$pipe_addresses</literal> facility are incompatible with <option>use_shell</option>. The
+command is expanded as a single string, and handed to <filename>/bin/sh</filename> as data for
+its <option>-c</option> option.
+</para>
+</section>
+<section id="SECID143">
+<title>Using an external local delivery agent</title>
+<para>
+<indexterm role="concept">
+<primary>local delivery</primary>
+<secondary>using an external agent</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>procmail</emphasis></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>external local delivery</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary><emphasis>procmail</emphasis></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>by external agent</secondary>
+</indexterm>
+The <command>pipe</command> transport can be used to pass all messages that require local
+delivery to a separate local delivery agent such as <option>procmail</option>. When doing
+this, care must be taken to ensure that the pipe is run under an appropriate
+uid and gid. In some configurations one wants this to be a uid that is trusted
+by the delivery agent to supply the correct sender of the message. It may be
+necessary to recompile or reconfigure the delivery agent so that it trusts an
+appropriate user. The following is an example transport and router
+configuration for <option>procmail</option>:
+</para>
+<literallayout class="monospaced">
+# transport
+procmail_pipe:
+ driver = pipe
+ command = /usr/local/bin/procmail -d $local_part_data
+ return_path_add
+ delivery_date_add
+ envelope_to_add
+ check_string = "From "
+ escape_string = ">From "
+ umask = 077
+ user = $local_part_data
+ group = mail
+
+# router
+procmail:
+ driver = accept
+ check_local_user
+ transport = procmail_pipe
+</literallayout>
+<para>
+In this example, the pipe is run as the local user, but with the group set to
+<emphasis>mail</emphasis>. An alternative is to run the pipe as a specific user such as <emphasis>mail</emphasis>
+or <emphasis>exim</emphasis>, but in this case you must arrange for <option>procmail</option> to trust that
+user to supply a correct sender address. If you do not specify either a
+<option>group</option> or a <option>user</option> option, the pipe command is run as the local user. The
+home directory is the user’s home directory by default.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: The command that the pipe transport runs does <emphasis>not</emphasis> begin with
+</para>
+<literallayout class="monospaced">
+IFS=" "
+</literallayout>
+<para>
+as shown in some <option>procmail</option> documentation, because Exim does not by default
+use a shell to run pipe commands.
+</para>
+<para>
+<indexterm role="concept">
+<primary>Cyrus</primary>
+</indexterm>
+The next example shows a transport and a router for a system where local
+deliveries are handled by the Cyrus IMAP server.
+</para>
+<literallayout class="monospaced">
+# transport
+local_delivery_cyrus:
+ driver = pipe
+ command = /usr/cyrus/bin/deliver \
+ -m ${substr_1:$local_part_suffix} -- $local_part
+ user = cyrus
+ group = mail
+ return_output
+ log_output
+ message_prefix =
+ message_suffix =
+
+# router
+local_user_cyrus:
+ driver = accept
+ check_local_user
+ local_part_suffix = .*
+ transport = local_delivery_cyrus
+</literallayout>
+<para>
+Note the unsetting of <option>message_prefix</option> and <option>message_suffix</option>, and the use of
+<option>return_output</option> to cause any text written by Cyrus to be returned to the
+sender.
+<indexterm role="concept" startref="IIDpiptra1" class="endofrange"/>
+<indexterm role="concept" startref="IIDpiptra2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPsmtptrans">
+<title>The smtp transport</title>
+<para>
+<indexterm role="concept" id="IIDsmttra1" class="startofrange">
+<primary>transports</primary>
+<secondary><command>smtp</command></secondary>
+</indexterm>
+<indexterm role="concept" id="IIDsmttra2" class="startofrange">
+<primary><command>smtp</command> transport</primary>
+</indexterm>
+The <command>smtp</command> transport delivers messages over TCP/IP connections using the SMTP
+or LMTP protocol. The list of hosts to try can either be taken from the address
+that is being processed (having been set up by the router), or specified
+explicitly for the transport. Timeout and retry processing (see chapter
+<xref linkend="CHAPretry"/>) is applied to each IP address independently.
+</para>
+<section id="SECID144">
+<title>Multiple messages on a single connection</title>
+<para>
+The sending of multiple messages over a single TCP/IP connection can arise in
+two ways:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If a message contains more than <option>max_rcpt</option> (see below) addresses that are
+routed to the same host, more than one copy of the message has to be sent to
+that host. In this situation, multiple copies may be sent in a single run of
+the <command>smtp</command> transport over a single TCP/IP connection. (What Exim actually
+does when it has too many addresses to send in one message also depends on the
+value of the global <option>remote_max_parallel</option> option. Details are given in
+section <xref linkend="SECToutSMTPTCP"/>.)
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>remembering routing</secondary>
+</indexterm>
+When a message has been successfully delivered over a TCP/IP connection, Exim
+looks in its hints database to see if there are any other messages awaiting a
+connection to the same host. If there are, a new delivery process is started
+for one of them, and the current TCP/IP connection is passed on to it. The new
+process may in turn send multiple copies and possibly create yet another
+process.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+For each copy sent over the same TCP/IP connection, a sequence counter is
+incremented, and if it ever gets to the value of <option>connection_max_messages</option>,
+no further messages are sent over that connection.
+</para>
+</section>
+<section id="SECID145">
+<title>Use of the $host and $host_address variables</title>
+<para>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host_address</varname></primary>
+</indexterm>
+At the start of a run of the <command>smtp</command> transport, the values of <varname>$host</varname> and
+<varname>$host_address</varname> are the name and IP address of the first host on the host list
+passed by the router. However, when the transport is about to connect to a
+specific host, and while it is connected to that host, <varname>$host</varname> and
+<varname>$host_address</varname> are set to the values for that host. These are the values
+that are in force when the <option>helo_data</option>, <option>hosts_try_auth</option>, <option>interface</option>,
+<option>serialize_hosts</option>, and the various TLS options are expanded.
+</para>
+</section>
+<section id="usecippeer">
+<title>Use of $tls_cipher and $tls_peerdn</title>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_bits</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tls_cipher</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tls_peerdn</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tls_sni</varname></primary>
+</indexterm>
+At the start of a run of the <command>smtp</command> transport, the values of <varname>$tls_bits</varname>,
+<varname>$tls_cipher</varname>, <varname>$tls_peerdn</varname> and <varname>$tls_sni</varname>
+are the values that were set when the message was received.
+These are the values that are used for options that are expanded before any
+SMTP connections are made. Just before each connection is made, these four
+variables are emptied. If TLS is subsequently started, they are set to the
+appropriate values for the outgoing connection, and these are the values that
+are in force when any authenticators are run and when the
+<option>authenticated_sender</option> option is expanded.
+</para>
+<para>
+These variables are deprecated in favour of <varname>$tls_in_cipher</varname> et. al.
+and will be removed in a future release.
+</para>
+</section>
+<section id="SECID146">
+<title>Private options for smtp</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>smtp</command> transport</secondary>
+</indexterm>
+The private options of the <command>smtp</command> transport are as follows:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>address_retry_include_sender</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>address_retry_include_sender</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>4<emphasis>xx</emphasis> responses</primary>
+<secondary>retrying after</secondary>
+</indexterm>
+When an address is delayed because of a 4<emphasis>xx</emphasis> response to a RCPT command, it
+is the combination of sender and recipient that is delayed in subsequent queue
+runs until the retry time is reached. You can delay the recipient without
+reference to the sender (which is what earlier versions of Exim did), by
+setting <option>address_retry_include_sender</option> false. However, this can lead to
+problems with servers that regularly issue 4<emphasis>xx</emphasis> responses to RCPT commands.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>allow_localhost</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>allow_localhost</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>local host</primary>
+<secondary>sending to</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>fallback</primary>
+<secondary>hosts specified on transport</secondary>
+</indexterm>
+When a host specified in <option>hosts</option> or <option>fallback_hosts</option> (see below) turns out
+to be the local host, or is listed in <option>hosts_treat_as_local</option>, delivery is
+deferred by default. However, if <option>allow_localhost</option> is set, Exim goes on to do
+the delivery anyway. This should be used only in special cases when the
+configuration ensures that no looping will result (for example, a differently
+configured Exim is listening on the port to which the message is sent).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>authenticated_sender</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>authenticated_sender</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>Cyrus</primary>
+</indexterm>
+When Exim has authenticated as a client, or if <option>authenticated_sender_force</option>
+is true, this option sets a value for the AUTH= item on outgoing MAIL commands,
+overriding any existing authenticated sender value. If the string expansion is
+forced to fail, the option is ignored. Other expansion failures cause delivery
+to be deferred. If the result of expansion is an empty string, that is also
+ignored.
+</para>
+<para>
+The expansion happens after the outgoing connection has been made and TLS
+started, if required. This means that the <varname>$host</varname>, <varname>$host_address</varname>,
+<varname>$tls_out_cipher</varname>, and <varname>$tls_out_peerdn</varname> variables are set according to the
+particular connection.
+</para>
+<para>
+If the SMTP session is not authenticated, the expansion of
+<option>authenticated_sender</option> still happens (and can cause the delivery to be
+deferred if it fails), but no AUTH= item is added to MAIL commands
+unless <option>authenticated_sender_force</option> is true.
+</para>
+<para>
+This option allows you to use the <command>smtp</command> transport in LMTP mode to
+deliver mail to Cyrus IMAP and provide the proper local part as the
+<quote>authenticated sender</quote>, via a setting such as:
+</para>
+<literallayout class="monospaced">
+authenticated_sender = $local_part
+</literallayout>
+<para>
+This removes the need for IMAP subfolders to be assigned special ACLs to
+allow direct delivery to those subfolders.
+</para>
+<para>
+Because of expected uses such as that just described for Cyrus (when no
+domain is involved), there is no checking on the syntax of the provided
+value.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>authenticated_sender_force</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>authenticated_sender_force</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is set true, the <option>authenticated_sender</option> option’s value
+is used for the AUTH= item on outgoing MAIL commands, even if Exim has not
+authenticated as a client.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>command_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>command_timeout</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>5m</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This sets a timeout for receiving a response to an SMTP command that has been
+sent out. It is also used when waiting for the initial banner line from the
+remote host. Its value must not be zero.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>connect_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>connect_timeout</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>5m</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This sets a timeout for the <function>connect()</function> function, which sets up a TCP/IP call
+to a remote host. A setting of zero allows the system timeout (typically
+several minutes) to act. To have any effect, the value of this option must be
+less than the system timeout. However, it has been observed that on some
+systems there is no system timeout, which is why the default value for this
+option is 5 minutes, a value recommended by RFC 1123.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>connection_max_messages</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>connection_max_messages</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>500</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>passed connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>multiple deliveries</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>multiple SMTP deliveries</primary>
+</indexterm>
+This controls the maximum number of separate message deliveries that are sent
+over a single TCP/IP connection. If the value is zero, there is no limit.
+For testing purposes, this value can be overridden by the <option>-oB</option> command line
+option.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dane_require_tls_ciphers</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dane_require_tls_ciphers</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>requiring specific ciphers for DANE</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>cipher</primary>
+<secondary>requiring specific</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DANE</primary>
+<secondary>TLS ciphers</secondary>
+</indexterm>
+This option may be used to override <option>tls_require_ciphers</option> for connections
+where DANE has been determined to be in effect.
+If not set, then <option>tls_require_ciphers</option> will be used.
+Normal SMTP delivery is not able to make strong demands of TLS cipher
+configuration, because delivery will fall back to plaintext. Once DANE has
+been determined to be in effect, there is no plaintext fallback and making the
+TLS cipherlist configuration stronger will increase security, rather than
+counter-intuitively decreasing it.
+If the option expands to be empty or is forced to fail, then it will
+be treated as unset and <option>tls_require_ciphers</option> will be used instead.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>data_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>data_timeout</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>5m</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This sets a timeout for the transmission of each block in the data portion of
+the message. As a result, the overall timeout for a message depends on the size
+of the message. Its value must not be zero. See also <option>final_timeout</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dkim_canon</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_canon</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+DKIM signing option. For details see section <xref linkend="SECDKIMSIGN"/>.
+<indexterm role="option">
+<primary><option>unset</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_domain</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>list</emphasis>†<emphasis></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+DKIM signing option. For details see section <xref linkend="SECDKIMSIGN"/>.
+<indexterm role="option">
+<primary><option>dkim_hash</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_hash</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>sha256</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+DKIM signing option. For details see section <xref linkend="SECDKIMSIGN"/>.
+<indexterm role="option">
+<primary><option>dkim_identity</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_identity</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+DKIM signing option. For details see section <xref linkend="SECDKIMSIGN"/>.
+<indexterm role="option">
+<primary><option>dkim_private_key</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_private_key</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+DKIM signing option. For details see section <xref linkend="SECDKIMSIGN"/>.
+<indexterm role="option">
+<primary><option>dkim_selector</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_selector</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+DKIM signing option. For details see section <xref linkend="SECDKIMSIGN"/>.
+<indexterm role="option">
+<primary><option>dkim_strict</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_strict</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+DKIM signing option. For details see section <xref linkend="SECDKIMSIGN"/>.
+<indexterm role="option">
+<primary><option>dkim_sign_headers</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_sign_headers</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>per RFC</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+DKIM signing option. For details see section <xref linkend="SECDKIMSIGN"/>.
+<indexterm role="option">
+<primary><option>dkim_timestamps</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_timestamps</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+DKIM signing option. For details see section <xref linkend="SECDKIMSIGN"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>delay_after_cutoff</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>delay_after_cutoff</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>final cutoff</primary>
+<secondary>retries, controlling</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>final cutoff</secondary>
+</indexterm>
+This option controls what happens when all remote IP addresses for a given
+domain have been inaccessible for so long that they have passed their retry
+cutoff times.
+</para>
+<para>
+In the default state, if the next retry time has not been reached for any of
+them, the address is bounced without trying any deliveries. In other words,
+Exim delays retrying an IP address after the final cutoff time until a new
+retry time is reached, and can therefore bounce an address without ever trying
+a delivery, when machines have been down for a long time. Some people are
+unhappy at this prospect, so...
+</para>
+<para>
+If <option>delay_after_cutoff</option> is set false, Exim behaves differently. If all IP
+addresses are past their final cutoff time, Exim tries to deliver to those
+IP addresses that have not been tried since the message arrived. If there are
+none, of if they all fail, the address is bounced. In other words, it does not
+delay when a new message arrives, but immediately tries those expired IP
+addresses that haven’t been tried since the message arrived. If there is a
+continuous stream of messages for the dead hosts, unsetting
+<option>delay_after_cutoff</option> means that there will be many more attempts to deliver
+to them.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dns_qualify_single</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dns_qualify_single</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If the <option>hosts</option> or <option>fallback_hosts</option> option is being used,
+and the <option>gethostbyname</option> option is false,
+the RES_DEFNAMES resolver option is set. See the <option>qualify_single</option> option
+in chapter <xref linkend="CHAPdnslookup"/> for more details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dns_search_parents</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dns_search_parents</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If the <option>hosts</option> or <option>fallback_hosts</option> option is being used, and the
+<option>gethostbyname</option> option is false, the RES_DNSRCH resolver option is set.
+See the <option>search_parents</option> option in chapter <xref linkend="CHAPdnslookup"/> for more
+details.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dnssec_request_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dnssec_request_domains</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>MX record</primary>
+<secondary>security</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNSSEC</primary>
+<secondary>MX lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>security</primary>
+<secondary>MX lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>DNSSEC</secondary>
+</indexterm>
+DNS lookups for domains matching <option>dnssec_request_domains</option> will be done with
+the dnssec request bit set. Setting this transport option is only useful if the
+transport overrides or sets the host names. See the <option>dnssec_request_domains</option>
+router option.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dnssec_require_domains</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dnssec_require_domains</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>domain list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>MX record</primary>
+<secondary>security</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNSSEC</primary>
+<secondary>MX lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>security</primary>
+<secondary>MX lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>DNSSEC</secondary>
+</indexterm>
+DNS lookups for domains matching <option>dnssec_require_domains</option> will be done with
+the dnssec request bit set. Setting this transport option is only
+useful if the transport overrides or sets the host names. See the
+<option>dnssec_require_domains</option> router option.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dscp</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dscp</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DCSP</primary>
+<secondary>outbound</secondary>
+</indexterm>
+This option causes the DSCP value associated with a socket to be set to one
+of a number of fixed strings or to numeric value.
+The <option>-bI:dscp</option> option may be used to ask Exim which names it knows of.
+Common values include <literal>throughput</literal>, <literal>mincost</literal>, and on newer systems
+<literal>ef</literal>, <literal>af41</literal>, etc. Numeric values may be in the range 0 to 0x3F.
+</para>
+<para>
+The outbound packets from Exim will be marked with this value in the header
+(for IPv4, the TOS field; for IPv6, the TCLASS field); there is no guarantee
+that these values will have any effect, not be stripped by networking
+equipment, or do much of anything without cooperation with your Network
+Engineer and those of all network operators between the source and destination.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>fallback_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>fallback_hosts</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>fallback</primary>
+<secondary>hosts specified on transport</secondary>
+</indexterm>
+String expansion is not applied to this option. The argument must be a
+colon-separated list of host names or IP addresses, optionally also including
+port numbers, though the separator can be changed, as described in section
+<xref linkend="SECTlistconstruct"/>. Each individual item in the list is the same as an
+item in a <option>route_list</option> setting for the <command>manualroute</command> router, as described
+in section <xref linkend="SECTformatonehostitem"/>.
+</para>
+<para>
+Fallback hosts can also be specified on routers, which associate them with the
+addresses they process. As for the <option>hosts</option> option without <option>hosts_override</option>,
+<option>fallback_hosts</option> specified on the transport is used only if the address does
+not have its own associated fallback host list. Unlike <option>hosts</option>, a setting of
+<option>fallback_hosts</option> on an address is not overridden by <option>hosts_override</option>.
+However, <option>hosts_randomize</option> does apply to fallback host lists.
+</para>
+<para>
+If Exim is unable to deliver to any of the hosts for a particular address, and
+the errors are not permanent rejections, the address is put on a separate
+transport queue with its host list replaced by the fallback hosts, unless the
+address was routed via MX records and the current host was in the original MX
+list. In that situation, the fallback host list is not used.
+</para>
+<para>
+Once normal deliveries are complete, the fallback queue is delivered by
+re-running the same transports with the new host lists. If several failing
+addresses have the same fallback hosts (and <option>max_rcpt</option> permits it), a single
+copy of the message is sent.
+</para>
+<para>
+The resolution of the host names on the fallback list is controlled by the
+<option>gethostbyname</option> option, as for the <option>hosts</option> option. Fallback hosts apply
+both to cases when the host list comes with the address and when it is taken
+from <option>hosts</option>. This option provides a <quote>use a smart host only if delivery
+fails</quote> facility.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>final_timeout</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>final_timeout</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>time</emphasis></entry>
+<entry>Default: <emphasis>10m</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This is the timeout that applies while waiting for the response to the final
+line containing just <quote>.</quote> that terminates a message. Its value must not be
+zero.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>gethostbyname</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>gethostbyname</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is true when the <option>hosts</option> and/or <option>fallback_hosts</option> options are
+being used, names are looked up using <function>gethostbyname()</function>
+(or <function>getipnodebyname()</function> when available)
+instead of using the DNS. Of course, that function may in fact use the DNS, but
+it may also consult other sources of information such as <filename>/etc/hosts</filename>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>gnutls_compat_mode</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>gnutls_compat_mode</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option controls whether GnuTLS is used in compatibility mode in an Exim
+server. This reduces security slightly, but improves interworking with older
+implementations of TLS.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>helo_data</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>helo_data</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>HELO</primary>
+<secondary>argument, setting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>EHLO</primary>
+<secondary>argument, setting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>LHLO argument setting</primary>
+</indexterm>
+The value of this option is expanded after a connection to a another host has
+been set up. The result is used as the argument for the EHLO, HELO, or LHLO
+command that starts the outgoing SMTP or LMTP session. The default value of the
+option is:
+</para>
+<literallayout class="monospaced">
+$primary_hostname
+</literallayout>
+<para>
+During the expansion, the variables <varname>$host</varname> and <varname>$host_address</varname> are set to
+the identity of the remote host, and the variables <varname>$sending_ip_address</varname> and
+<varname>$sending_port</varname> are set to the local IP address and port number that are being
+used. These variables can be used to generate different values for different
+servers or different local IP addresses. For example, if you want the string
+that is used for <option>helo_data</option> to be obtained by a DNS lookup of the outgoing
+interface address, you could use this:
+</para>
+<literallayout class="monospaced">
+helo_data = ${lookup dnsdb{ptr=$sending_ip_address}{$value}\
+ {$primary_hostname}}
+</literallayout>
+<para>
+The use of <option>helo_data</option> applies both to sending messages and when doing
+callouts.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Hosts are associated with an address by a router such as <command>dnslookup</command>, which
+finds the hosts by looking up the address domain in the DNS, or by
+<command>manualroute</command>, which has lists of hosts in its configuration. However,
+email addresses can be passed to the <command>smtp</command> transport by any router, and not
+all of them can provide an associated list of hosts.
+</para>
+<para>
+The <option>hosts</option> option specifies a list of hosts to be used if the address being
+processed does not have any hosts associated with it. The hosts specified by
+<option>hosts</option> are also used, whether or not the address has its own hosts, if
+<option>hosts_override</option> is set.
+</para>
+<para>
+The string is first expanded, before being interpreted as a colon-separated
+list of host names or IP addresses, possibly including port numbers. The
+separator may be changed to something other than colon, as described in section
+<xref linkend="SECTlistconstruct"/>. Each individual item in the list is the same as an
+item in a <option>route_list</option> setting for the <command>manualroute</command> router, as described
+in section <xref linkend="SECTformatonehostitem"/>. However, note that the <literal>/MX</literal> facility
+of the <command>manualroute</command> router is not available here.
+</para>
+<para>
+If the expansion fails, delivery is deferred. Unless the failure was caused by
+the inability to complete a lookup, the error is logged to the panic log as
+well as the main log. Host names are looked up either by searching directly for
+address records in the DNS or by calling <function>gethostbyname()</function> (or
+<function>getipnodebyname()</function> when available), depending on the setting of the
+<option>gethostbyname</option> option. When Exim is compiled with IPv6 support, if a host
+that is looked up in the DNS has both IPv4 and IPv6 addresses, both types of
+address are used.
+</para>
+<para>
+During delivery, the hosts are tried in order, subject to their retry status,
+unless <option>hosts_randomize</option> is set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_avoid_esmtp</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_avoid_esmtp</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>ESMTP, avoiding use of</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>HELO</primary>
+<secondary>forcing use of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>EHLO</primary>
+<secondary>avoiding use of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>PIPELINING</primary>
+<secondary>avoiding the use of</secondary>
+</indexterm>
+This option is for use with broken hosts that announce ESMTP facilities (for
+example, PIPELINING) and then fail to implement them properly. When a host
+matches <option>hosts_avoid_esmtp</option>, Exim sends HELO rather than EHLO at the
+start of the SMTP session. This means that it cannot use any of the ESMTP
+facilities such as AUTH, PIPELINING, SIZE, and STARTTLS.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_avoid_pipelining</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_avoid_pipelining</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>PIPELINING</primary>
+<secondary>avoiding the use of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>PIPELINING</secondary>
+</indexterm>
+Exim will not use the ESMTP PIPELINING extension when delivering to any host
+that matches this list, even if the server host advertises PIPELINING support.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_pipe_connect</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_pipe_connect</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>pipelining</primary>
+<secondary>early connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>pipelining</primary>
+<secondary>PIPE_CONNECT</secondary>
+</indexterm>
+If Exim is built with the SUPPORT_PIPE_CONNECT build option
+this option controls which to hosts the facility watched for
+and recorded, and used for subsequent connections.
+</para>
+<para>
+The retry hints database is used for the record,
+and records are subject to the <option>retry_data_expire</option> option.
+When used, the pipelining saves on roundtrip times.
+It also turns SMTP into a client-first protocol
+so combines well with TCP Fast Open.
+</para>
+<para>
+See also the <option>pipelining_connect_advertise_hosts</option> main option.
+</para>
+<para>
+Note:
+When the facility is used, the transport <option>helo_data</option> option
+will be expanded before the <varname>$sending_ip_address</varname> variable
+is filled in.
+A check is made for the use of that variable, without the
+presence of a <quote>def:</quote> test on it, but suitably complex coding
+can avoid the check and produce unexpected results.
+You have been warned.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_avoid_tls</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_avoid_tls</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>avoiding for certain hosts</secondary>
+</indexterm>
+Exim will not try to start a TLS session when delivering to any host that
+matches this list. See chapter <xref linkend="CHAPTLS"/> for details of TLS.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_verify_avoid_tls</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_verify_avoid_tls</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>avoiding for certain hosts</secondary>
+</indexterm>
+Exim will not try to start a TLS session for a verify callout,
+or when delivering in cutthrough mode,
+to any host that matches this list.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_max_try</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_max_try</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>5</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>maximum number to try</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>number of hosts tried</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>number of MX tried</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>MX record</primary>
+<secondary>maximum tried</secondary>
+</indexterm>
+This option limits the number of IP addresses that are tried for any one
+delivery in cases where there are temporary delivery errors. Section
+<xref linkend="SECTvalhosmax"/> describes in detail how the value of this option is used.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_max_try_hardlimit</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_max_try_hardlimit</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>50</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This is an additional check on the maximum number of IP addresses that Exim
+tries for any one delivery. Section <xref linkend="SECTvalhosmax"/> describes its use and
+why it exists.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_nopass_tls</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_nopass_tls</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>passing connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>multiple SMTP deliveries</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>multiple message deliveries</secondary>
+</indexterm>
+For any host that matches this list, a connection on which a TLS session has
+been started will not be passed to a new delivery process for sending another
+message on the same connection. See section <xref linkend="SECTmulmessam"/> for an
+explanation of when this might be needed.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_noproxy_tls</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_noproxy_tls</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>passing connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>multiple SMTP deliveries</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>multiple message deliveries</secondary>
+</indexterm>
+For any host that matches this list, a TLS session which has
+been started will not be passed to a new delivery process for sending another
+message on the same session.
+</para>
+<para>
+The traditional implementation closes down TLS and re-starts it in the new
+process, on the same open TCP connection, for each successive message
+sent. If permitted by this option a pipe to to the new process is set up
+instead, and the original process maintains the TLS connection and proxies
+the SMTP connection from and to the new process and any subsequents.
+The new process has no access to TLS information, so cannot include it in
+logging.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_override</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_override</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is set and the <option>hosts</option> option is also set, any hosts that are
+attached to the address are ignored, and instead the hosts specified by the
+<option>hosts</option> option are always used. This option does not apply to
+<option>fallback_hosts</option>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_randomize</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_randomize</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>randomized host list</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>list of; randomized</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>fallback</primary>
+<secondary>randomized hosts</secondary>
+</indexterm>
+If this option is set, and either the list of hosts is taken from the
+<option>hosts</option> or the <option>fallback_hosts</option> option, or the hosts supplied by the router
+were not obtained from MX records (this includes fallback hosts from the
+router), and were not randomized by the router, the order of trying the hosts
+is randomized each time the transport runs. Randomizing the order of a host
+list can be used to do crude load sharing.
+</para>
+<para>
+When <option>hosts_randomize</option> is true, a host list may be split into groups whose
+order is separately randomized. This makes it possible to set up MX-like
+behaviour. The boundaries between groups are indicated by an item that is just
+<literal>+</literal> in the host list. For example:
+</para>
+<literallayout class="monospaced">
+hosts = host1:host2:host3:+:host4:host5
+</literallayout>
+<para>
+The order of the first three hosts and the order of the last two hosts is
+randomized for each use, but the first three always end up before the last two.
+If <option>hosts_randomize</option> is not set, a <literal>+</literal> item in the list is ignored.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_require_auth</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_require_auth</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>required by client</secondary>
+</indexterm>
+This option provides a list of servers for which authentication must succeed
+before Exim will try to transfer a message. If authentication fails for
+servers which are not in this list, Exim tries to send unauthenticated. If
+authentication fails for one of these servers, delivery is deferred. This
+temporary error is detectable in the retry rules, so it can be turned into a
+hard failure if required. See also <option>hosts_try_auth</option>, and chapter
+<xref linkend="CHAPSMTPAUTH"/> for details of authentication.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_request_ocsp</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_request_ocsp</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>requiring for certain servers</secondary>
+</indexterm>
+Exim will request a Certificate Status on a
+TLS session for any host that matches this list.
+<option>tls_verify_certificates</option> should also be set for the transport.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_require_dane</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_require_dane</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DANE</primary>
+<secondary>transport options</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DANE</primary>
+<secondary>requiring for certain servers</secondary>
+</indexterm>
+If built with DANE support, Exim will require that a DNSSEC-validated
+TLSA record is present for any host matching the list,
+and that a DANE-verified TLS connection is made. See
+the <option>dnssec_request_domains</option> router and transport options.
+There will be no fallback to in-clear communication.
+See section <xref linkend="SECDANE"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_require_ocsp</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_require_ocsp</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>requiring for certain servers</secondary>
+</indexterm>
+Exim will request, and check for a valid Certificate Status being given, on a
+TLS session for any host that matches this list.
+<option>tls_verify_certificates</option> should also be set for the transport.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_require_tls</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_require_tls</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>requiring for certain servers</secondary>
+</indexterm>
+Exim will insist on using a TLS session when delivering to any host that
+matches this list. See chapter <xref linkend="CHAPTLS"/> for details of TLS.
+<emphasis role="bold">Note</emphasis>: This option affects outgoing mail only. To insist on TLS for
+incoming messages, use an appropriate ACL.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_try_auth</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_try_auth</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>optional in client</secondary>
+</indexterm>
+This option provides a list of servers to which, provided they announce
+authentication support, Exim will attempt to authenticate as a client when it
+connects. If authentication fails, Exim will try to transfer the message
+unauthenticated. See also <option>hosts_require_auth</option>, and chapter
+<xref linkend="CHAPSMTPAUTH"/> for details of authentication.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_try_chunking</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_try_chunking</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>CHUNKING</primary>
+<secondary>enabling, in client</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>BDAT</primary>
+<secondary>SMTP command</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>RFC 3030</primary>
+<secondary>CHUNKING</secondary>
+</indexterm>
+This option provides a list of servers to which, provided they announce
+CHUNKING support, Exim will attempt to use BDAT commands rather than DATA.
+</para>
+<para revisionflag="changed">
+Unless DKIM signing is being done,
+</para>
+<para>
+BDAT will not be used in conjunction with a transport filter.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_try_dane</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_try_dane</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>DANE</primary>
+<secondary>transport options</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DANE</primary>
+<secondary>attempting for certain servers</secondary>
+</indexterm>
+If built with DANE support, Exim will require that a DNSSEC-validated
+TLSA record is present for any host matching the list,
+and that a DANE-verified TLS connection is made. See
+the <option>dnssec_request_domains</option> router and transport options.
+There will be no fallback to in-clear communication.
+See section <xref linkend="SECDANE"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_try_fastopen</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_try_fastopen</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>fast open, TCP</primary>
+<secondary>enabling, in client</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP Fast Open</primary>
+<secondary>enabling, in client</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>RFC 7413</primary>
+<secondary>TCP Fast Open</secondary>
+</indexterm>
+This option provides a list of servers to which, provided
+the facility is supported by this system, Exim will attempt to
+perform a TCP Fast Open.
+No data is sent on the SYN segment but, if the remote server also
+supports the facility, it can send its SMTP banner immediately after
+the SYN,ACK segment. This can save up to one round-trip time.
+</para>
+<para>
+The facility is only active for previously-contacted servers,
+as the initiator must present a cookie in the SYN segment.
+</para>
+<para>
+On (at least some) current Linux distributions the facility must be enabled
+in the kernel by the sysadmin before the support is usable.
+There is no option for control of the server side; if the system supports
+it it is always enabled. Note that lengthy operations in the connect ACL,
+such as DNSBL lookups, will still delay the emission of the SMTP banner.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>hosts_try_prdr</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>hosts_try_prdr</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>PRDR</primary>
+<secondary>enabling, optional in client</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>PRDR</secondary>
+</indexterm>
+This option provides a list of servers to which, provided they announce
+PRDR support, Exim will attempt to negotiate PRDR
+for multi-recipient messages.
+The option can usually be left as default.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>interface</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>interface</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>bind IP address</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>IP address</primary>
+<secondary>binding</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host_address</varname></primary>
+</indexterm>
+This option specifies which interface to bind to when making an outgoing SMTP
+call. The value is an IP address, not an interface name such as
+<literal>eth0</literal>. Do not confuse this with the interface address that was used when a
+message was received, which is in <varname>$received_ip_address</varname>, formerly known as
+<varname>$interface_address</varname>. The name was changed to minimize confusion with the
+outgoing interface address. There is no variable that contains an outgoing
+interface address because, unless it is set by this option, its value is
+unknown.
+</para>
+<para>
+During the expansion of the <option>interface</option> option the variables <varname>$host</varname> and
+<varname>$host_address</varname> refer to the host to which a connection is about to be made
+during the expansion of the string. Forced expansion failure, or an empty
+string result causes the option to be ignored. Otherwise, after expansion, the
+string must be a list of IP addresses, colon-separated by default, but the
+separator can be changed in the usual way (<xref linkend="SECTlistsepchange"/>).
+For example:
+</para>
+<literallayout class="monospaced">
+interface = <; 192.168.123.123 ; 3ffe:ffff:836f::fe86:a061
+</literallayout>
+<para>
+The first interface of the correct type (IPv4 or IPv6) is used for the outgoing
+connection. If none of them are the correct type, the option is ignored. If
+<option>interface</option> is not set, or is ignored, the system’s IP functions choose which
+interface to use if the host has more than one.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>keepalive</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>keepalive</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>keepalive</primary>
+<secondary>on outgoing connection</secondary>
+</indexterm>
+This option controls the setting of SO_KEEPALIVE on outgoing TCP/IP socket
+connections. When set, it causes the kernel to probe idle connections
+periodically, by sending packets with <quote>old</quote> sequence numbers. The other end
+of the connection should send a acknowledgment if the connection is still okay
+or a reset if the connection has been aborted. The reason for doing this is
+that it has the beneficial effect of freeing up certain types of connection
+that can get stuck when the remote host is disconnected without tidying up the
+TCP/IP call properly. The keepalive mechanism takes several hours to detect
+unreachable hosts.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>lmtp_ignore_quota</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>lmtp_ignore_quota</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>LMTP</primary>
+<secondary>ignoring quota errors</secondary>
+</indexterm>
+If this option is set true when the <option>protocol</option> option is set to <quote>lmtp</quote>, the
+string <literal>IGNOREQUOTA</literal> is added to RCPT commands, provided that the LMTP server
+has advertised support for IGNOREQUOTA in its response to the LHLO command.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>max_rcpt</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>max_rcpt</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>100</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>RCPT</primary>
+<secondary>maximum number of outgoing</secondary>
+</indexterm>
+This option limits the number of RCPT commands that are sent in a single
+SMTP message transaction. Each set of addresses is treated independently, and
+so can cause parallel connections to the same host if <option>remote_max_parallel</option>
+permits this.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>multi_domain</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>multi_domain</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+When this option is set, the <command>smtp</command> transport can handle a number of
+addresses containing a mixture of different domains provided they all resolve
+to the same list of hosts. Turning the option off restricts the transport to
+handling only one domain at a time. This is useful if you want to use
+<varname>$domain</varname> in an expansion for the transport, because it is set only when there
+is a single domain involved in a remote delivery.
+</para>
+<para>
+It is expanded per-address and can depend on any of
+<varname>$address_data</varname>, <varname>$domain_data</varname>, <varname>$local_part_data</varname>,
+<varname>$host</varname>, <varname>$host_address</varname> and <varname>$host_port</varname>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>port</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>port</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>port</primary>
+<secondary>sending TCP/IP</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP/IP</primary>
+<secondary>setting outgoing port</secondary>
+</indexterm>
+This option specifies the TCP/IP port on the server to which Exim connects.
+<emphasis role="bold">Note:</emphasis> Do not confuse this with the port that was used when a message was
+received, which is in <varname>$received_port</varname>, formerly known as <varname>$interface_port</varname>.
+The name was changed to minimize confusion with the outgoing port. There is no
+variable that contains an outgoing port.
+</para>
+<para>
+If the value of this option begins with a digit it is taken as a port number;
+otherwise it is looked up using <function>getservbyname()</function>. The default value is
+normally <quote>smtp</quote>,
+but if <option>protocol</option> is set to <quote>lmtp</quote> the default is <quote>lmtp</quote>
+and if <option>protocol</option> is set to <quote>smtps</quote> the default is <quote>smtps</quote>.
+If the expansion fails, or if a port number cannot be found, delivery
+is deferred.
+</para>
+<para>
+Note that at least one Linux distribution has been seen failing
+to put <quote>smtps</quote> in its <quote>/etc/services</quote> file, resulting is such deferrals.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>protocol</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>protocol</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>smtp</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>LMTP</primary>
+<secondary>over TCP/IP</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ssmtp protocol</primary>
+<secondary>outbound</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>SSL-on-connect outbound</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$port</varname></primary>
+</indexterm>
+If this option is set to <quote>lmtp</quote> instead of <quote>smtp</quote>, the default value for
+the <option>port</option> option changes to <quote>lmtp</quote>, and the transport operates the LMTP
+protocol (RFC 2033) instead of SMTP. This protocol is sometimes used for local
+deliveries into closed message stores. Exim also has support for running LMTP
+over a pipe to a local process – see chapter <xref linkend="CHAPLMTP"/>.
+</para>
+<para>
+If this option is set to <quote>smtps</quote>, the default value for the <option>port</option> option
+changes to <quote>smtps</quote>, and the transport initiates TLS immediately after
+connecting, as an outbound SSL-on-connect, instead of using STARTTLS to upgrade.
+The Internet standards bodies used to strongly discourage use of this mode,
+but as of RFC 8314 it is perferred over STARTTLS for message submission
+(as distinct from MTA-MTA communication).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>retry_include_ip_address</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>retry_include_ip_address</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Exim normally includes both the host name and the IP address in the key it
+constructs for indexing retry data after a temporary delivery failure. This
+means that when one of several IP addresses for a host is failing, it gets
+tried periodically (controlled by the retry rules), but use of the other IP
+addresses is not affected.
+</para>
+<para>
+However, in some dialup environments hosts are assigned a different IP address
+each time they connect. In this situation the use of the IP address as part of
+the retry key leads to undesirable behaviour. Setting this option false causes
+Exim to use only the host name.
+Since it is expanded it can be made to depend on the host or domain.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>serialize_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>serialize_hosts</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>serializing connections</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>serializing connections</secondary>
+</indexterm>
+Because Exim operates in a distributed manner, if several messages for the same
+host arrive at around the same time, more than one simultaneous connection to
+the remote host can occur. This is not usually a problem except when there is a
+slow link between the hosts. In that situation it may be helpful to restrict
+Exim to one connection at a time. This can be done by setting
+<option>serialize_hosts</option> to match the relevant hosts.
+</para>
+<para>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>serializing deliveries to a host</secondary>
+</indexterm>
+Exim implements serialization by means of a hints database in which a record is
+written whenever a process connects to one of the restricted hosts. The record
+is deleted when the connection is completed. Obviously there is scope for
+records to get left lying around if there is a system or program crash. To
+guard against this, Exim ignores any records that are more than six hours old.
+</para>
+<para>
+If you set up this kind of serialization, you should also arrange to delete the
+relevant hints database whenever your system reboots. The names of the files
+start with <filename>misc</filename> and they are kept in the <filename>spool/db</filename> directory. There
+may be one or two files, depending on the type of DBM in use. The same files
+are used for ETRN serialization.
+</para>
+<para>
+See also the <option>max_parallel</option> generic transport option.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>size_addition</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>size_addition</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>1024</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>SIZE</primary>
+<secondary>ESMTP extension</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>size issue for transport filter</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>size</primary>
+<secondary>of message</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>filter</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>transport filter</secondary>
+</indexterm>
+If a remote SMTP server indicates that it supports the SIZE option of the
+MAIL command, Exim uses this to pass over the message size at the start of
+an SMTP transaction. It adds the value of <option>size_addition</option> to the value it
+sends, to allow for headers and other text that may be added during delivery by
+configuration options or in a transport filter. It may be necessary to increase
+this if a lot of text is added to messages.
+</para>
+<para>
+Alternatively, if the value of <option>size_addition</option> is set negative, it disables
+the use of the SIZE option altogether.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>socks_proxy</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>socks_proxy</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>proxy</primary>
+<secondary>SOCKS</secondary>
+</indexterm>
+This option enables use of SOCKS proxies for connections made by the
+transport. For details see section <xref linkend="SECTproxySOCKS"/>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_certificate</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_certificate</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>client certificate, location of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>client, location of</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host_address</varname></primary>
+</indexterm>
+The value of this option must be the absolute path to a file which contains the
+client’s certificate, for possible use when sending a message over an encrypted
+connection. The values of <varname>$host</varname> and <varname>$host_address</varname> are set to the name and
+address of the server during the expansion. See chapter <xref linkend="CHAPTLS"/> for
+details of TLS.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: This option must be set if you want Exim to be able to use a TLS
+certificate when sending messages as a client. The global option of the same
+name specifies the certificate for Exim as a server; it is not automatically
+assumed that the same certificate should be used when Exim is operating as a
+client.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_crl</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_crl</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>client certificate revocation list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>revocation list for client</secondary>
+</indexterm>
+This option specifies a certificate revocation list. The expanded value must
+be the name of a file that contains a CRL in PEM format.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_dh_min_bits</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_dh_min_bits</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis></entry>
+<entry>Default: <emphasis>1024</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>Diffie-Hellman minimum acceptable size</secondary>
+</indexterm>
+When establishing a TLS session, if a ciphersuite which uses Diffie-Hellman
+key agreement is negotiated, the server will provide a large prime number
+for use. This option establishes the minimum acceptable size of that number.
+If the parameter offered by the server is too small, then the TLS handshake
+will fail.
+</para>
+<para>
+Only supported when using GnuTLS.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_privatekey</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_privatekey</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>client private key, location of</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host_address</varname></primary>
+</indexterm>
+The value of this option must be the absolute path to a file which contains the
+client’s private key. This is used when sending a message over an encrypted
+connection using a client certificate. The values of <varname>$host</varname> and
+<varname>$host_address</varname> are set to the name and address of the server during the
+expansion. If this option is unset, or the expansion is forced to fail, or the
+result is an empty string, the private key is assumed to be in the same file as
+the certificate. See chapter <xref linkend="CHAPTLS"/> for details of TLS.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_require_ciphers</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_require_ciphers</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>requiring specific ciphers</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>cipher</primary>
+<secondary>requiring specific</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host_address</varname></primary>
+</indexterm>
+The value of this option must be a list of permitted cipher suites, for use
+when setting up an outgoing encrypted connection. (There is a global option of
+the same name for controlling incoming connections.) The values of <varname>$host</varname> and
+<varname>$host_address</varname> are set to the name and address of the server during the
+expansion. See chapter <xref linkend="CHAPTLS"/> for details of TLS; note that this option
+is used in different ways by OpenSSL and GnuTLS (see sections
+<xref linkend="SECTreqciphssl"/> and <xref linkend="SECTreqciphgnu"/>). For GnuTLS, the order of the
+ciphers is a preference order.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_sni</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_sni</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>Server Name Indication</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tls_sni</varname></primary>
+</indexterm>
+If this option is set then it sets the $tls_out_sni variable and causes any
+TLS session to pass this value as the Server Name Indication extension to
+the remote side, which can be used by the remote side to select an appropriate
+certificate and private key for the session.
+</para>
+<para>
+See <xref linkend="SECTtlssni"/> for more information.
+</para>
+<para>
+Note that for OpenSSL, this feature requires a build of OpenSSL that supports
+TLS extensions.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_tempfail_tryclear</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_tempfail_tryclear</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>true</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>4<emphasis>xx</emphasis> responses</primary>
+<secondary>to STARTTLS</secondary>
+</indexterm>
+When the server host is not in <option>hosts_require_tls</option>, and there is a problem in
+setting up a TLS session, this option determines whether or not Exim should try
+to deliver the message unencrypted. If it is set false, delivery to the
+current host is deferred; if there are other hosts, they are tried. If this
+option is set true, Exim attempts to deliver unencrypted after a 4<emphasis>xx</emphasis>
+response to STARTTLS. Also, if STARTTLS is accepted, but the subsequent
+TLS negotiation fails, Exim closes the current connection (because it is in an
+unknown state), opens a new one to the same host, and then tries the delivery
+in clear.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_try_verify_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_try_verify_hosts</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>server certificate verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>verification of server</secondary>
+</indexterm>
+This option gives a list of hosts for which, on encrypted connections,
+certificate verification will be tried but need not succeed.
+The <option>tls_verify_certificates</option> option must also be set.
+Note that unless the host is in this list
+TLS connections will be denied to hosts using self-signed certificates
+when <option>tls_verify_certificates</option> is matched.
+The <varname>$tls_out_certificate_verified</varname> variable is set when
+certificate verification succeeds.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_verify_cert_hostnames</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_verify_cert_hostnames</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>*</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>server certificate hostname verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>verification of server</secondary>
+</indexterm>
+This option give a list of hosts for which,
+while verifying the server certificate,
+checks will be included on the host name
+(note that this will generally be the result of a DNS MX lookup)
+versus Subject and Subject-Alternate-Name fields. Wildcard names are permitted
+limited to being the initial component of a 3-or-more component FQDN.
+</para>
+<para>
+There is no equivalent checking on client certificates.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_verify_certificates</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_verify_certificates</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>system</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>server certificate verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>verification of server</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host_address</varname></primary>
+</indexterm>
+The value of this option must be either the
+word "system"
+or the absolute path to
+a file or directory containing permitted certificates for servers,
+for use when setting up an encrypted connection.
+</para>
+<para>
+The "system" value for the option will use a location compiled into the SSL library.
+This is not available for GnuTLS versions preceding 3.0.20; a value of "system"
+is taken as empty and an explicit location
+must be specified.
+</para>
+<para>
+The use of a directory for the option value is not available for GnuTLS versions
+preceding 3.3.6 and a single file must be used.
+</para>
+<para>
+With OpenSSL the certificates specified
+explicitly
+either by file or directory
+are added to those given by the system default location.
+</para>
+<para>
+The values of <varname>$host</varname> and
+<varname>$host_address</varname> are set to the name and address of the server during the
+expansion of this option. See chapter <xref linkend="CHAPTLS"/> for details of TLS.
+</para>
+<para>
+For back-compatibility,
+if neither tls_verify_hosts nor tls_try_verify_hosts are set
+(a single-colon empty list counts as being set)
+and certificate verification fails the TLS connection is closed.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>tls_verify_hosts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>tls_verify_hosts</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>host list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>server certificate verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>verification of server</secondary>
+</indexterm>
+This option gives a list of hosts for which, on encrypted connections,
+certificate verification must succeed.
+The <option>tls_verify_certificates</option> option must also be set.
+If both this option and <option>tls_try_verify_hosts</option> are unset
+operation is as if this option selected all hosts.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>utf8_downconvert</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>utf8_downconvert</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>-1</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>utf8</primary>
+<secondary>address downconversion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>i18n</primary>
+<secondary>utf8 address downconversion</secondary>
+</indexterm>
+If built with internationalization support,
+this option controls conversion of UTF-8 in message envelope addresses
+to a-label form.
+If, after expansion, the value is 1, 0, or -1 then this value overrides
+any value previously set for the message. Otherwise, any previously
+set value is used. To permit use of a previous value,
+set this option to an empty string.
+For details on the values see section <xref linkend="SECTi18nMTA"/>.
+</para>
+</section>
+<section id="SECTvalhosmax">
+<title>How the limits for the number of hosts to try are used</title>
+<para>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>maximum number to try</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>hosts; maximum number tried</secondary>
+</indexterm>
+There are two options that are concerned with the number of hosts that are
+tried when an SMTP delivery takes place. They are <option>hosts_max_try</option> and
+<option>hosts_max_try_hardlimit</option>.
+</para>
+<para>
+The <option>hosts_max_try</option> option limits the number of hosts that are tried
+for a single delivery. However, despite the term <quote>host</quote> in its name, the
+option actually applies to each IP address independently. In other words, a
+multihomed host is treated as several independent hosts, just as it is for
+retrying.
+</para>
+<para>
+Many of the larger ISPs have multiple MX records which often point to
+multihomed hosts. As a result, a list of a dozen or more IP addresses may be
+created as a result of routing one of these domains.
+</para>
+<para>
+Trying every single IP address on such a long list does not seem sensible; if
+several at the top of the list fail, it is reasonable to assume there is some
+problem that is likely to affect all of them. Roughly speaking, the value of
+<option>hosts_max_try</option> is the maximum number that are tried before deferring the
+delivery. However, the logic cannot be quite that simple.
+</para>
+<para>
+Firstly, IP addresses that are skipped because their retry times have not
+arrived do not count, and in addition, addresses that are past their retry
+limits are also not counted, even when they are tried. This means that when
+some IP addresses are past their retry limits, more than the value of
+<option>hosts_max_retry</option> may be tried. The reason for this behaviour is to ensure
+that all IP addresses are considered before timing out an email address (but
+see below for an exception).
+</para>
+<para>
+Secondly, when the <option>hosts_max_try</option> limit is reached, Exim looks down the host
+list to see if there is a subsequent host with a different (higher valued) MX.
+If there is, that host is considered next, and the current IP address is used
+but not counted. This behaviour helps in the case of a domain with a retry rule
+that hardly ever delays any hosts, as is now explained:
+</para>
+<para>
+Consider the case of a long list of hosts with one MX value, and a few with a
+higher MX value. If <option>hosts_max_try</option> is small (the default is 5) only a few
+hosts at the top of the list are tried at first. With the default retry rule,
+which specifies increasing retry times, the higher MX hosts are eventually
+tried when those at the top of the list are skipped because they have not
+reached their retry times.
+</para>
+<para>
+However, it is common practice to put a fixed short retry time on domains for
+large ISPs, on the grounds that their servers are rarely down for very long.
+Unfortunately, these are exactly the domains that tend to resolve to long lists
+of hosts. The short retry time means that the lowest MX hosts are tried every
+time. The attempts may be in a different order because of random sorting, but
+without the special MX check, the higher MX hosts would never be tried until
+all the lower MX hosts had timed out (which might be several days), because
+there are always some lower MX hosts that have reached their retry times. With
+the special check, Exim considers at least one IP address from each MX value at
+every delivery attempt, even if the <option>hosts_max_try</option> limit has already been
+reached.
+</para>
+<para>
+The above logic means that <option>hosts_max_try</option> is not a hard limit, and in
+particular, Exim normally eventually tries all the IP addresses before timing
+out an email address. When <option>hosts_max_try</option> was implemented, this seemed a
+reasonable thing to do. Recently, however, some lunatic DNS configurations have
+been set up with hundreds of IP addresses for some domains. It can
+take a very long time indeed for an address to time out in these cases.
+</para>
+<para>
+The <option>hosts_max_try_hardlimit</option> option was added to help with this problem.
+Exim never tries more than this number of IP addresses; if it hits this limit
+and they are all timed out, the email address is bounced, even though not all
+possible IP addresses have been tried.
+<indexterm role="concept" startref="IIDsmttra1" class="endofrange"/>
+<indexterm role="concept" startref="IIDsmttra2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPrewrite">
+<title>Address rewriting</title>
+<para>
+<indexterm role="concept" id="IIDaddrew" class="startofrange">
+<primary>rewriting</primary>
+<secondary>addresses</secondary>
+</indexterm>
+There are some circumstances in which Exim automatically rewrites domains in
+addresses. The two most common are when an address is given without a domain
+(referred to as an <quote>unqualified address</quote>) or when an address contains an
+abbreviated domain that is expanded by DNS lookup.
+</para>
+<para>
+Unqualified envelope addresses are accepted only for locally submitted
+messages, or for messages that are received from hosts matching
+<option>sender_unqualified_hosts</option> or <option>recipient_unqualified_hosts</option>, as
+appropriate. Unqualified addresses in header lines are qualified if they are in
+locally submitted messages, or messages from hosts that are permitted to send
+unqualified envelope addresses. Otherwise, unqualified addresses in header
+lines are neither qualified nor rewritten.
+</para>
+<para>
+One situation in which Exim does <emphasis>not</emphasis> automatically rewrite a domain is
+when it is the name of a CNAME record in the DNS. The older RFCs suggest that
+such a domain should be rewritten using the <quote>canonical</quote> name, and some MTAs
+do this. The new RFCs do not contain this suggestion.
+</para>
+<section id="SECID147">
+<title>Explicitly configured address rewriting</title>
+<para>
+This chapter describes the rewriting rules that can be used in the
+main rewrite section of the configuration file, and also in the generic
+<option>headers_rewrite</option> option that can be set on any transport.
+</para>
+<para>
+Some people believe that configured address rewriting is a Mortal Sin.
+Others believe that life is not possible without it. Exim provides the
+facility; you do not have to use it.
+</para>
+<para>
+The main rewriting rules that appear in the <quote>rewrite</quote> section of the
+configuration file are applied to addresses in incoming messages, both envelope
+addresses and addresses in header lines. Each rule specifies the types of
+address to which it applies.
+</para>
+<para>
+Whether or not addresses in header lines are rewritten depends on the origin of
+the headers and the type of rewriting. Global rewriting, that is, rewriting
+rules from the rewrite section of the configuration file, is applied only to
+those headers that were received with the message. Header lines that are added
+by ACLs or by a system filter or by individual routers or transports (which
+are specific to individual recipient addresses) are not rewritten by the global
+rules.
+</para>
+<para>
+Rewriting at transport time, by means of the <option>headers_rewrite</option> option,
+applies all headers except those added by routers and transports. That is, as
+well as the headers that were received with the message, it also applies to
+headers that were added by an ACL or a system filter.
+</para>
+<para>
+In general, rewriting addresses from your own system or domain has some
+legitimacy. Rewriting other addresses should be done only with great care and
+in special circumstances. The author of Exim believes that rewriting should be
+used sparingly, and mainly for <quote>regularizing</quote> addresses in your own domains.
+Although it can sometimes be used as a routing tool, this is very strongly
+discouraged.
+</para>
+<para>
+There are two commonly encountered circumstances where rewriting is used, as
+illustrated by these examples:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The company whose domain is <emphasis>hitch.fict.example</emphasis> has a number of hosts that
+exchange mail with each other behind a firewall, but there is only a single
+gateway to the outer world. The gateway rewrites <emphasis>*.hitch.fict.example</emphasis> as
+<emphasis>hitch.fict.example</emphasis> when sending mail off-site.
+</para>
+</listitem>
+<listitem>
+<para>
+A host rewrites the local parts of its own users so that, for example,
+<emphasis>fp42@hitch.fict.example</emphasis> becomes <emphasis>Ford.Prefect@hitch.fict.example</emphasis>.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID148">
+<title>When does rewriting happen?</title>
+<para>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>timing of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>rewriting addresses in</secondary>
+</indexterm>
+Configured address rewriting can take place at several different stages of a
+message’s processing.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_address</varname></primary>
+</indexterm>
+At the start of an ACL for MAIL, the sender address may have been rewritten
+by a special SMTP-time rewrite rule (see section <xref linkend="SECTrewriteS"/>), but no
+ordinary rewrite rules have yet been applied. If, however, the sender address
+is verified in the ACL, it is rewritten before verification, and remains
+rewritten thereafter. The subsequent value of <varname>$sender_address</varname> is the
+rewritten address. This also applies if sender verification happens in a
+RCPT ACL. Otherwise, when the sender address is not verified, it is
+rewritten as soon as a message’s header lines have been received.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+Similarly, at the start of an ACL for RCPT, the current recipient’s address
+may have been rewritten by a special SMTP-time rewrite rule, but no ordinary
+rewrite rules have yet been applied to it. However, the behaviour is different
+from the sender address when a recipient is verified. The address is rewritten
+for the verification, but the rewriting is not remembered at this stage. The
+value of <varname>$local_part</varname> and <varname>$domain</varname> after verification are always the same
+as they were before (that is, they contain the unrewritten – except for
+SMTP-time rewriting – address).
+</para>
+<para>
+As soon as a message’s header lines have been received, all the envelope
+recipient addresses are permanently rewritten, and rewriting is also applied to
+the addresses in the header lines (if configured). This happens before adding
+any header lines that were specified in MAIL or RCPT ACLs, and
+<indexterm role="concept">
+<primary><function>local_scan()</function> function</primary>
+<secondary>address rewriting; timing of</secondary>
+</indexterm>
+before the DATA ACL and <function>local_scan()</function> functions are run.
+</para>
+<para>
+When an address is being routed, either for delivery or for verification,
+rewriting is applied immediately to child addresses that are generated by
+redirection, unless <option>no_rewrite</option> is set on the router.
+</para>
+<para>
+<indexterm role="concept">
+<primary>envelope from</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope sender</primary>
+<secondary>rewriting at transport time</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>at transport time</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>rewriting at transport time</secondary>
+</indexterm>
+At transport time, additional rewriting of addresses in header lines can be
+specified by setting the generic <option>headers_rewrite</option> option on a transport.
+This option contains rules that are identical in form to those in the rewrite
+section of the configuration file. They are applied to the original message
+header lines and any that were added by ACLs or a system filter. They are not
+applied to header lines that are added by routers or the transport.
+</para>
+<para>
+The outgoing envelope sender can be rewritten by means of the <option>return_path</option>
+transport option. However, it is not possible to rewrite envelope recipients at
+transport time.
+</para>
+</section>
+<section id="SECID149">
+<title>Testing the rewriting rules that apply on input</title>
+<para>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>testing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>testing</primary>
+<secondary>rewriting</secondary>
+</indexterm>
+Exim’s input rewriting configuration appears in a part of the runtime
+configuration file headed by <quote>begin rewrite</quote>. It can be tested by the
+<option>-brw</option> command line option. This takes an address (which can be a full RFC
+2822 address) as its argument. The output is a list of how the address would be
+transformed by the rewriting rules for each of the different places it might
+appear in an incoming message, that is, for each different header and for the
+envelope sender and recipient fields. For example,
+</para>
+<literallayout class="monospaced">
+exim -brw ph10@exim.workshop.example
+</literallayout>
+<para>
+might produce the output
+</para>
+<literallayout class="monospaced">
+sender: Philip.Hazel@exim.workshop.example
+from: Philip.Hazel@exim.workshop.example
+to: ph10@exim.workshop.example
+cc: ph10@exim.workshop.example
+bcc: ph10@exim.workshop.example
+reply-to: Philip.Hazel@exim.workshop.example
+env-from: Philip.Hazel@exim.workshop.example
+env-to: ph10@exim.workshop.example
+</literallayout>
+<para>
+which shows that rewriting has been set up for that address when used in any of
+the source fields, but not when it appears as a recipient address. At the
+present time, there is no equivalent way of testing rewriting rules that are
+set for a particular transport.
+</para>
+</section>
+<section id="SECID150">
+<title>Rewriting rules</title>
+<para>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>rules</secondary>
+</indexterm>
+The rewrite section of the configuration file consists of lines of rewriting
+rules in the form
+</para>
+<literallayout>
+<<emphasis>source pattern</emphasis>> <<emphasis>replacement</emphasis>> <<emphasis>flags</emphasis>>
+</literallayout>
+<para>
+Rewriting rules that are specified for the <option>headers_rewrite</option> generic
+transport option are given as a colon-separated list. Each item in the list
+takes the same form as a line in the main rewriting configuration (except that
+any colons must be doubled, of course).
+</para>
+<para>
+The formats of source patterns and replacement strings are described below.
+Each is terminated by white space, unless enclosed in double quotes, in which
+case normal quoting conventions apply inside the quotes. The flags are single
+characters which may appear in any order. Spaces and tabs between them are
+ignored.
+</para>
+<para>
+For each address that could potentially be rewritten, the rules are scanned in
+order, and replacements for the address from earlier rules can themselves be
+replaced by later rules (but see the <quote>q</quote> and <quote>R</quote> flags).
+</para>
+<para>
+The order in which addresses are rewritten is undefined, may change between
+releases, and must not be relied on, with one exception: when a message is
+received, the envelope sender is always rewritten first, before any header
+lines are rewritten. For example, the replacement string for a rewrite of an
+address in <emphasis>To:</emphasis> must not assume that the message’s address in <emphasis>From:</emphasis> has
+(or has not) already been rewritten. However, a rewrite of <emphasis>From:</emphasis> may assume
+that the envelope sender has already been rewritten.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+The variables <varname>$local_part</varname> and <varname>$domain</varname> can be used in the replacement
+string to refer to the address that is being rewritten. Note that lookup-driven
+rewriting can be done by a rule of the form
+</para>
+<literallayout class="monospaced">
+*@* ${lookup ...
+</literallayout>
+<para>
+where the lookup key uses <varname>$1</varname> and <varname>$2</varname> or <varname>$local_part</varname> and <varname>$domain</varname> to
+refer to the address that is being rewritten.
+</para>
+</section>
+<section id="SECID151">
+<title>Rewriting patterns</title>
+<para>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>patterns</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address list</primary>
+<secondary>in a rewriting pattern</secondary>
+</indexterm>
+The source pattern in a rewriting rule is any item which may appear in an
+address list (see section <xref linkend="SECTaddresslist"/>). It is in fact processed as a
+single-item address list, which means that it is expanded before being tested
+against the address. As always, if you use a regular expression as a pattern,
+you must take care to escape dollar and backslash characters, or use the <literal>\N</literal>
+facility to suppress string expansion within the regular expression.
+</para>
+<para>
+Domains in patterns should be given in lower case. Local parts in patterns are
+case-sensitive. If you want to do case-insensitive matching of local parts, you
+can use a regular expression that starts with <literal>^(?i)</literal>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>numerical variables (<varname>$1</varname> <varname>$2</varname> etc)</primary>
+<secondary>in rewriting rules</secondary>
+</indexterm>
+After matching, the numerical variables <varname>$1</varname>, <varname>$2</varname>, etc. may be set,
+depending on the type of match which occurred. These can be used in the
+replacement string to insert portions of the incoming address. <varname>$0</varname> always
+refers to the complete incoming address. When a regular expression is used, the
+numerical variables are set from its capturing subexpressions. For other types
+of pattern they are set as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If a local part or domain starts with an asterisk, the numerical variables
+refer to the character strings matched by asterisks, with <varname>$1</varname> associated with
+the first asterisk, and <varname>$2</varname> with the second, if present. For example, if the
+pattern
+</para>
+<literallayout class="monospaced">
+*queen@*.fict.example
+</literallayout>
+<para>
+is matched against the address <emphasis>hearts-queen@wonderland.fict.example</emphasis> then
+</para>
+<literallayout class="monospaced">
+$0 = hearts-queen@wonderland.fict.example
+$1 = hearts-
+$2 = wonderland
+</literallayout>
+<para>
+Note that if the local part does not start with an asterisk, but the domain
+does, it is <varname>$1</varname> that contains the wild part of the domain.
+</para>
+</listitem>
+<listitem>
+<para>
+If the domain part of the pattern is a partial lookup, the wild and fixed parts
+of the domain are placed in the next available numerical variables. Suppose,
+for example, that the address <emphasis>foo@bar.baz.example</emphasis> is processed by a
+rewriting rule of the form
+</para>
+<literallayout>
+<literal>*@partial-dbm;/some/dbm/file</literal> <<emphasis>replacement string</emphasis>>
+</literallayout>
+<para>
+and the key in the file that matches the domain is <literal>*.baz.example</literal>. Then
+</para>
+<literallayout class="monospaced">
+$1 = foo
+$2 = bar
+$3 = baz.example
+</literallayout>
+<para>
+If the address <emphasis>foo@baz.example</emphasis> is looked up, this matches the same
+wildcard file entry, and in this case <varname>$2</varname> is set to the empty string, but
+<varname>$3</varname> is still set to <emphasis>baz.example</emphasis>. If a non-wild key is matched in a
+partial lookup, <varname>$2</varname> is again set to the empty string and <varname>$3</varname> is set to the
+whole domain. For non-partial domain lookups, no numerical variables are set.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID152">
+<title>Rewriting replacements</title>
+<para>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>replacements</secondary>
+</indexterm>
+If the replacement string for a rule is a single asterisk, addresses that
+match the pattern and the flags are <emphasis>not</emphasis> rewritten, and no subsequent
+rewriting rules are scanned. For example,
+</para>
+<literallayout class="monospaced">
+hatta@lookingglass.fict.example * f
+</literallayout>
+<para>
+specifies that <emphasis>hatta@lookingglass.fict.example</emphasis> is never to be rewritten in
+<emphasis>From:</emphasis> headers.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+If the replacement string is not a single asterisk, it is expanded, and must
+yield a fully qualified address. Within the expansion, the variables
+<varname>$local_part</varname> and <varname>$domain</varname> refer to the address that is being rewritten.
+Any letters they contain retain their original case – they are not lower
+cased. The numerical variables are set up according to the type of pattern that
+matched the address, as described above. If the expansion is forced to fail by
+the presence of <quote>fail</quote> in a conditional or lookup item, rewriting by the
+current rule is abandoned, but subsequent rules may take effect. Any other
+expansion failure causes the entire rewriting operation to be abandoned, and an
+entry written to the panic log.
+</para>
+</section>
+<section id="SECID153">
+<title>Rewriting flags</title>
+<para>
+There are three different kinds of flag that may appear on rewriting rules:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Flags that specify which headers and envelope addresses to rewrite: E, F, T, b,
+c, f, h, r, s, t.
+</para>
+</listitem>
+<listitem>
+<para>
+A flag that specifies rewriting at SMTP time: S.
+</para>
+</listitem>
+<listitem>
+<para>
+Flags that control the rewriting process: Q, q, R, w.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+For rules that are part of the <option>headers_rewrite</option> generic transport option,
+E, F, T, and S are not permitted.
+</para>
+</section>
+<section id="SECID154">
+<title>Flags specifying which headers and envelope addresses to rewrite</title>
+<para>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>flags</secondary>
+</indexterm>
+If none of the following flag letters, nor the <quote>S</quote> flag (see section
+<xref linkend="SECTrewriteS"/>) are present, a main rewriting rule applies to all headers
+and to both the sender and recipient fields of the envelope, whereas a
+transport-time rewriting rule just applies to all headers. Otherwise, the
+rewriting rule is skipped unless the relevant addresses are being processed.
+</para>
+<literallayout>
+<literal>E</literal> rewrite all envelope fields
+<literal>F</literal> rewrite the envelope From field
+<literal>T</literal> rewrite the envelope To field
+<literal>b</literal> rewrite the <emphasis>Bcc:</emphasis> header
+<literal>c</literal> rewrite the <emphasis>Cc:</emphasis> header
+<literal>f</literal> rewrite the <emphasis>From:</emphasis> header
+<literal>h</literal> rewrite all headers
+<literal>r</literal> rewrite the <emphasis>Reply-To:</emphasis> header
+<literal>s</literal> rewrite the <emphasis>Sender:</emphasis> header
+<literal>t</literal> rewrite the <emphasis>To:</emphasis> header
+</literallayout>
+<para>
+"All headers" means all of the headers listed above that can be selected
+individually, plus their <emphasis>Resent-</emphasis> versions. It does not include
+other headers such as <emphasis>Subject:</emphasis> etc.
+</para>
+<para>
+You should be particularly careful about rewriting <emphasis>Sender:</emphasis> headers, and
+restrict this to special known cases in your own domains.
+</para>
+</section>
+<section id="SECTrewriteS">
+<title>The SMTP-time rewriting flag</title>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>rewriting malformed addresses</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>RCPT</primary>
+<secondary>rewriting argument of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>MAIL</primary>
+<secondary>rewriting argument of</secondary>
+</indexterm>
+The rewrite flag <quote>S</quote> specifies a rewrite of incoming envelope addresses at
+SMTP time, as soon as an address is received in a MAIL or RCPT command, and
+before any other processing; even before syntax checking. The pattern is
+required to be a regular expression, and it is matched against the whole of the
+data for the command, including any surrounding angle brackets.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+This form of rewrite rule allows for the handling of addresses that are not
+compliant with RFCs 2821 and 2822 (for example, <quote>bang paths</quote> in batched SMTP
+input). Because the input is not required to be a syntactically valid address,
+the variables <varname>$local_part</varname> and <varname>$domain</varname> are not available during the
+expansion of the replacement string. The result of rewriting replaces the
+original address in the MAIL or RCPT command.
+</para>
+</section>
+<section id="SECID155">
+<title>Flags controlling the rewriting process</title>
+<para>
+There are four flags which control the way the rewriting process works. These
+take effect only when a rule is invoked, that is, when the address is of the
+correct type (matches the flags) and matches the pattern:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If the <quote>Q</quote> flag is set on a rule, the rewritten address is permitted to be an
+unqualified local part. It is qualified with <option>qualify_recipient</option>. In the
+absence of <quote>Q</quote> the rewritten address must always include a domain.
+</para>
+</listitem>
+<listitem>
+<para>
+If the <quote>q</quote> flag is set on a rule, no further rewriting rules are considered,
+even if no rewriting actually takes place because of a <quote>fail</quote> in the
+expansion. The <quote>q</quote> flag is not effective if the address is of the wrong type
+(does not match the flags) or does not match the pattern.
+</para>
+</listitem>
+<listitem>
+<para>
+The <quote>R</quote> flag causes a successful rewriting rule to be re-applied to the new
+address, up to ten times. It can be combined with the <quote>q</quote> flag, to stop
+rewriting once it fails to match (after at least one successful rewrite).
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>whole addresses</secondary>
+</indexterm>
+When an address in a header is rewritten, the rewriting normally applies only
+to the working part of the address, with any comments and RFC 2822 <quote>phrase</quote>
+left unchanged. For example, rewriting might change
+</para>
+<literallayout class="monospaced">
+From: Ford Prefect <fp42@restaurant.hitch.fict.example>
+</literallayout>
+<para>
+into
+</para>
+<literallayout class="monospaced">
+From: Ford Prefect <prefectf@hitch.fict.example>
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>RFC 2047</primary>
+</indexterm>
+Sometimes there is a need to replace the whole address item, and this can be
+done by adding the flag letter <quote>w</quote> to a rule. If this is set on a rule that
+causes an address in a header line to be rewritten, the entire address is
+replaced, not just the working part. The replacement must be a complete RFC
+2822 address, including the angle brackets if necessary. If text outside angle
+brackets contains a character whose value is greater than 126 or less than 32
+(except for tab), the text is encoded according to RFC 2047. The character set
+is taken from <option>headers_charset</option>, which gets its default at build time.
+</para>
+<para>
+When the <quote>w</quote> flag is set on a rule that causes an envelope address to be
+rewritten, all but the working part of the replacement address is discarded.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID156">
+<title>Rewriting examples</title>
+<para>
+Here is an example of the two common rewriting paradigms:
+</para>
+<literallayout class="monospaced">
+*@*.hitch.fict.example $1@hitch.fict.example
+*@hitch.fict.example ${lookup{$1}dbm{/etc/realnames}\
+ {$value}fail}@hitch.fict.example bctfrF
+</literallayout>
+<para>
+Note the use of <quote>fail</quote> in the lookup expansion in the second rule, forcing
+the string expansion to fail if the lookup does not succeed. In this context it
+has the effect of leaving the original address unchanged, but Exim goes on to
+consider subsequent rewriting rules, if any, because the <quote>q</quote> flag is not
+present in that rule. An alternative to <quote>fail</quote> would be to supply <varname>$1</varname>
+explicitly, which would cause the rewritten address to be the same as before,
+at the cost of a small bit of processing. Not supplying either of these is an
+error, since the rewritten address would then contain no local part.
+</para>
+<para>
+The first example above replaces the domain with a superior, more general
+domain. This may not be desirable for certain local parts. If the rule
+</para>
+<literallayout class="monospaced">
+root@*.hitch.fict.example *
+</literallayout>
+<para>
+were inserted before the first rule, rewriting would be suppressed for the
+local part <emphasis>root</emphasis> at any domain ending in <emphasis>hitch.fict.example</emphasis>.
+</para>
+<para>
+Rewriting can be made conditional on a number of tests, by making use of
+<varname>${if</varname> in the expansion item. For example, to apply a rewriting rule only to
+messages that originate outside the local host:
+</para>
+<literallayout class="monospaced">
+*@*.hitch.fict.example "${if !eq {$sender_host_address}{}\
+ {$1@hitch.fict.example}fail}"
+</literallayout>
+<para>
+The replacement string is quoted in this example because it contains white
+space.
+</para>
+<para>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>bang paths</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>bang paths</primary>
+<secondary>rewriting</secondary>
+</indexterm>
+Exim does not handle addresses in the form of <quote>bang paths</quote>. If it sees such
+an address it treats it as an unqualified local part which it qualifies with
+the local qualification domain (if the source of the message is local or if the
+remote host is permitted to send unqualified addresses). Rewriting can
+sometimes be used to handle simple bang paths with a fixed number of
+components. For example, the rule
+</para>
+<literallayout class="monospaced">
+\N^([^!]+)!(.*)@your.domain.example$\N $2@$1
+</literallayout>
+<para>
+rewrites a two-component bang path <emphasis>host.name!user</emphasis> as the domain address
+<emphasis>user@host.name</emphasis>. However, there is a security implication in using this as
+a global rewriting rule for envelope addresses. It can provide a backdoor
+method for using your system as a relay, because the incoming addresses appear
+to be local. If the bang path addresses are received via SMTP, it is safer to
+use the <quote>S</quote> flag to rewrite them as they are received, so that relay checking
+can be done on the rewritten addresses.
+<indexterm role="concept" startref="IIDaddrew" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPretry">
+<title>Retry configuration</title>
+<para>
+<indexterm role="concept" id="IIDretconf1" class="startofrange">
+<primary>retry</primary>
+<secondary>configuration, description of</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDregconf2" class="startofrange">
+<primary>configuration file</primary>
+<secondary>retry section</secondary>
+</indexterm>
+The <quote>retry</quote> section of the runtime configuration file contains a list of
+retry rules that control how often Exim tries to deliver messages that cannot
+be delivered at the first attempt. If there are no retry rules (the section is
+empty or not present), there are no retries. In this situation, temporary
+errors are treated as permanent. The default configuration contains a single,
+general-purpose retry rule (see section <xref linkend="SECID57"/>). The <option>-brt</option> command
+line option can be used to test which retry rule will be used for a given
+address, domain and error.
+</para>
+<para>
+The most common cause of retries is temporary failure to deliver to a remote
+host because the host is down, or inaccessible because of a network problem.
+Exim’s retry processing in this case is applied on a per-host (strictly, per IP
+address) basis, not on a per-message basis. Thus, if one message has recently
+been delayed, delivery of a new message to the same host is not immediately
+tried, but waits for the host’s retry time to arrive. If the <option>retry_defer</option>
+log selector is set, the message
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>time not reached</secondary>
+</indexterm>
+<quote>retry time not reached</quote> is written to the main log whenever a delivery is
+skipped for this reason. Section <xref linkend="SECToutSMTPerr"/> contains more details of
+the handling of errors during remote deliveries.
+</para>
+<para>
+Retry processing applies to routing as well as to delivering, except as covered
+in the next paragraph. The retry rules do not distinguish between these
+actions. It is not possible, for example, to specify different behaviour for
+failures to route the domain <emphasis>snark.fict.example</emphasis> and failures to deliver to
+the host <emphasis>snark.fict.example</emphasis>. I didn’t think anyone would ever need this
+added complication, so did not implement it. However, although they share the
+same retry rule, the actual retry times for routing and transporting a given
+domain are maintained independently.
+</para>
+<para>
+When a delivery is not part of a queue run (typically an immediate delivery on
+receipt of a message), the routers are always run, and local deliveries are
+always attempted, even if retry times are set for them. This makes for better
+behaviour if one particular message is causing problems (for example, causing
+quota overflow, or provoking an error in a filter file). If such a delivery
+suffers a temporary failure, the retry data is updated as normal, and
+subsequent delivery attempts from queue runs occur only when the retry time for
+the local address is reached.
+</para>
+<section id="SECID157">
+<title>Changing retry rules</title>
+<para>
+If you change the retry rules in your configuration, you should consider
+whether or not to delete the retry data that is stored in Exim’s spool area in
+files with names like <filename>db/retry</filename>. Deleting any of Exim’s hints files is
+always safe; that is why they are called <quote>hints</quote>.
+</para>
+<para>
+The hints retry data contains suggested retry times based on the previous
+rules. In the case of a long-running problem with a remote host, it might
+record the fact that the host has timed out. If your new rules increase the
+timeout time for such a host, you should definitely remove the old retry data
+and let Exim recreate it, based on the new rules. Otherwise Exim might bounce
+messages that it should now be retaining.
+</para>
+</section>
+<section id="SECID158">
+<title>Format of retry rules</title>
+<para>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>rules</secondary>
+</indexterm>
+Each retry rule occupies one line and consists of three or four parts,
+separated by white space: a pattern, an error name, an optional list of sender
+addresses, and a list of retry parameters. The pattern and sender lists must be
+enclosed in double quotes if they contain white space. The rules are searched
+in order until one is found where the pattern, error name, and sender list (if
+present) match the failing host or address, the error that occurred, and the
+message’s sender, respectively.
+</para>
+<para>
+The pattern is any single item that may appear in an address list (see section
+<xref linkend="SECTaddresslist"/>). It is in fact processed as a one-item address list,
+which means that it is expanded before being tested against the address that
+has been delayed. A negated address list item is permitted. Address
+list processing treats a plain domain name as if it were preceded by <quote>*@</quote>,
+which makes it possible for many retry rules to start with just a domain. For
+example,
+</para>
+<literallayout class="monospaced">
+lookingglass.fict.example * F,24h,30m;
+</literallayout>
+<para>
+provides a rule for any address in the <emphasis>lookingglass.fict.example</emphasis> domain,
+whereas
+</para>
+<literallayout class="monospaced">
+alice@lookingglass.fict.example * F,24h,30m;
+</literallayout>
+<para>
+applies only to temporary failures involving the local part <option>alice</option>.
+In practice, almost all rules start with a domain name pattern without a local
+part.
+</para>
+<para>
+<indexterm role="concept">
+<primary>regular expressions</primary>
+<secondary>in retry rules</secondary>
+</indexterm>
+<emphasis role="bold">Warning</emphasis>: If you use a regular expression in a retry rule pattern, it
+must match a complete address, not just a domain, because that is how regular
+expressions work in address lists.
+</para>
+<literallayout>
+<literal>^\Nxyz\d+\.abc\.example$\N * G,1h,10m,2</literal> <option>Wrong</option>
+<literal>^\N[^@]+@xyz\d+\.abc\.example$\N * G,1h,10m,2</literal> <option>Right</option>
+</literallayout>
+</section>
+<section id="SECID159">
+<title>Choosing which retry rule to use for address errors</title>
+<para>
+When Exim is looking for a retry rule after a routing attempt has failed (for
+example, after a DNS timeout), each line in the retry configuration is tested
+against the complete address only if <option>retry_use_local_part</option> is set for the
+router. Otherwise, only the domain is used, except when matching against a
+regular expression, when the local part of the address is replaced with <quote>*</quote>.
+A domain on its own can match a domain pattern, or a pattern that starts with
+<quote>*@</quote>. By default, <option>retry_use_local_part</option> is true for routers where
+<option>check_local_user</option> is true, and false for other routers.
+</para>
+<para>
+Similarly, when Exim is looking for a retry rule after a local delivery has
+failed (for example, after a mailbox full error), each line in the retry
+configuration is tested against the complete address only if
+<option>retry_use_local_part</option> is set for the transport (it defaults true for all
+local transports).
+</para>
+<para>
+<indexterm role="concept">
+<primary>4<emphasis>xx</emphasis> responses</primary>
+<secondary>retry rules for</secondary>
+</indexterm>
+However, when Exim is looking for a retry rule after a remote delivery attempt
+suffers an address error (a 4<emphasis>xx</emphasis> SMTP response for a recipient address), the
+whole address is always used as the key when searching the retry rules. The
+rule that is found is used to create a retry time for the combination of the
+failing address and the message’s sender. It is the combination of sender and
+recipient that is delayed in subsequent queue runs until its retry time is
+reached. You can delay the recipient without regard to the sender by setting
+<option>address_retry_include_sender</option> false in the <command>smtp</command> transport but this can
+lead to problems with servers that regularly issue 4<emphasis>xx</emphasis> responses to RCPT
+commands.
+</para>
+</section>
+<section id="SECID160">
+<title>Choosing which retry rule to use for host and message errors</title>
+<para>
+For a temporary error that is not related to an individual address (for
+example, a connection timeout), each line in the retry configuration is checked
+twice. First, the name of the remote host is used as a domain name (preceded by
+<quote>*@</quote> when matching a regular expression). If this does not match the line,
+the domain from the email address is tried in a similar fashion. For example,
+suppose the MX records for <emphasis>a.b.c.example</emphasis> are
+</para>
+<literallayout class="monospaced">
+a.b.c.example MX 5 x.y.z.example
+ MX 6 p.q.r.example
+ MX 7 m.n.o.example
+</literallayout>
+<para>
+and the retry rules are
+</para>
+<literallayout class="monospaced">
+p.q.r.example * F,24h,30m;
+a.b.c.example * F,4d,45m;
+</literallayout>
+<para>
+and a delivery to the host <emphasis>x.y.z.example</emphasis> suffers a connection failure. The
+first rule matches neither the host nor the domain, so Exim looks at the second
+rule. This does not match the host, but it does match the domain, so it is used
+to calculate the retry time for the host <emphasis>x.y.z.example</emphasis>. Meanwhile, Exim
+tries to deliver to <emphasis>p.q.r.example</emphasis>. If this also suffers a host error, the
+first retry rule is used, because it matches the host.
+</para>
+<para>
+In other words, temporary failures to deliver to host <emphasis>p.q.r.example</emphasis> use the
+first rule to determine retry times, but for all the other hosts for the domain
+<emphasis>a.b.c.example</emphasis>, the second rule is used. The second rule is also used if
+routing to <emphasis>a.b.c.example</emphasis> suffers a temporary failure.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: The host name is used when matching the patterns, not its IP address.
+However, if a message is routed directly to an IP address without the use of a
+host name, for example, if a <command>manualroute</command> router contains a setting such as:
+</para>
+<literallayout class="monospaced">
+route_list = *.a.example 192.168.34.23
+</literallayout>
+<para>
+then the <quote>host name</quote> that is used when searching for a retry rule is the
+textual form of the IP address.
+</para>
+</section>
+<section id="SECID161">
+<title>Retry rules for specific errors</title>
+<para>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>specific errors; specifying</secondary>
+</indexterm>
+The second field in a retry rule is the name of a particular error, or an
+asterisk, which matches any error. The errors that can be tested for are:
+</para>
+<variablelist>
+<varlistentry>
+<term><option>auth_failed</option></term>
+<listitem>
+<para>
+Authentication failed when trying to send to a host in the
+<option>hosts_require_auth</option> list in an <command>smtp</command> transport.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>data_4xx</option></term>
+<listitem>
+<para>
+A 4<emphasis>xx</emphasis> error was received for an outgoing DATA command, either immediately
+after the command, or after sending the message’s data.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>mail_4xx</option></term>
+<listitem>
+<para>
+A 4<emphasis>xx</emphasis> error was received for an outgoing MAIL command.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>rcpt_4xx</option></term>
+<listitem>
+<para>
+A 4<emphasis>xx</emphasis> error was received for an outgoing RCPT command.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+For the three 4<emphasis>xx</emphasis> errors, either the first or both of the x’s can be given
+as specific digits, for example: <literal>mail_45x</literal> or <literal>rcpt_436</literal>. For example, to
+recognize 452 errors given to RCPT commands for addresses in a certain domain,
+and have retries every ten minutes with a one-hour timeout, you could set up a
+retry rule of this form:
+</para>
+<literallayout class="monospaced">
+the.domain.name rcpt_452 F,1h,10m
+</literallayout>
+<para>
+These errors apply to both outgoing SMTP (the <command>smtp</command> transport) and outgoing
+LMTP (either the <command>lmtp</command> transport, or the <command>smtp</command> transport in LMTP mode).
+</para>
+<variablelist>
+<varlistentry>
+<term><option>lost_connection</option></term>
+<listitem>
+<para>
+A server unexpectedly closed the SMTP connection. There may, of course,
+legitimate reasons for this (host died, network died), but if it repeats a lot
+for the same host, it indicates something odd.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>lookup</option></term>
+<listitem>
+<para>
+A DNS lookup for a host failed.
+Note that a <option>dnslookup</option> router will need to have matched
+its <option>fail_defer_domains</option> option for this retry type to be usable.
+Also note that a <option>manualroute</option> router will probably need
+its <option>host_find_failed</option> option set to <option>defer</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>refused_MX</option></term>
+<listitem>
+<para>
+A connection to a host obtained from an MX record was refused.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>refused_A</option></term>
+<listitem>
+<para>
+A connection to a host not obtained from an MX record was refused.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>refused</option></term>
+<listitem>
+<para>
+A connection was refused.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>timeout_connect_MX</option></term>
+<listitem>
+<para>
+A connection attempt to a host obtained from an MX record timed out.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>timeout_connect_A</option></term>
+<listitem>
+<para>
+A connection attempt to a host not obtained from an MX record timed out.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>timeout_connect</option></term>
+<listitem>
+<para>
+A connection attempt timed out.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>timeout_MX</option></term>
+<listitem>
+<para>
+There was a timeout while connecting or during an SMTP session with a host
+obtained from an MX record.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>timeout_A</option></term>
+<listitem>
+<para>
+There was a timeout while connecting or during an SMTP session with a host not
+obtained from an MX record.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>timeout</option></term>
+<listitem>
+<para>
+There was a timeout while connecting or during an SMTP session.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>tls_required</option></term>
+<listitem>
+<para>
+The server was required to use TLS (it matched <option>hosts_require_tls</option> in the
+<command>smtp</command> transport), but either did not offer TLS, or it responded with 4<emphasis>xx</emphasis>
+to STARTTLS, or there was a problem setting up the TLS connection.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>quota</option></term>
+<listitem>
+<para>
+A mailbox quota was exceeded in a local delivery by the <command>appendfile</command>
+transport.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>quota_</option><<emphasis>time</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>quota</primary>
+<secondary>error testing in retry rule</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>quota error testing</secondary>
+</indexterm>
+A mailbox quota was exceeded in a local delivery by the <command>appendfile</command>
+transport, and the mailbox has not been accessed for <<emphasis>time</emphasis>>. For example,
+<emphasis>quota_4d</emphasis> applies to a quota error when the mailbox has not been accessed
+for four days.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+<indexterm role="concept">
+<primary>mailbox</primary>
+<secondary>time of last read</secondary>
+</indexterm>
+The idea of <option>quota_</option><<emphasis>time</emphasis>> is to make it possible to have shorter
+timeouts when the mailbox is full and is not being read by its owner. Ideally,
+it should be based on the last time that the user accessed the mailbox.
+However, it is not always possible to determine this. Exim uses the following
+heuristic rules:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If the mailbox is a single file, the time of last access (the <quote>atime</quote>) is
+used. As no new messages are being delivered (because the mailbox is over
+quota), Exim does not access the file, so this is the time of last user access.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>maildir format</primary>
+<secondary>time of last read</secondary>
+</indexterm>
+For a maildir delivery, the time of last modification of the <filename>new</filename>
+subdirectory is used. As the mailbox is over quota, no new files are created in
+the <filename>new</filename> subdirectory, because no new messages are being delivered. Any
+change to the <filename>new</filename> subdirectory is therefore assumed to be the result of an
+MUA moving a new message to the <filename>cur</filename> directory when it is first read. The
+time that is used is therefore the last time that the user read a new message.
+</para>
+</listitem>
+<listitem>
+<para>
+For other kinds of multi-file mailbox, the time of last access cannot be
+obtained, so a retry rule that uses this type of error field is never matched.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The quota errors apply both to system-enforced quotas and to Exim’s own quota
+mechanism in the <command>appendfile</command> transport. The <emphasis>quota</emphasis> error also applies
+when a local delivery is deferred because a partition is full (the ENOSPC
+error).
+</para>
+</section>
+<section id="SECID162">
+<title>Retry rules for specified senders</title>
+<para>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>rules; sender-specific</secondary>
+</indexterm>
+You can specify retry rules that apply only when the failing message has a
+specific sender. In particular, this can be used to define retry rules that
+apply only to bounce messages. The third item in a retry rule can be of this
+form:
+</para>
+<literallayout>
+<literal>senders=</literal><<emphasis>address list</emphasis>>
+</literallayout>
+<para>
+The retry timings themselves are then the fourth item. For example:
+</para>
+<literallayout class="monospaced">
+* rcpt_4xx senders=: F,1h,30m
+</literallayout>
+<para>
+matches recipient 4<emphasis>xx</emphasis> errors for bounce messages sent to any address at any
+host. If the address list contains white space, it must be enclosed in quotes.
+For example:
+</para>
+<literallayout class="monospaced">
+a.domain rcpt_452 senders="xb.dom : yc.dom" G,8h,10m,1.5
+</literallayout>
+<para>
+<emphasis role="bold">Warning</emphasis>: This facility can be unhelpful if it is used for host errors
+(which do not depend on the recipient). The reason is that the sender is used
+only to match the retry rule. Once the rule has been found for a host error,
+its contents are used to set a retry time for the host, and this will apply to
+all messages, not just those with specific senders.
+</para>
+<para>
+When testing retry rules using <option>-brt</option>, you can supply a sender using the
+<option>-f</option> command line option, like this:
+</para>
+<literallayout class="monospaced">
+exim -f "" -brt user@dom.ain
+</literallayout>
+<para>
+If you do not set <option>-f</option> with <option>-brt</option>, a retry rule that contains a senders
+list is never matched.
+</para>
+</section>
+<section id="SECID163">
+<title>Retry parameters</title>
+<para>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>parameters in rules</secondary>
+</indexterm>
+The third (or fourth, if a senders list is present) field in a retry rule is a
+sequence of retry parameter sets, separated by semicolons. Each set consists of
+</para>
+<literallayout>
+<<emphasis>letter</emphasis>>,<<emphasis>cutoff time</emphasis>>,<<emphasis>arguments</emphasis>>
+</literallayout>
+<para>
+The letter identifies the algorithm for computing a new retry time; the cutoff
+time is the time beyond which this algorithm no longer applies, and the
+arguments vary the algorithm’s action. The cutoff time is measured from the
+time that the first failure for the domain (combined with the local part if
+relevant) was detected, not from the time the message was received.
+</para>
+<para>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>algorithms</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>fixed intervals</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>increasing intervals</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>random intervals</secondary>
+</indexterm>
+The available algorithms are:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<emphasis>F</emphasis>: retry at fixed intervals. There is a single time parameter specifying
+the interval.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>G</emphasis>: retry at geometrically increasing intervals. The first argument
+specifies a starting value for the interval, and the second a multiplier, which
+is used to increase the size of the interval at each retry.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>H</emphasis>: retry at randomized intervals. The arguments are as for <emphasis>G</emphasis>. For each
+retry, the previous interval is multiplied by the factor in order to get a
+maximum for the next interval. The minimum interval is the first argument of
+the parameter, and an actual interval is chosen randomly between them. Such a
+rule has been found to be helpful in cluster configurations when all the
+members of the cluster restart at once, and may therefore synchronize their
+queue processing times.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+When computing the next retry time, the algorithm definitions are scanned in
+order until one whose cutoff time has not yet passed is reached. This is then
+used to compute a new retry time that is later than the current time. In the
+case of fixed interval retries, this simply means adding the interval to the
+current time. For geometrically increasing intervals, retry intervals are
+computed from the rule’s parameters until one that is greater than the previous
+interval is found. The main configuration variable
+<indexterm role="concept">
+<primary>limit</primary>
+<secondary>retry interval</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>interval, maximum</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>retry_interval_max</option></primary>
+</indexterm>
+<option>retry_interval_max</option> limits the maximum interval between retries. It
+cannot be set greater than <literal>24h</literal>, which is its default value.
+</para>
+<para>
+A single remote domain may have a number of hosts associated with it, and each
+host may have more than one IP address. Retry algorithms are selected on the
+basis of the domain name, but are applied to each IP address independently. If,
+for example, a host has two IP addresses and one is unusable, Exim will
+generate retry times for it and will not try to use it until its next retry
+time comes. Thus the good IP address is likely to be tried first most of the
+time.
+</para>
+<para>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>use for retrying</secondary>
+</indexterm>
+Retry times are hints rather than promises. Exim does not make any attempt to
+run deliveries exactly at the computed times. Instead, a queue runner process
+starts delivery processes for delayed messages periodically, and these attempt
+new deliveries only for those addresses that have passed their next retry time.
+If a new message arrives for a deferred address, an immediate delivery attempt
+occurs only if the address has passed its retry time. In the absence of new
+messages, the minimum time between retries is the interval between queue runner
+processes. There is not much point in setting retry times of five minutes if
+your queue runners happen only once an hour, unless there are a significant
+number of incoming messages (which might be the case on a system that is
+sending everything to a smart host, for example).
+</para>
+<para>
+The data in the retry hints database can be inspected by using the
+<emphasis>exim_dumpdb</emphasis> or <emphasis>exim_fixdb</emphasis> utility programs (see chapter
+<xref linkend="CHAPutils"/>). The latter utility can also be used to change the data. The
+<emphasis>exinext</emphasis> utility script can be used to find out what the next retry times
+are for the hosts associated with a particular mail domain, and also for local
+deliveries that have been deferred.
+</para>
+</section>
+<section id="SECID164">
+<title>Retry rule examples</title>
+<para>
+Here are some example retry rules:
+</para>
+<literallayout class="monospaced">
+alice@wonderland.fict.example quota_5d F,7d,3h
+wonderland.fict.example quota_5d
+wonderland.fict.example * F,1h,15m; G,2d,1h,2;
+lookingglass.fict.example * F,24h,30m;
+* refused_A F,2h,20m;
+* * F,2h,15m; G,16h,1h,1.5; F,5d,8h
+</literallayout>
+<para>
+The first rule sets up special handling for mail to
+<emphasis>alice@wonderland.fict.example</emphasis> when there is an over-quota error and the
+mailbox has not been read for at least 5 days. Retries continue every three
+hours for 7 days. The second rule handles over-quota errors for all other local
+parts at <emphasis>wonderland.fict.example</emphasis>; the absence of a local part has the same
+effect as supplying <quote>*@</quote>. As no retry algorithms are supplied, messages that
+fail are bounced immediately if the mailbox has not been read for at least 5
+days.
+</para>
+<para>
+The third rule handles all other errors at <emphasis>wonderland.fict.example</emphasis>; retries
+happen every 15 minutes for an hour, then with geometrically increasing
+intervals until two days have passed since a delivery first failed. After the
+first hour there is a delay of one hour, then two hours, then four hours, and
+so on (this is a rather extreme example).
+</para>
+<para>
+The fourth rule controls retries for the domain <emphasis>lookingglass.fict.example</emphasis>.
+They happen every 30 minutes for 24 hours only. The remaining two rules handle
+all other domains, with special action for connection refusal from hosts that
+were not obtained from an MX record.
+</para>
+<para>
+The final rule in a retry configuration should always have asterisks in the
+first two fields so as to provide a general catch-all for any addresses that do
+not have their own special handling. This example tries every 15 minutes for 2
+hours, then with intervals starting at one hour and increasing by a factor of
+1.5 up to 16 hours, then every 8 hours up to 5 days.
+</para>
+</section>
+<section id="SECID165">
+<title>Timeout of retry data</title>
+<para>
+<indexterm role="concept">
+<primary>timeout</primary>
+<secondary>of retry data</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>retry_data_expire</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>data expiry</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>timeout of data</secondary>
+</indexterm>
+Exim timestamps the data that it writes to its retry hints database. When it
+consults the data during a delivery it ignores any that is older than the value
+set in <option>retry_data_expire</option> (default 7 days). If, for example, a host hasn’t
+been tried for 7 days, Exim will try to deliver to it immediately a message
+arrives, and if that fails, it will calculate a retry time as if it were
+failing for the first time.
+</para>
+<para>
+This improves the behaviour for messages routed to rarely-used hosts such as MX
+backups. If such a host was down at one time, and happens to be down again when
+Exim tries a month later, using the old retry data would imply that it had been
+down all the time, which is not a justified assumption.
+</para>
+<para>
+If a host really is permanently dead, this behaviour causes a burst of retries
+every now and again, but only if messages routed to it are rare. If there is a
+message at least once every 7 days the retry data never expires.
+</para>
+</section>
+<section id="SECID166">
+<title>Long-term failures</title>
+<para>
+<indexterm role="concept">
+<primary>delivery failure, long-term</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>after long-term failure</secondary>
+</indexterm>
+Special processing happens when an email address has been failing for so long
+that the cutoff time for the last algorithm is reached. For example, using the
+default retry rule:
+</para>
+<literallayout class="monospaced">
+* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
+</literallayout>
+<para>
+the cutoff time is four days. Reaching the retry cutoff is independent of how
+long any specific message has been failing; it is the length of continuous
+failure for the recipient address that counts.
+</para>
+<para>
+When the cutoff time is reached for a local delivery, or for all the IP
+addresses associated with a remote delivery, a subsequent delivery failure
+causes Exim to give up on the address, and a bounce message is generated.
+In order to cater for new messages that use the failing address, a next retry
+time is still computed from the final algorithm, and is used as follows:
+</para>
+<para>
+For local deliveries, one delivery attempt is always made for any subsequent
+messages. If this delivery fails, the address fails immediately. The
+post-cutoff retry time is not used.
+</para>
+<para>
+<indexterm role="concept">
+<primary>final cutoff</primary>
+<secondary>retries, controlling</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>final cutoff</secondary>
+</indexterm>
+If the delivery is remote, there are two possibilities, controlled by the
+<indexterm role="option">
+<primary><option>delay_after_cutoff</option></primary>
+</indexterm>
+<option>delay_after_cutoff</option> option of the <command>smtp</command> transport. The option is true by
+default. Until the post-cutoff retry time for one of the IP addresses,
+as set by the <option>retry_data_expire</option> option, is
+reached, the failing email address is bounced immediately, without a delivery
+attempt taking place. After that time, one new delivery attempt is made to
+those IP addresses that are past their retry times, and if that still fails,
+the address is bounced and new retry times are computed.
+</para>
+<para>
+In other words, when all the hosts for a given email address have been failing
+for a long time, Exim bounces rather then defers until one of the hosts’ retry
+times is reached. Then it tries once, and bounces if that attempt fails. This
+behaviour ensures that few resources are wasted in repeatedly trying to deliver
+to a broken destination, but if the host does recover, Exim will eventually
+notice.
+</para>
+<para>
+If <option>delay_after_cutoff</option> is set false, Exim behaves differently. If all IP
+addresses are past their final cutoff time, Exim tries to deliver to those IP
+addresses that have not been tried since the message arrived. If there are
+no suitable IP addresses, or if they all fail, the address is bounced. In other
+words, it does not delay when a new message arrives, but tries the expired
+addresses immediately, unless they have been tried since the message arrived.
+If there is a continuous stream of messages for the failing domains, setting
+<option>delay_after_cutoff</option> false means that there will be many more attempts to
+deliver to permanently failing IP addresses than when <option>delay_after_cutoff</option> is
+true.
+</para>
+</section>
+<section id="SECID167">
+<title>Deliveries that work intermittently</title>
+<para>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>intermittently working deliveries</secondary>
+</indexterm>
+Some additional logic is needed to cope with cases where a host is
+intermittently available, or when a message has some attribute that prevents
+its delivery when others to the same address get through. In this situation,
+because some messages are successfully delivered, the <quote>retry clock</quote> for the
+host or address keeps getting reset by the successful deliveries, and so
+failing messages remain in the queue for ever because the cutoff time is never
+reached.
+</para>
+<para>
+Two exceptional actions are applied to prevent this happening. The first
+applies to errors that are related to a message rather than a remote host.
+Section <xref linkend="SECToutSMTPerr"/> has a discussion of the different kinds of error;
+examples of message-related errors are 4<emphasis>xx</emphasis> responses to MAIL or DATA
+commands, and quota failures. For this type of error, if a message’s arrival
+time is earlier than the <quote>first failed</quote> time for the error, the earlier time
+is used when scanning the retry rules to decide when to try next and when to
+time out the address.
+</para>
+<para>
+The exceptional second action applies in all cases. If a message has been on
+the queue for longer than the cutoff time of any applicable retry rule for a
+given address, a delivery is attempted for that address, even if it is not yet
+time, and if this delivery fails, the address is timed out. A new retry time is
+not computed in this case, so that other messages for the same address are
+considered immediately.
+<indexterm role="concept" startref="IIDretconf1" class="endofrange"/>
+<indexterm role="concept" startref="IIDregconf2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPSMTPAUTH">
+<title>SMTP authentication</title>
+<para>
+<indexterm role="concept" id="IIDauthconf1" class="startofrange">
+<primary>SMTP</primary>
+<secondary>authentication configuration</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDauthconf2" class="startofrange">
+<primary>authentication</primary>
+</indexterm>
+The <quote>authenticators</quote> section of Exim’s runtime configuration is concerned
+with SMTP authentication. This facility is an extension to the SMTP protocol,
+described in RFC 2554, which allows a client SMTP host to authenticate itself
+to a server. This is a common way for a server to recognize clients that are
+permitted to use it as a relay. SMTP authentication is not of relevance to the
+transfer of mail between servers that have no managerial connection with each
+other.
+</para>
+<para>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>description of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>AUTH</secondary>
+</indexterm>
+Very briefly, the way SMTP authentication works is as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The server advertises a number of authentication <emphasis>mechanisms</emphasis> in response to
+the client’s EHLO command.
+</para>
+</listitem>
+<listitem>
+<para>
+The client issues an AUTH command, naming a specific mechanism. The command
+may, optionally, contain some authentication data.
+</para>
+</listitem>
+<listitem>
+<para>
+The server may issue one or more <emphasis>challenges</emphasis>, to which the client must send
+appropriate responses. In simple authentication mechanisms, the challenges are
+just prompts for user names and passwords. The server does not have to issue
+any challenges – in some mechanisms the relevant data may all be transmitted
+with the AUTH command.
+</para>
+</listitem>
+<listitem>
+<para>
+The server either accepts or denies authentication.
+</para>
+</listitem>
+<listitem>
+<para>
+If authentication succeeds, the client may optionally make use of the AUTH
+option on the MAIL command to pass an authenticated sender in subsequent
+mail transactions. Authentication lasts for the remainder of the SMTP
+connection.
+</para>
+</listitem>
+<listitem>
+<para>
+If authentication fails, the client may give up, or it may try a different
+authentication mechanism, or it may try transferring mail over the
+unauthenticated connection.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+If you are setting up a client, and want to know which authentication
+mechanisms the server supports, you can use Telnet to connect to port 25 (the
+SMTP port) on the server, and issue an EHLO command. The response to this
+includes the list of supported mechanisms. For example:
+</para>
+<literallayout>
+<literal>$ </literal><emphasis role="bold"><literal>telnet server.example 25</literal></emphasis>
+<literal>Trying 192.168.34.25...</literal>
+<literal>Connected to server.example.</literal>
+<literal>Escape character is '^]'.</literal>
+<literal>220 server.example ESMTP Exim 4.20 ...</literal>
+<emphasis role="bold"><literal>ehlo client.example</literal></emphasis>
+<literal>250-server.example Hello client.example [10.8.4.5]</literal>
+<literal>250-SIZE 52428800</literal>
+<literal>250-PIPELINING</literal>
+<literal>250-AUTH PLAIN</literal>
+<literal>250 HELP</literal>
+</literallayout>
+<para>
+The second-last line of this example output shows that the server supports
+authentication using the PLAIN mechanism. In Exim, the different authentication
+mechanisms are configured by specifying <emphasis>authenticator</emphasis> drivers. Like the
+routers and transports, which authenticators are included in the binary is
+controlled by build-time definitions. The following are currently available,
+included by setting
+</para>
+<literallayout class="monospaced">
+AUTH_CRAM_MD5=yes
+AUTH_CYRUS_SASL=yes
+AUTH_DOVECOT=yes
+AUTH_EXTERNAL=yes
+AUTH_GSASL=yes
+AUTH_HEIMDAL_GSSAPI=yes
+AUTH_PLAINTEXT=yes
+AUTH_SPA=yes
+AUTH_TLS=yes
+</literallayout>
+<para>
+in <filename>Local/Makefile</filename>, respectively. The first of these supports the CRAM-MD5
+authentication mechanism (RFC 2195), and the second provides an interface to
+the Cyrus SASL authentication library.
+The third is an interface to Dovecot’s authentication system, delegating the
+work via a socket interface.
+The fourth provides for negotiation of authentication done via non-SMTP means,
+as defined by RFC 4422 Appendix A.
+The fifth provides an interface to the GNU SASL authentication library, which
+provides mechanisms but typically not data sources.
+The sixth provides direct access to Heimdal GSSAPI, geared for Kerberos, but
+supporting setting a server keytab.
+The seventh can be configured to support
+the PLAIN authentication mechanism (RFC 2595) or the LOGIN mechanism, which is
+not formally documented, but used by several MUAs.
+The eighth authenticator
+supports Microsoft’s <emphasis>Secure Password Authentication</emphasis> mechanism.
+The last is an Exim authenticator but not an SMTP one;
+instead it can use information from a TLS negotiation.
+</para>
+<para>
+The authenticators are configured using the same syntax as other drivers (see
+section <xref linkend="SECTfordricon"/>). If no authenticators are required, no
+authentication section need be present in the configuration file. Each
+authenticator can in principle have both server and client functions. When Exim
+is receiving SMTP mail, it is acting as a server; when it is sending out
+messages over SMTP, it is acting as a client. Authenticator configuration
+options are provided for use in both these circumstances.
+</para>
+<para>
+To make it clear which options apply to which situation, the prefixes
+<option>server_</option> and <option>client_</option> are used on option names that are specific to
+either the server or the client function, respectively. Server and client
+functions are disabled if none of their options are set. If an authenticator is
+to be used for both server and client functions, a single definition, using
+both sets of options, is required. For example:
+</para>
+<literallayout class="monospaced">
+cram:
+ driver = cram_md5
+ public_name = CRAM-MD5
+ server_secret = ${if eq{$auth1}{ph10}{secret1}fail}
+ client_name = ph10
+ client_secret = secret2
+</literallayout>
+<para>
+The <option>server_</option> option is used when Exim is acting as a server, and the
+<option>client_</option> options when it is acting as a client.
+</para>
+<para>
+Descriptions of the individual authenticators are given in subsequent chapters.
+The remainder of this chapter covers the generic options for the
+authenticators, followed by general discussion of the way authentication works
+in Exim.
+</para>
+<para>
+<emphasis role="bold">Beware:</emphasis> the meaning of <varname>$auth1</varname>, <varname>$auth2</varname>, ... varies on a per-driver and
+per-mechanism basis. Please read carefully to determine which variables hold
+account labels such as usercodes and which hold passwords or other
+authenticating data.
+</para>
+<para>
+Note that some mechanisms support two different identifiers for accounts: the
+<emphasis>authentication id</emphasis> and the <emphasis>authorization id</emphasis>. The contractions <emphasis>authn</emphasis>
+and <emphasis>authz</emphasis> are commonly encountered. The American spelling is standard here.
+Conceptually, authentication data such as passwords are tied to the identifier
+used to authenticate; servers may have rules to permit one user to act as a
+second user, so that after login the session is treated as though that second
+user had logged in. That second user is the <emphasis>authorization id</emphasis>. A robust
+configuration might confirm that the <emphasis>authz</emphasis> field is empty or matches the
+<emphasis>authn</emphasis> field. Often this is just ignored. The <emphasis>authn</emphasis> can be considered
+as verified data, the <emphasis>authz</emphasis> as an unverified request which the server might
+choose to honour.
+</para>
+<para>
+A <emphasis>realm</emphasis> is a text string, typically a domain name, presented by a server
+to a client to help it select an account and credentials to use. In some
+mechanisms, the client and server provably agree on the realm, but clients
+typically can not treat the realm as secure data to be blindly trusted.
+</para>
+<section id="SECID168">
+<title>Generic options for authenticators</title>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>generic options</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary>generic; for authenticators</secondary>
+</indexterm>
+</para>
+<para>
+<indexterm role="option">
+<primary><option>client_condition</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_condition</option></entry>
+<entry>Use: <emphasis>authenticators</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+When Exim is authenticating as a client, it skips any authenticator whose
+<option>client_condition</option> expansion yields <quote>0</quote>, <quote>no</quote>, or <quote>false</quote>. This can be
+used, for example, to skip plain text authenticators when the connection is not
+encrypted by a setting such as:
+</para>
+<literallayout class="monospaced">
+client_condition = ${if !eq{$tls_out_cipher}{}}
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>client_set_id</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_set_id</option></entry>
+<entry>Use: <emphasis>authenticators</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+When client authentication succeeds, this condition is expanded; the
+result is used in the log lines for outbound messages.
+Typically it will be the user name used for authentication.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>driver</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>driver</option></entry>
+<entry>Use: <emphasis>authenticators</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option must always be set. It specifies which of the available
+authenticators is to be used.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>public_name</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>public_name</option></entry>
+<entry>Use: <emphasis>authenticators</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies the name of the authentication mechanism that the driver
+implements, and by which it is known to the outside world. These names should
+contain only upper case letters, digits, underscores, and hyphens (RFC 2222),
+but Exim in fact matches them caselessly. If <option>public_name</option> is not set, it
+defaults to the driver’s instance name.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_advertise_condition</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_advertise_condition</option></entry>
+<entry>Use: <emphasis>authenticators</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+When a server is about to advertise an authentication mechanism, the condition
+is expanded. If it yields the empty string, <quote>0</quote>, <quote>no</quote>, or <quote>false</quote>, the
+mechanism is not advertised.
+If the expansion fails, the mechanism is not advertised. If the failure was not
+forced, and was not caused by a lookup defer, the incident is logged.
+See section <xref linkend="SECTauthexiser"/> below for further discussion.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_condition</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_condition</option></entry>
+<entry>Use: <emphasis>authenticators</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option must be set for a <option>plaintext</option> server authenticator, where it
+is used directly to control authentication. See section <xref linkend="SECTplainserver"/>
+for details.
+</para>
+<para>
+For the <command>gsasl</command> authenticator, this option is required for various
+mechanisms; see chapter <xref linkend="CHAPgsasl"/> for details.
+</para>
+<para>
+For the other authenticators, <option>server_condition</option> can be used as an additional
+authentication or authorization mechanism that is applied after the other
+authenticator conditions succeed. If it is set, it is expanded when the
+authenticator would otherwise return a success code. If the expansion is forced
+to fail, authentication fails. Any other expansion failure causes a temporary
+error code to be returned. If the result of a successful expansion is an empty
+string, <quote>0</quote>, <quote>no</quote>, or <quote>false</quote>, authentication fails. If the result of the
+expansion is <quote>1</quote>, <quote>yes</quote>, or <quote>true</quote>, authentication succeeds. For any
+other result, a temporary error code is returned, with the expanded string as
+the error text.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_debug_print</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_debug_print</option></entry>
+<entry>Use: <emphasis>authenticators</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If this option is set and authentication debugging is enabled (see the <option>-d</option>
+command line option), the string is expanded and included in the debugging
+output when the authenticator is run as a server. This can help with checking
+out the values of variables.
+If expansion of the string fails, the error message is written to the debugging
+output, and Exim carries on processing.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_set_id</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_set_id</option></entry>
+<entry>Use: <emphasis>authenticators</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="variable">
+<primary><varname>$authenticated_id</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$authenticated_fail_id</varname></primary>
+</indexterm>
+When an Exim server successfully authenticates a client, this string is
+expanded using data from the authentication, and preserved for any incoming
+messages in the variable <varname>$authenticated_id</varname>. It is also included in the log
+lines for incoming messages. For example, a user/password authenticator
+configuration might preserve the user name that was used to authenticate, and
+refer to it subsequently during delivery of the message.
+On a failing authentication the expansion result is instead saved in
+the <varname>$authenticated_fail_id</varname> variable.
+If expansion fails, the option is ignored.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_mail_auth_condition</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_mail_auth_condition</option></entry>
+<entry>Use: <emphasis>authenticators</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option allows a server to discard authenticated sender addresses supplied
+as part of MAIL commands in SMTP connections that are authenticated by the
+driver on which <option>server_mail_auth_condition</option> is set. The option is not used
+as part of the authentication process; instead its (unexpanded) value is
+remembered for later use.
+How it is used is described in the following section.
+</para>
+</section>
+<section id="SECTauthparamail">
+<title>The AUTH parameter on MAIL commands</title>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>sender; authenticated</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>on MAIL command</secondary>
+</indexterm>
+When a client supplied an AUTH= item on a MAIL command, Exim applies
+the following checks before accepting it as the authenticated sender of the
+message:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If the connection is not using extended SMTP (that is, HELO was used rather
+than EHLO), the use of AUTH= is a syntax error.
+</para>
+</listitem>
+<listitem>
+<para>
+If the value of the AUTH= parameter is <quote><></quote>, it is ignored.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$authenticated_sender</varname></primary>
+</indexterm>
+If <option>acl_smtp_mailauth</option> is defined, the ACL it specifies is run. While it is
+running, the value of <varname>$authenticated_sender</varname> is set to the value obtained
+from the AUTH= parameter. If the ACL does not yield <quote>accept</quote>, the value of
+<varname>$authenticated_sender</varname> is deleted. The <option>acl_smtp_mailauth</option> ACL may not
+return <quote>drop</quote> or <quote>discard</quote>. If it defers, a temporary error code (451) is
+given for the MAIL command.
+</para>
+</listitem>
+<listitem>
+<para>
+If <option>acl_smtp_mailauth</option> is not defined, the value of the AUTH= parameter
+is accepted and placed in <varname>$authenticated_sender</varname> only if the client has
+authenticated.
+</para>
+</listitem>
+<listitem>
+<para>
+If the AUTH= value was accepted by either of the two previous rules, and
+the client has authenticated, and the authenticator has a setting for the
+<option>server_mail_auth_condition</option>, the condition is checked at this point. The
+valued that was saved from the authenticator is expanded. If the expansion
+fails, or yields an empty string, <quote>0</quote>, <quote>no</quote>, or <quote>false</quote>, the value of
+<varname>$authenticated_sender</varname> is deleted. If the expansion yields any other value,
+the value of <varname>$authenticated_sender</varname> is retained and passed on with the
+message.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+When <varname>$authenticated_sender</varname> is set for a message, it is passed on to other
+hosts to which Exim authenticates as a client. Do not confuse this value with
+<varname>$authenticated_id</varname>, which is a string obtained from the authentication
+process, and which is not usually a complete email address.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_address</varname></primary>
+</indexterm>
+Whenever an AUTH= value is ignored, the incident is logged. The ACL for
+MAIL, if defined, is run after AUTH= is accepted or ignored. It can
+therefore make use of <varname>$authenticated_sender</varname>. The converse is not true: the
+value of <varname>$sender_address</varname> is not yet set up when the <option>acl_smtp_mailauth</option>
+ACL is run.
+</para>
+</section>
+<section id="SECTauthexiser">
+<title>Authentication on an Exim server</title>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>on an Exim server</secondary>
+</indexterm>
+When Exim receives an EHLO command, it advertises the public names of those
+authenticators that are configured as servers, subject to the following
+conditions:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The client host must match <option>auth_advertise_hosts</option> (default *).
+</para>
+</listitem>
+<listitem>
+<para>
+It the <option>server_advertise_condition</option> option is set, its expansion must not
+yield the empty string, <quote>0</quote>, <quote>no</quote>, or <quote>false</quote>.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The order in which the authenticators are defined controls the order in which
+the mechanisms are advertised.
+</para>
+<para>
+Some mail clients (for example, some versions of Netscape) require the user to
+provide a name and password for authentication whenever AUTH is advertised,
+even though authentication may not in fact be needed (for example, Exim may be
+set up to allow unconditional relaying from the client by an IP address check).
+You can make such clients more friendly by not advertising AUTH to them.
+For example, if clients on the 10.9.8.0/24 network are permitted (by the ACL
+that runs for RCPT) to relay without authentication, you should set
+</para>
+<literallayout class="monospaced">
+auth_advertise_hosts = ! 10.9.8.0/24
+</literallayout>
+<para>
+so that no authentication mechanisms are advertised to them.
+</para>
+<para>
+The <option>server_advertise_condition</option> controls the advertisement of individual
+authentication mechanisms. For example, it can be used to restrict the
+advertisement of a particular mechanism to encrypted connections, by a setting
+such as:
+</para>
+<literallayout class="monospaced">
+server_advertise_condition = ${if eq{$tls_in_cipher}{}{no}{yes}}
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_cipher</varname></primary>
+</indexterm>
+If the session is encrypted, <varname>$tls_in_cipher</varname> is not empty, and so the expansion
+yields <quote>yes</quote>, which allows the advertisement to happen.
+</para>
+<para>
+When an Exim server receives an AUTH command from a client, it rejects it
+immediately if AUTH was not advertised in response to an earlier EHLO
+command. This is the case if
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The client host does not match <option>auth_advertise_hosts</option>; or
+</para>
+</listitem>
+<listitem>
+<para>
+No authenticators are configured with server options; or
+</para>
+</listitem>
+<listitem>
+<para>
+Expansion of <option>server_advertise_condition</option> blocked the advertising of all the
+server authenticators.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Otherwise, Exim runs the ACL specified by <option>acl_smtp_auth</option> in order
+to decide whether to accept the command. If <option>acl_smtp_auth</option> is not set,
+AUTH is accepted from any client host.
+</para>
+<para>
+If AUTH is not rejected by the ACL, Exim searches its configuration for a
+server authentication mechanism that was advertised in response to EHLO and
+that matches the one named in the AUTH command. If it finds one, it runs
+the appropriate authentication protocol, and authentication either succeeds or
+fails. If there is no matching advertised mechanism, the AUTH command is
+rejected with a 504 error.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$received_protocol</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$sender_host_authenticated</varname></primary>
+</indexterm>
+When a message is received from an authenticated host, the value of
+<varname>$received_protocol</varname> is set to <quote>esmtpa</quote> or <quote>esmtpsa</quote> instead of <quote>esmtp</quote>
+or <quote>esmtps</quote>, and <varname>$sender_host_authenticated</varname> contains the name (not the
+public name) of the authenticator driver that successfully authenticated the
+client from which the message was received. This variable is empty if there was
+no successful authentication.
+</para>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>expansion item</secondary>
+</indexterm>
+Successful authentication sets up information used by the
+<option>authresults</option> expansion item.
+</para>
+</section>
+<section id="SECID169">
+<title>Testing server authentication</title>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>testing a server</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>testing a server</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>base64 encoding</primary>
+<secondary>creating authentication test data</secondary>
+</indexterm>
+Exim’s <option>-bh</option> option can be useful for testing server authentication
+configurations. The data for the AUTH command has to be sent using base64
+encoding. A quick way to produce such data for testing is the following Perl
+script:
+</para>
+<literallayout class="monospaced">
+use MIME::Base64;
+printf ("%s", encode_base64(eval "\"$ARGV[0]\""));
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>binary zero</primary>
+<secondary>in authentication data</secondary>
+</indexterm>
+This interprets its argument as a Perl string, and then encodes it. The
+interpretation as a Perl string allows binary zeros, which are required for
+some kinds of authentication, to be included in the data. For example, a
+command line to run this script on such data might be
+</para>
+<literallayout class="monospaced">
+encode '\0user\0password'
+</literallayout>
+<para>
+Note the use of single quotes to prevent the shell interpreting the
+backslashes, so that they can be interpreted by Perl to specify characters
+whose code value is zero.
+</para>
+<para>
+<emphasis role="bold">Warning 1</emphasis>: If either of the user or password strings starts with an octal
+digit, you must use three zeros instead of one after the leading backslash. If
+you do not, the octal digit that starts your string will be incorrectly
+interpreted as part of the code for the first character.
+</para>
+<para>
+<emphasis role="bold">Warning 2</emphasis>: If there are characters in the strings that Perl interprets
+specially, you must use a Perl escape to prevent them being misinterpreted. For
+example, a command such as
+</para>
+<literallayout class="monospaced">
+encode '\0user@domain.com\0pas$$word'
+</literallayout>
+<para>
+gives an incorrect answer because of the unescaped <quote>@</quote> and <quote>$</quote> characters.
+</para>
+<para>
+If you have the <option>mimencode</option> command installed, another way to do produce
+base64-encoded strings is to run the command
+</para>
+<literallayout class="monospaced">
+echo -e -n `\0user\0password' | mimencode
+</literallayout>
+<para>
+The <option>-e</option> option of <option>echo</option> enables the interpretation of backslash escapes
+in the argument, and the <option>-n</option> option specifies no newline at the end of its
+output. However, not all versions of <option>echo</option> recognize these options, so you
+should check your version before relying on this suggestion.
+</para>
+</section>
+<section id="SECID170">
+<title>Authentication by an Exim client</title>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>on an Exim client</secondary>
+</indexterm>
+The <command>smtp</command> transport has two options called <option>hosts_require_auth</option> and
+<option>hosts_try_auth</option>. When the <command>smtp</command> transport connects to a server that
+announces support for authentication, and the host matches an entry in either
+of these options, Exim (as a client) tries to authenticate as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+For each authenticator that is configured as a client, in the order in which
+they are defined in the configuration, it searches the authentication
+mechanisms announced by the server for one whose name matches the public name
+of the authenticator.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host_address</varname></primary>
+</indexterm>
+When it finds one that matches, it runs the authenticator’s client code. The
+variables <varname>$host</varname> and <varname>$host_address</varname> are available for any string expansions
+that the client might do. They are set to the server’s name and IP address. If
+any expansion is forced to fail, the authentication attempt is abandoned, and
+Exim moves on to the next authenticator. Otherwise an expansion failure causes
+delivery to be deferred.
+</para>
+</listitem>
+<listitem>
+<para>
+If the result of the authentication attempt is a temporary error or a timeout,
+Exim abandons trying to send the message to the host for the moment. It will
+try again later. If there are any backup hosts available, they are tried in the
+usual way.
+</para>
+</listitem>
+<listitem>
+<para>
+If the response to authentication is a permanent error (5<emphasis>xx</emphasis> code), Exim
+carries on searching the list of authenticators and tries another one if
+possible. If all authentication attempts give permanent errors, or if there are
+no attempts because no mechanisms match (or option expansions force failure),
+what happens depends on whether the host matches <option>hosts_require_auth</option> or
+<option>hosts_try_auth</option>. In the first case, a temporary error is generated, and
+delivery is deferred. The error can be detected in the retry rules, and thereby
+turned into a permanent error if you wish. In the second case, Exim tries to
+deliver the message unauthenticated.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Note that the hostlist test for whether to do authentication can be
+confused if name-IP lookups change between the time the peer is decided
+upon and the time that the transport runs. For example, with a manualroute
+router given a host name, and with DNS "round-robin" used by that name: if
+the local resolver cache times out between the router and the transport
+running, the transport may get an IP for the name for its authentication
+check which does not match the connection peer IP.
+No authentication will then be done, despite the names being identical.
+</para>
+<para>
+For such cases use a separate transport which always authenticates.
+</para>
+<para>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>on MAIL command</secondary>
+</indexterm>
+When Exim has authenticated itself to a remote server, it adds the AUTH
+parameter to the MAIL commands it sends, if it has an authenticated sender for
+the message. If the message came from a remote host, the authenticated sender
+is the one that was receiving on an incoming MAIL command, provided that the
+incoming connection was authenticated and the <option>server_mail_auth</option> condition
+allowed the authenticated sender to be retained. If a local process calls Exim
+to send a message, the sender address that is built from the login name and
+<option>qualify_domain</option> is treated as authenticated. However, if the
+<option>authenticated_sender</option> option is set on the <command>smtp</command> transport, it overrides
+the authenticated sender that was received with the message.
+<indexterm role="concept" startref="IIDauthconf1" class="endofrange"/>
+<indexterm role="concept" startref="IIDauthconf2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPplaintext">
+<title>The plaintext authenticator</title>
+<para>
+<indexterm role="concept" id="IIDplaiauth1" class="startofrange">
+<primary><command>plaintext</command> authenticator</primary>
+</indexterm>
+<indexterm role="concept" id="IIDplaiauth2" class="startofrange">
+<primary>authenticators</primary>
+<secondary><command>plaintext</command></secondary>
+</indexterm>
+The <command>plaintext</command> authenticator can be configured to support the PLAIN and
+LOGIN authentication mechanisms, both of which transfer authentication data as
+plain (unencrypted) text (though base64 encoded). The use of plain text is a
+security risk; you are strongly advised to insist on the use of SMTP encryption
+(see chapter <xref linkend="CHAPTLS"/>) if you use the PLAIN or LOGIN mechanisms. If you do
+use unencrypted plain text, you should not use the same passwords for SMTP
+connections as you do for login accounts.
+</para>
+<section id="SECTplain_TLS">
+<title>Avoiding cleartext use</title>
+<para>
+The following generic option settings will disable <command>plaintext</command> authenticators when
+TLS is not being used:
+</para>
+<literallayout class="monospaced">
+ server_advertise_condition = ${if def:tls_in_cipher }
+ client_condition = ${if def:tls_out_cipher}
+</literallayout>
+<para>
+<emphasis role="bold">Note</emphasis>: a plaintext SMTP AUTH done inside TLS is not vulnerable to casual snooping,
+but is still vulnerable to a Man In The Middle attack unless certificates
+(including their names) have been properly verified.
+</para>
+</section>
+<section id="SECID171">
+<title>Plaintext server options</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>plaintext</command> authenticator (server)</secondary>
+</indexterm>
+When configured as a server, <command>plaintext</command> uses the following options:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_condition</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_condition</option></entry>
+<entry>Use: <emphasis>authenticators</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This is actually a global authentication option, but it must be set in order to
+configure the <command>plaintext</command> driver as a server. Its use is described below.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_prompts</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_prompts</option></entry>
+<entry>Use: <emphasis>plaintext</emphasis></entry>
+<entry>Type: <emphasis>string list</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+The contents of this option, after expansion, must be a colon-separated list of
+prompt strings. If expansion fails, a temporary authentication rejection is
+given.
+</para>
+</section>
+<section id="SECTplainserver">
+<title>Using plaintext in a server</title>
+<para>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>in <command>plaintext</command> authenticator</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>binary zero</primary>
+<secondary>in <command>plaintext</command> authenticator</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>numerical variables (<varname>$1</varname> <varname>$2</varname> etc)</primary>
+<secondary>in <command>plaintext</command> authenticator</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$auth1</varname>, <varname>$auth2</varname>, etc</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>base64 encoding</primary>
+<secondary>in <command>plaintext</command> authenticator</secondary>
+</indexterm>
+</para>
+<para>
+When running as a server, <command>plaintext</command> performs the authentication test by
+expanding a string. The data sent by the client with the AUTH command, or in
+response to subsequent prompts, is base64 encoded, and so may contain any byte
+values when decoded. If any data is supplied with the command, it is treated as
+a list of strings, separated by NULs (binary zeros), the first three of which
+are placed in the expansion variables <varname>$auth1</varname>, <varname>$auth2</varname>, and <varname>$auth3</varname>
+(neither LOGIN nor PLAIN uses more than three strings).
+</para>
+<para>
+For compatibility with previous releases of Exim, the values are also placed in
+the expansion variables <varname>$1</varname>, <varname>$2</varname>, and <varname>$3</varname>. However, the use of these
+variables for this purpose is now deprecated, as it can lead to confusion in
+string expansions that also use them for other things.
+</para>
+<para>
+If there are more strings in <option>server_prompts</option> than the number of strings
+supplied with the AUTH command, the remaining prompts are used to obtain more
+data. Each response from the client may be a list of NUL-separated strings.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$authenticated_id</varname></primary>
+</indexterm>
+Once a sufficient number of data strings have been received,
+<option>server_condition</option> is expanded. If the expansion is forced to fail,
+authentication fails. Any other expansion failure causes a temporary error code
+to be returned. If the result of a successful expansion is an empty string,
+<quote>0</quote>, <quote>no</quote>, or <quote>false</quote>, authentication fails. If the result of the
+expansion is <quote>1</quote>, <quote>yes</quote>, or <quote>true</quote>, authentication succeeds and the
+generic <option>server_set_id</option> option is expanded and saved in <varname>$authenticated_id</varname>.
+For any other result, a temporary error code is returned, with the expanded
+string as the error text.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: If you use a lookup in the expansion to find the user’s
+password, be sure to make the authentication fail if the user is unknown.
+There are good and bad examples at the end of the next section.
+</para>
+</section>
+<section id="SECID172">
+<title>The PLAIN authentication mechanism</title>
+<para>
+<indexterm role="concept">
+<primary>PLAIN authentication mechanism</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>PLAIN</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>binary zero</primary>
+<secondary>in <command>plaintext</command> authenticator</secondary>
+</indexterm>
+The PLAIN authentication mechanism (RFC 2595) specifies that three strings be
+sent as one item of data (that is, one combined string containing two NUL
+separators). The data is sent either as part of the AUTH command, or
+subsequently in response to an empty prompt from the server.
+</para>
+<para>
+The second and third strings are a user name and a corresponding password.
+Using a single fixed user name and password as an example, this could be
+configured as follows:
+</para>
+<literallayout class="monospaced">
+fixed_plain:
+ driver = plaintext
+ public_name = PLAIN
+ server_prompts = :
+ server_condition = \
+ ${if and {{eq{$auth2}{username}}{eq{$auth3}{mysecret}}}}
+ server_set_id = $auth2
+</literallayout>
+<para>
+Note that the default result strings from <option>if</option> (<quote>true</quote> or an empty string)
+are exactly what we want here, so they need not be specified. Obviously, if the
+password contains expansion-significant characters such as dollar, backslash,
+or closing brace, they have to be escaped.
+</para>
+<para>
+The <option>server_prompts</option> setting specifies a single, empty prompt (empty items at
+the end of a string list are ignored). If all the data comes as part of the
+AUTH command, as is commonly the case, the prompt is not used. This
+authenticator is advertised in the response to EHLO as
+</para>
+<literallayout class="monospaced">
+250-AUTH PLAIN
+</literallayout>
+<para>
+and a client host can authenticate itself by sending the command
+</para>
+<literallayout class="monospaced">
+AUTH PLAIN AHVzZXJuYW1lAG15c2VjcmV0
+</literallayout>
+<para>
+As this contains three strings (more than the number of prompts), no further
+data is required from the client. Alternatively, the client may just send
+</para>
+<literallayout class="monospaced">
+AUTH PLAIN
+</literallayout>
+<para>
+to initiate authentication, in which case the server replies with an empty
+prompt. The client must respond with the combined data string.
+</para>
+<para>
+The data string is base64 encoded, as required by the RFC. This example,
+when decoded, is <<emphasis>NUL</emphasis>><literal>username</literal><<emphasis>NUL</emphasis>><literal>mysecret</literal>, where <<emphasis>NUL</emphasis>>
+represents a zero byte. This is split up into three strings, the first of which
+is empty. The <option>server_condition</option> option in the authenticator checks that the
+second two are <literal>username</literal> and <literal>mysecret</literal> respectively.
+</para>
+<para>
+Having just one fixed user name and password, as in this example, is not very
+realistic, though for a small organization with only a handful of
+authenticating clients it could make sense.
+</para>
+<para>
+A more sophisticated instance of this authenticator could use the user name in
+<varname>$auth2</varname> to look up a password in a file or database, and maybe do an encrypted
+comparison (see <option>crypteq</option> in chapter <xref linkend="CHAPexpand"/>). Here is a example of
+this approach, where the passwords are looked up in a DBM file. <emphasis role="bold">Warning</emphasis>:
+This is an incorrect example:
+</para>
+<literallayout class="monospaced">
+server_condition = \
+ ${if eq{$auth3}{${lookup{$auth2}dbm{/etc/authpwd}}}}
+</literallayout>
+<para>
+The expansion uses the user name (<varname>$auth2</varname>) as the key to look up a password,
+which it then compares to the supplied password (<varname>$auth3</varname>). Why is this example
+incorrect? It works fine for existing users, but consider what happens if a
+non-existent user name is given. The lookup fails, but as no success/failure
+strings are given for the lookup, it yields an empty string. Thus, to defeat
+the authentication, all a client has to do is to supply a non-existent user
+name and an empty password. The correct way of writing this test is:
+</para>
+<literallayout class="monospaced">
+server_condition = ${lookup{$auth2}dbm{/etc/authpwd}\
+ {${if eq{$value}{$auth3}}} {false}}
+</literallayout>
+<para>
+In this case, if the lookup succeeds, the result is checked; if the lookup
+fails, <quote>false</quote> is returned and authentication fails. If <option>crypteq</option> is being
+used instead of <option>eq</option>, the first example is in fact safe, because <option>crypteq</option>
+always fails if its second argument is empty. However, the second way of
+writing the test makes the logic clearer.
+</para>
+</section>
+<section id="SECID173">
+<title>The LOGIN authentication mechanism</title>
+<para>
+<indexterm role="concept">
+<primary>LOGIN authentication mechanism</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>LOGIN</secondary>
+</indexterm>
+The LOGIN authentication mechanism is not documented in any RFC, but is in use
+in a number of programs. No data is sent with the AUTH command. Instead, a
+user name and password are supplied separately, in response to prompts. The
+plaintext authenticator can be configured to support this as in this example:
+</para>
+<literallayout class="monospaced">
+fixed_login:
+ driver = plaintext
+ public_name = LOGIN
+ server_prompts = User Name : Password
+ server_condition = \
+ ${if and {{eq{$auth1}{username}}{eq{$auth2}{mysecret}}}}
+ server_set_id = $auth1
+</literallayout>
+<para>
+Because of the way plaintext operates, this authenticator accepts data supplied
+with the AUTH command (in contravention of the specification of LOGIN), but
+if the client does not supply it (as is the case for LOGIN clients), the prompt
+strings are used to obtain two data items.
+</para>
+<para>
+Some clients are very particular about the precise text of the prompts. For
+example, Outlook Express is reported to recognize only <quote>Username:</quote> and
+<quote>Password:</quote>. Here is an example of a LOGIN authenticator that uses those
+strings. It uses the <option>ldapauth</option> expansion condition to check the user
+name and password by binding to an LDAP server:
+</para>
+<literallayout class="monospaced">
+login:
+ driver = plaintext
+ public_name = LOGIN
+ server_prompts = Username:: : Password::
+ server_condition = ${if and{{ \
+ !eq{}{$auth1} }{ \
+ ldapauth{\
+ user="uid=${quote_ldap_dn:$auth1},ou=people,o=example.org" \
+ pass=${quote:$auth2} \
+ ldap://ldap.example.org/} }} }
+ server_set_id = uid=$auth1,ou=people,o=example.org
+</literallayout>
+<para>
+We have to check that the username is not empty before using it, because LDAP
+does not permit empty DN components. We must also use the <option>quote_ldap_dn</option>
+operator to correctly quote the DN for authentication. However, the basic
+<option>quote</option> operator, rather than any of the LDAP quoting operators, is the
+correct one to use for the password, because quoting is needed only to make
+the password conform to the Exim syntax. At the LDAP level, the password is an
+uninterpreted string.
+</para>
+</section>
+<section id="SECID174">
+<title>Support for different kinds of authentication</title>
+<para>
+A number of string expansion features are provided for the purpose of
+interfacing to different ways of user authentication. These include checking
+traditionally encrypted passwords from <filename>/etc/passwd</filename> (or equivalent), PAM,
+Radius, <option>ldapauth</option>, <emphasis>pwcheck</emphasis>, and <emphasis>saslauthd</emphasis>. For details see section
+<xref linkend="SECTexpcond"/>.
+</para>
+</section>
+<section id="SECID175">
+<title>Using plaintext in a client</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>plaintext</command> authenticator (client)</secondary>
+</indexterm>
+The <command>plaintext</command> authenticator has two client options:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>client_ignore_invalid_base64</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_ignore_invalid_base64</option></entry>
+<entry>Use: <emphasis>plaintext</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If the client receives a server prompt that is not a valid base64 string,
+authentication is abandoned by default. However, if this option is set true,
+the error in the challenge is ignored and the client sends the response as
+usual.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>client_send</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_send</option></entry>
+<entry>Use: <emphasis>plaintext</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+The string is a colon-separated list of authentication data strings. Each
+string is independently expanded before being sent to the server. The first
+string is sent with the AUTH command; any more strings are sent in response
+to prompts from the server. Before each string is expanded, the value of the
+most recent prompt is placed in the next <varname>$auth</varname><<emphasis>n</emphasis>> variable, starting
+with <varname>$auth1</varname> for the first prompt. Up to three prompts are stored in this
+way. Thus, the prompt that is received in response to sending the first string
+(with the AUTH command) can be used in the expansion of the second string, and
+so on. If an invalid base64 string is received when
+<option>client_ignore_invalid_base64</option> is set, an empty string is put in the
+<varname>$auth</varname><<emphasis>n</emphasis>> variable.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: You cannot use expansion to create multiple strings, because
+splitting takes priority and happens first.
+</para>
+<para>
+Because the PLAIN authentication mechanism requires NUL (binary zero) bytes in
+the data, further processing is applied to each string before it is sent. If
+there are any single circumflex characters in the string, they are converted to
+NULs. Should an actual circumflex be required as data, it must be doubled in
+the string.
+</para>
+<para>
+This is an example of a client configuration that implements the PLAIN
+authentication mechanism with a fixed user name and password:
+</para>
+<literallayout class="monospaced">
+fixed_plain:
+ driver = plaintext
+ public_name = PLAIN
+ client_send = ^username^mysecret
+</literallayout>
+<para>
+The lack of colons means that the entire text is sent with the AUTH
+command, with the circumflex characters converted to NULs. A similar example
+that uses the LOGIN mechanism is:
+</para>
+<literallayout class="monospaced">
+fixed_login:
+ driver = plaintext
+ public_name = LOGIN
+ client_send = : username : mysecret
+</literallayout>
+<para>
+The initial colon means that the first string is empty, so no data is sent with
+the AUTH command itself. The remaining strings are sent in response to
+prompts.
+<indexterm role="concept" startref="IIDplaiauth1" class="endofrange"/>
+<indexterm role="concept" startref="IIDplaiauth2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHID9">
+<title>The cram_md5 authenticator</title>
+<para>
+<indexterm role="concept" id="IIDcramauth1" class="startofrange">
+<primary><command>cram_md5</command> authenticator</primary>
+</indexterm>
+<indexterm role="concept" id="IIDcramauth2" class="startofrange">
+<primary>authenticators</primary>
+<secondary><command>cram_md5</command></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>CRAM-MD5 authentication mechanism</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>CRAM-MD5</secondary>
+</indexterm>
+The CRAM-MD5 authentication mechanism is described in RFC 2195. The server
+sends a challenge string to the client, and the response consists of a user
+name and the CRAM-MD5 digest of the challenge string combined with a secret
+string (password) which is known to both server and client. Thus, the secret
+is not sent over the network as plain text, which makes this authenticator more
+secure than <command>plaintext</command>. However, the downside is that the secret has to be
+available in plain text at either end.
+</para>
+<section id="SECID176">
+<title>Using cram_md5 as a server</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>cram_md5</command> authenticator (server)</secondary>
+</indexterm>
+This authenticator has one server option, which must be set to configure the
+authenticator as a server:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_secret</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_secret</option></entry>
+<entry>Use: <emphasis>cram_md5</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>numerical variables (<varname>$1</varname> <varname>$2</varname> etc)</primary>
+<secondary>in <command>cram_md5</command> authenticator</secondary>
+</indexterm>
+When the server receives the client’s response, the user name is placed in
+the expansion variable <varname>$auth1</varname>, and <option>server_secret</option> is expanded to
+obtain the password for that user. The server then computes the CRAM-MD5 digest
+that the client should have sent, and checks that it received the correct
+string. If the expansion of <option>server_secret</option> is forced to fail, authentication
+fails. If the expansion fails for some other reason, a temporary error code is
+returned to the client.
+</para>
+<para>
+For compatibility with previous releases of Exim, the user name is also placed
+in <varname>$1</varname>. However, the use of this variables for this purpose is now
+deprecated, as it can lead to confusion in string expansions that also use
+numeric variables for other things.
+</para>
+<para>
+For example, the following authenticator checks that the user name given by the
+client is <quote>ph10</quote>, and if so, uses <quote>secret</quote> as the password. For any other
+user name, authentication fails.
+</para>
+<literallayout class="monospaced">
+fixed_cram:
+ driver = cram_md5
+ public_name = CRAM-MD5
+ server_secret = ${if eq{$auth1}{ph10}{secret}fail}
+ server_set_id = $auth1
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$authenticated_id</varname></primary>
+</indexterm>
+If authentication succeeds, the setting of <option>server_set_id</option> preserves the user
+name in <varname>$authenticated_id</varname>. A more typical configuration might look up the
+secret string in a file, using the user name as the key. For example:
+</para>
+<literallayout class="monospaced">
+lookup_cram:
+ driver = cram_md5
+ public_name = CRAM-MD5
+ server_secret = ${lookup{$auth1}lsearch{/etc/authpwd}\
+ {$value}fail}
+ server_set_id = $auth1
+</literallayout>
+<para>
+Note that this expansion explicitly forces failure if the lookup fails
+because <varname>$auth1</varname> contains an unknown user name.
+</para>
+<para>
+As another example, if you wish to re-use a Cyrus SASL sasldb2 file without
+using the relevant libraries, you need to know the realm to specify in the
+lookup and then ask for the <quote>userPassword</quote> attribute for that user in that
+realm, with:
+</para>
+<literallayout class="monospaced">
+cyrusless_crammd5:
+ driver = cram_md5
+ public_name = CRAM-MD5
+ server_secret = ${lookup{$auth1:mail.example.org:userPassword}\
+ dbmjz{/etc/sasldb2}{$value}fail}
+ server_set_id = $auth1
+</literallayout>
+</section>
+<section id="SECID177">
+<title>Using cram_md5 as a client</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>cram_md5</command> authenticator (client)</secondary>
+</indexterm>
+When used as a client, the <command>cram_md5</command> authenticator has two options:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>client_name</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_name</option></entry>
+<entry>Use: <emphasis>cram_md5</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>the primary host name</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This string is expanded, and the result used as the user name data when
+computing the response to the server’s challenge.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>client_secret</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_secret</option></entry>
+<entry>Use: <emphasis>cram_md5</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option must be set for the authenticator to work as a client. Its value is
+expanded and the result used as the secret string when computing the response.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host_address</varname></primary>
+</indexterm>
+Different user names and secrets can be used for different servers by referring
+to <varname>$host</varname> or <varname>$host_address</varname> in the options. Forced failure of either
+expansion string is treated as an indication that this authenticator is not
+prepared to handle this case. Exim moves on to the next configured client
+authenticator. Any other expansion failure causes Exim to give up trying to
+send the message to the current server.
+</para>
+<para>
+A simple example configuration of a <command>cram_md5</command> authenticator, using fixed
+strings, is:
+</para>
+<literallayout class="monospaced">
+fixed_cram:
+ driver = cram_md5
+ public_name = CRAM-MD5
+ client_name = ph10
+ client_secret = secret
+</literallayout>
+<para>
+<indexterm role="concept" startref="IIDcramauth1" class="endofrange"/>
+<indexterm role="concept" startref="IIDcramauth2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHID10">
+<title>The cyrus_sasl authenticator</title>
+<para>
+<indexterm role="concept" id="IIDcyrauth1" class="startofrange">
+<primary><command>cyrus_sasl</command> authenticator</primary>
+</indexterm>
+<indexterm role="concept" id="IIDcyrauth2" class="startofrange">
+<primary>authenticators</primary>
+<secondary><command>cyrus_sasl</command></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Cyrus</primary>
+<secondary>SASL library</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Kerberos</primary>
+</indexterm>
+The code for this authenticator was provided by Matthew Byng-Maddick while
+at A L Digital Ltd.
+</para>
+<para>
+The <command>cyrus_sasl</command> authenticator provides server support for the Cyrus SASL
+library implementation of the RFC 2222 (<quote>Simple Authentication and Security
+Layer</quote>). This library supports a number of authentication mechanisms,
+including PLAIN and LOGIN, but also several others that Exim does not support
+directly. In particular, there is support for Kerberos authentication.
+</para>
+<para>
+The <command>cyrus_sasl</command> authenticator provides a gatewaying mechanism directly to
+the Cyrus interface, so if your Cyrus library can do, for example, CRAM-MD5,
+then so can the <command>cyrus_sasl</command> authenticator. By default it uses the public
+name of the driver to determine which mechanism to support.
+</para>
+<para>
+Where access to some kind of secret file is required, for example, in GSSAPI
+or CRAM-MD5, it is worth noting that the authenticator runs as the Exim
+user, and that the Cyrus SASL library has no way of escalating privileges
+by default. You may also find you need to set environment variables,
+depending on the driver you are using.
+</para>
+<para>
+The application name provided by Exim is <quote>exim</quote>, so various SASL options may
+be set in <filename>exim.conf</filename> in your SASL directory. If you are using GSSAPI for
+Kerberos, note that because of limitations in the GSSAPI interface,
+changing the server keytab might need to be communicated down to the Kerberos
+layer independently. The mechanism for doing so is dependent upon the Kerberos
+implementation.
+</para>
+<para>
+For example, for older releases of Heimdal, the environment variable KRB5_KTNAME
+may be set to point to an alternative keytab file. Exim will pass this
+variable through from its own inherited environment when started as root or the
+Exim user. The keytab file needs to be readable by the Exim user.
+With newer releases of Heimdal, a setuid Exim may cause Heimdal to discard the
+environment variable. In practice, for those releases, the Cyrus authenticator
+is not a suitable interface for GSSAPI (Kerberos) support. Instead, consider
+the <command>heimdal_gssapi</command> authenticator, described in chapter <xref linkend="CHAPheimdalgss"/>
+</para>
+<section id="SECID178">
+<title>Using cyrus_sasl as a server</title>
+<para>
+The <command>cyrus_sasl</command> authenticator has four private options. It puts the username
+(on a successful authentication) into <varname>$auth1</varname>. For compatibility with
+previous releases of Exim, the username is also placed in <varname>$1</varname>. However, the
+use of this variable for this purpose is now deprecated, as it can lead to
+confusion in string expansions that also use numeric variables for other
+things.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_hostname</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_hostname</option></entry>
+<entry>Use: <emphasis>cyrus_sasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option selects the hostname that is used when communicating with the
+library. The default value is <literal>$primary_hostname</literal>. It is up to the underlying
+SASL plug-in what it does with this data.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_mech</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_mech</option></entry>
+<entry>Use: <emphasis>cyrus_sasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option selects the authentication mechanism this driver should use. The
+default is the value of the generic <option>public_name</option> option. This option allows
+you to use a different underlying mechanism from the advertised name. For
+example:
+</para>
+<literallayout class="monospaced">
+sasl:
+ driver = cyrus_sasl
+ public_name = X-ANYTHING
+ server_mech = CRAM-MD5
+ server_set_id = $auth1
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>server_realm</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_realm</option></entry>
+<entry>Use: <emphasis>cyrus_sasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies the SASL realm that the server claims to be in.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_service</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_service</option></entry>
+<entry>Use: <emphasis>cyrus_sasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis><literal>smtp</literal></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This is the SASL service that the server claims to implement.
+</para>
+<para>
+For straightforward cases, you do not need to set any of the authenticator’s
+private options. All you need to do is to specify an appropriate mechanism as
+the public name. Thus, if you have a SASL library that supports CRAM-MD5 and
+PLAIN, you could have two authenticators as follows:
+</para>
+<literallayout class="monospaced">
+sasl_cram_md5:
+ driver = cyrus_sasl
+ public_name = CRAM-MD5
+ server_set_id = $auth1
+
+sasl_plain:
+ driver = cyrus_sasl
+ public_name = PLAIN
+ server_set_id = $auth2
+</literallayout>
+<para>
+Cyrus SASL does implement the LOGIN authentication method, even though it is
+not a standard method. It is disabled by default in the source distribution,
+but it is present in many binary distributions.
+<indexterm role="concept" startref="IIDcyrauth1" class="endofrange"/>
+<indexterm role="concept" startref="IIDcyrauth2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPdovecot">
+<title>The dovecot authenticator</title>
+<para>
+<indexterm role="concept" id="IIDdcotauth1" class="startofrange">
+<primary><command>dovecot</command> authenticator</primary>
+</indexterm>
+<indexterm role="concept" id="IIDdcotauth2" class="startofrange">
+<primary>authenticators</primary>
+<secondary><command>dovecot</command></secondary>
+</indexterm>
+This authenticator is an interface to the authentication facility of the
+Dovecot 2 POP/IMAP server, which can support a number of authentication methods.
+Note that Dovecot must be configured to use auth-client not auth-userdb.
+If you are using Dovecot to authenticate POP/IMAP clients, it might be helpful
+to use the same mechanisms for SMTP authentication. This is a server
+authenticator only. There is only one option:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_socket</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_socket</option></entry>
+<entry>Use: <emphasis>dovecot</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option must specify the UNIX socket that is the interface to Dovecot
+authentication. The <option>public_name</option> option must specify an authentication
+mechanism that Dovecot is configured to support. You can have several
+authenticators for different mechanisms. For example:
+</para>
+<literallayout class="monospaced">
+dovecot_plain:
+ driver = dovecot
+ public_name = PLAIN
+ server_socket = /var/run/dovecot/auth-client
+ server_set_id = $auth1
+
+dovecot_ntlm:
+ driver = dovecot
+ public_name = NTLM
+ server_socket = /var/run/dovecot/auth-client
+ server_set_id = $auth1
+</literallayout>
+<para>
+If the SMTP connection is encrypted, or if <varname>$sender_host_address</varname> is equal to
+<varname>$received_ip_address</varname> (that is, the connection is local), the <quote>secured</quote>
+option is passed in the Dovecot authentication command. If, for a TLS
+connection, a client certificate has been verified, the <quote>valid-client-cert</quote>
+option is passed. When authentication succeeds, the identity of the user
+who authenticated is placed in <varname>$auth1</varname>.
+</para>
+<para revisionflag="changed">
+The Dovecot configuration to match the above wil look
+something like:
+</para>
+<literallayout class="monospaced" revisionflag="changed">
+conf.d/10-master.conf :-
+
+service auth {
+...
+#SASL
+ unix_listener auth-client {
+ mode = 0660
+ user = mail
+ }
+...
+}
+
+conf.d/10-auth.conf :-
+
+auth_mechanisms = plain login ntlm
+</literallayout>
+<para>
+<indexterm role="concept" startref="IIDdcotauth1" class="endofrange"/>
+<indexterm role="concept" startref="IIDdcotauth2" class="endofrange"/>
+</para>
+</chapter>
+
+<chapter id="CHAPgsasl">
+<title>The gsasl authenticator</title>
+<para>
+<indexterm role="concept" id="IIDgsaslauth1" class="startofrange">
+<primary><command>gsasl</command> authenticator</primary>
+</indexterm>
+<indexterm role="concept" id="IIDgsaslauth2" class="startofrange">
+<primary>authenticators</primary>
+<secondary><command>gsasl</command></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>GNU SASL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>SASL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>EXTERNAL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>ANONYMOUS</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>PLAIN</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>LOGIN</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>DIGEST-MD5</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>CRAM-MD5</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>SCRAM family</secondary>
+</indexterm>
+The <command>gsasl</command> authenticator provides integration for the GNU SASL
+library and the mechanisms it provides. This is new as of the 4.80 release
+and there are a few areas where the library does not let Exim smoothly
+scale to handle future authentication mechanisms, so no guarantee can be
+made that any particular new authentication mechanism will be supported
+without code changes in Exim.
+</para>
+<para revisionflag="changed">
+The library is expected to add support in an upcoming
+realease for the SCRAM-SHA-256 method.
+The macro _HAVE_AUTH_GSASL_SCRAM_SHA_256 will be defined
+when this happens.
+</para>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>client_authz</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all" revisionflag="changed">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_authz</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para revisionflag="changed">
+This option can be used to supply an <emphasis>authorization id</emphasis>
+which is different to the <emphasis>authentication_id</emphasis> provided
+by <option>client_username</option> option.
+If unset or (after expansion) empty it is not used,
+which is the common case.
+</para>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>client_channelbinding</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all" revisionflag="changed">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_channelbinding</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para revisionflag="changed">
+See <option>server_channelbinding</option> below.
+</para>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>client_password</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all" revisionflag="changed">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_password</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para revisionflag="changed">
+This option is exapanded before use, and should result in
+the password to be used, in clear.
+</para>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>client_username</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all" revisionflag="changed">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_username</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para revisionflag="changed">
+This option is exapanded before use, and should result in
+the account name to be used.
+</para>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>client_spassword</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all" revisionflag="changed">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_spassword</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para revisionflag="changed">
+If a SCRAM mechanism is being used and this option is set
+it is used in preference to <option>client_password</option>.
+The value after expansion should be
+a 40 (for SHA-1) or 64 (for SHA-256) character string
+with the PBKDF2-prepared password, hex-encoded.
+Note that this value will depend on the salt and iteration-count
+supplied by the server.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_channelbinding</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_channelbinding</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>boolean</emphasis></entry>
+<entry>Default: <emphasis>false</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Do not set this true and rely on the properties
+without consulting a cryptographic engineer.
+</para>
+<para>
+Some authentication mechanisms are able to use external context at both ends
+of the session to bind the authentication to that context, and fail the
+authentication process if that context differs. Specifically, some TLS
+ciphersuites can provide identifying information about the cryptographic
+context.
+</para>
+<para>
+This should have meant that certificate identity and verification becomes a
+non-issue, as a man-in-the-middle attack will cause the correct client and
+server to see different identifiers and authentication will fail.
+</para>
+<para revisionflag="changed">
+This is
+only usable by mechanisms which support "channel binding"; at time of
+writing, that’s the SCRAM family.
+When using this feature the "-PLUS" variants of the method names need to be used.
+</para>
+<para>
+This defaults off to ensure smooth upgrade across Exim releases, in case
+this option causes some clients to start failing. Some future release
+of Exim might have switched the default to be true.
+</para>
+<para>
+However, Channel Binding in TLS has proven to be vulnerable in current versions.
+Do not plan to rely upon this feature for security, ever, without consulting
+with a subject matter expert (a cryptographic engineer).
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_hostname</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_hostname</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option selects the hostname that is used when communicating with the
+library. The default value is <literal>$primary_hostname</literal>.
+Some mechanisms will use this data.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_mech</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_mech</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option selects the authentication mechanism this driver should use. The
+default is the value of the generic <option>public_name</option> option. This option allows
+you to use a different underlying mechanism from the advertised name. For
+example:
+</para>
+<literallayout class="monospaced">
+sasl:
+ driver = gsasl
+ public_name = X-ANYTHING
+ server_mech = CRAM-MD5
+ server_set_id = $auth1
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>server_password</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_password</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Various mechanisms need access to the cleartext password on the server, so
+that proof-of-possession can be demonstrated on the wire, without sending
+the password itself.
+</para>
+<para>
+The data available for lookup varies per mechanism.
+In all cases, <varname>$auth1</varname> is set to the <emphasis>authentication id</emphasis>.
+The <varname>$auth2</varname> variable will always be the <emphasis>authorization id</emphasis> (<emphasis>authz</emphasis>)
+if available, else the empty string.
+The <varname>$auth3</varname> variable will always be the <emphasis>realm</emphasis> if available,
+else the empty string.
+</para>
+<para>
+A forced failure will cause authentication to defer.
+</para>
+<para>
+If using this option, it may make sense to set the <option>server_condition</option>
+option to be simply "true".
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_realm</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_realm</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This specifies the SASL realm that the server claims to be in.
+Some mechanisms will use this data.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_scram_iter</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_scram_iter</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>4096</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option provides data for the SCRAM family of mechanisms.
+</para>
+<para revisionflag="changed">
+The <varname>$auth1</varname>, <varname>$auth2</varname> and <varname>$auth3</varname> variables are available
+when this option is expanded.
+</para>
+<para revisionflag="changed">
+The result of expansion should be a decimal number,
+and represents both a lower-bound on the security, and
+a compute cost factor imposed on the client
+(if it does not cache results, or the server changes
+either the iteration count or the salt).
+A minimum value of 4096 is required by the standards
+for all current SCRAM mechanism variants.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_scram_salt</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_scram_salt</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option provides data for the SCRAM family of mechanisms.
+</para>
+<para revisionflag="changed">
+The <varname>$auth1</varname>, <varname>$auth2</varname> and <varname>$auth3</varname> variables are available
+when this option is expanded.
+The value should be a base64-encoded string,
+of random data typically 4-to-16 bytes long.
+If unset or empty after expansion the library will provides a value for the
+protocol conversation.
+</para>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>server_key</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all" revisionflag="changed">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_key</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>server_skey</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all" revisionflag="changed">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_skey</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para revisionflag="changed">
+These options can be used for the SCRAM family of mechanisms
+to provide stored information related to a password,
+the storage of which is preferable to plaintext.
+</para>
+<para revisionflag="changed">
+<option>server_key</option> is the value defined in the SCRAM standards as ServerKey;
+<option>server_skey</option> is StoredKey.
+</para>
+<para revisionflag="changed">
+They are only available for version 1.9.0 (or later) of the gsasl library.
+When this is so, the macros
+_OPT_AUTHENTICATOR_GSASL_SERVER_KEY
+and _HAVE_AUTH_GSASL_SCRAM_S_KEY
+will be defined.
+</para>
+<para revisionflag="changed">
+The <varname>$authN</varname> variables are available when these options are expanded.
+</para>
+<para revisionflag="changed">
+If set, the results of expansion should for each
+should be a 28 (for SHA-1) or 44 (for SHA-256) character string
+of base64-coded data, and will be used in preference to the
+<option>server_password</option> option.
+If unset or not of the right length, <option>server_password</option> will be used.
+</para>
+<para revisionflag="changed">
+The libgsasl library release includes a utility <emphasis>gsasl</emphasis> which can be used
+to generate these values.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_service</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_service</option></entry>
+<entry>Use: <emphasis>gsasl</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis><literal>smtp</literal></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This is the SASL service that the server claims to implement.
+Some mechanisms will use this data.
+</para>
+<section id="SECTgsaslauthvar">
+<title><command>gsasl</command> auth variables</title>
+<para>
+<indexterm role="variable">
+<primary><varname>$auth1</varname>, <varname>$auth2</varname>, etc</primary>
+</indexterm>
+These may be set when evaluating specific options, as detailed above.
+They will also be set when evaluating <option>server_condition</option>.
+</para>
+<para>
+Unless otherwise stated below, the <command>gsasl</command> integration will use the following
+meanings for these variables:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$auth1</varname></primary>
+</indexterm>
+<varname>$auth1</varname>: the <emphasis>authentication id</emphasis>
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$auth2</varname></primary>
+</indexterm>
+<varname>$auth2</varname>: the <emphasis>authorization id</emphasis>
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$auth3</varname></primary>
+</indexterm>
+<varname>$auth3</varname>: the <emphasis>realm</emphasis>
+</para>
+</listitem>
+</itemizedlist>
+<para>
+On a per-mechanism basis:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>EXTERNAL</secondary>
+</indexterm>
+EXTERNAL: only <varname>$auth1</varname> is set, to the possibly empty <emphasis>authorization id</emphasis>;
+the <option>server_condition</option> option must be present.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>ANONYMOUS</secondary>
+</indexterm>
+ANONYMOUS: only <varname>$auth1</varname> is set, to the possibly empty <emphasis>anonymous token</emphasis>;
+the <option>server_condition</option> option must be present.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>GSSAPI</secondary>
+</indexterm>
+GSSAPI: <varname>$auth1</varname> will be set to the <emphasis>GSSAPI Display Name</emphasis>;
+<varname>$auth2</varname> will be set to the <emphasis>authorization id</emphasis>,
+the <option>server_condition</option> option must be present.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+An <emphasis>anonymous token</emphasis> is something passed along as an unauthenticated
+identifier; this is analogous to FTP anonymous authentication passing an
+email address, or software-identifier@, as the "password".
+</para>
+<para>
+An example showing the password having the realm specified in the callback
+and demonstrating a Cyrus SASL to GSASL migration approach is:
+</para>
+<literallayout class="monospaced">
+gsasl_cyrusless_crammd5:
+ driver = gsasl
+ public_name = CRAM-MD5
+ server_realm = imap.example.org
+ server_password = ${lookup{$auth1:$auth3:userPassword}\
+ dbmjz{/etc/sasldb2}{$value}fail}
+ server_set_id = ${quote:$auth1}
+ server_condition = yes
+</literallayout>
+</section>
+</chapter>
+
+<chapter id="CHAPheimdalgss">
+<title>The heimdal_gssapi authenticator</title>
+<para>
+<indexterm role="concept" id="IIDheimdalgssauth1" class="startofrange">
+<primary><command>heimdal_gssapi</command> authenticator</primary>
+</indexterm>
+<indexterm role="concept" id="IIDheimdalgssauth2" class="startofrange">
+<primary>authenticators</primary>
+<secondary><command>heimdal_gssapi</command></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>GSSAPI</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>Kerberos</secondary>
+</indexterm>
+The <command>heimdal_gssapi</command> authenticator provides server integration for the
+Heimdal GSSAPI/Kerberos library, permitting Exim to set a keytab pathname
+reliably.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_hostname</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_hostname</option></entry>
+<entry>Use: <emphasis>heimdal_gssapi</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option selects the hostname that is used, with <option>server_service</option>,
+for constructing the GSS server name, as a <emphasis>GSS_C_NT_HOSTBASED_SERVICE</emphasis>
+identifier. The default value is <literal>$primary_hostname</literal>.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_keytab</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_keytab</option></entry>
+<entry>Use: <emphasis>heimdal_gssapi</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If set, then Heimdal will not use the system default keytab (typically
+<filename>/etc/krb5.keytab</filename>) but instead the pathname given in this option.
+The value should be a pathname, with no <quote>file:</quote> prefix.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_service</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_service</option></entry>
+<entry>Use: <emphasis>heimdal_gssapi</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>smtp</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies the service identifier used, in conjunction with
+<option>server_hostname</option>, for building the identifier for finding credentials
+from the keytab.
+</para>
+<section id="SECTheimdalgssauthvar">
+<title><command>heimdal_gssapi</command> auth variables</title>
+<para>
+Beware that these variables will typically include a realm, thus will appear
+to be roughly like an email address already. The <emphasis>authzid</emphasis> in <varname>$auth2</varname> is
+not verified, so a malicious client can set it to anything.
+</para>
+<para>
+The <varname>$auth1</varname> field should be safely trustable as a value from the Key
+Distribution Center. Note that these are not quite email addresses.
+Each identifier is for a role, and so the left-hand-side may include a
+role suffix. For instance, <quote>joe/admin@EXAMPLE.ORG</quote>.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$auth1</varname>, <varname>$auth2</varname>, etc</primary>
+</indexterm>
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$auth1</varname></primary>
+</indexterm>
+<varname>$auth1</varname>: the <emphasis>authentication id</emphasis>, set to the GSS Display Name.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$auth2</varname></primary>
+</indexterm>
+<varname>$auth2</varname>: the <emphasis>authorization id</emphasis>, sent within SASL encapsulation after
+authentication. If that was empty, this will also be set to the
+GSS Display Name.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+</chapter>
+
+<chapter id="CHAPspa">
+<title>The spa authenticator</title>
+<para>
+<indexterm role="concept" id="IIDspaauth1" class="startofrange">
+<primary><command>spa</command> authenticator</primary>
+</indexterm>
+<indexterm role="concept" id="IIDspaauth2" class="startofrange">
+<primary>authenticators</primary>
+<secondary><command>spa</command></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>Microsoft Secure Password</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>NTLM</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Microsoft Secure Password Authentication</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>NTLM authentication</primary>
+</indexterm>
+The <command>spa</command> authenticator provides client support for Microsoft’s <emphasis>Secure
+Password Authentication</emphasis> mechanism,
+which is also sometimes known as NTLM (NT LanMan). The code for client side of
+this authenticator was contributed by Marc Prud’hommeaux, and much of it is
+taken from the Samba project (<emphasis role="bold"><ulink url="https://www.samba.org/">https://www.samba.org/</ulink></emphasis>). The code for the
+server side was subsequently contributed by Tom Kistner. The mechanism works as
+follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+After the AUTH command has been accepted, the client sends an SPA
+authentication request based on the user name and optional domain.
+</para>
+</listitem>
+<listitem>
+<para>
+The server sends back a challenge.
+</para>
+</listitem>
+<listitem>
+<para>
+The client builds a challenge response which makes use of the user’s password
+and sends it to the server, which then accepts or rejects it.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Encryption is used to protect the password in transit.
+</para>
+<section id="SECID179">
+<title>Using spa as a server</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>spa</command> authenticator (server)</secondary>
+</indexterm>
+The <command>spa</command> authenticator has just one server option:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_password</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_password</option></entry>
+<entry>Use: <emphasis>spa</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>numerical variables (<varname>$1</varname> <varname>$2</varname> etc)</primary>
+<secondary>in <command>spa</command> authenticator</secondary>
+</indexterm>
+This option is expanded, and the result must be the cleartext password for the
+authenticating user, whose name is at this point in <varname>$auth1</varname>. For
+compatibility with previous releases of Exim, the user name is also placed in
+<varname>$1</varname>. However, the use of this variable for this purpose is now deprecated, as
+it can lead to confusion in string expansions that also use numeric variables
+for other things. For example:
+</para>
+<literallayout class="monospaced">
+spa:
+ driver = spa
+ public_name = NTLM
+ server_password = \
+ ${lookup{$auth1}lsearch{/etc/exim/spa_clearpass}{$value}fail}
+</literallayout>
+<para>
+If the expansion is forced to fail, authentication fails. Any other expansion
+failure causes a temporary error code to be returned.
+</para>
+</section>
+<section id="SECID180">
+<title>Using spa as a client</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>spa</command> authenticator (client)</secondary>
+</indexterm>
+The <command>spa</command> authenticator has the following client options:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>client_domain</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_domain</option></entry>
+<entry>Use: <emphasis>spa</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies an optional domain for the authentication.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>client_password</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_password</option></entry>
+<entry>Use: <emphasis>spa</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies the user’s password, and must be set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>client_username</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_username</option></entry>
+<entry>Use: <emphasis>spa</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option specifies the user name, and must be set. Here is an example of a
+configuration of this authenticator for use with the mail servers at
+<emphasis>msn.com</emphasis>:
+</para>
+<literallayout class="monospaced">
+msn:
+ driver = spa
+ public_name = MSN
+ client_username = msn/msn_username
+ client_password = msn_plaintext_password
+ client_domain = DOMAIN_OR_UNSET
+</literallayout>
+<para>
+<indexterm role="concept" startref="IIDspaauth1" class="endofrange"/>
+<indexterm role="concept" startref="IIDspaauth2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPexternauth">
+<title>The external authenticator</title>
+<para>
+<indexterm role="concept" id="IIDexternauth1" class="startofrange">
+<primary><command>external</command> authenticator</primary>
+</indexterm>
+<indexterm role="concept" id="IIDexternauth2" class="startofrange">
+<primary>authenticators</primary>
+<secondary><command>external</command></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>Client Certificate</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>X509</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Certificate-based authentication</primary>
+</indexterm>
+The <command>external</command> authenticator provides support for
+authentication based on non-SMTP information.
+The specification is in RFC 4422 Appendix A
+(<emphasis role="bold"><ulink url="https://tools.ietf.org/html/rfc4422">https://tools.ietf.org/html/rfc4422</ulink></emphasis>).
+It is only a transport and negotiation mechanism;
+the process of authentication is entirely controlled
+by the server configuration.
+</para>
+<para>
+The client presents an identity in-clear.
+It is probably wise for a server to only advertise,
+and for clients to only attempt,
+this authentication method on a secure (eg. under TLS) connection.
+</para>
+<para>
+One possible use, compatible with the
+K-9 Mail Andoid client (<emphasis role="bold"><ulink url="https://k9mail.github.io/">https://k9mail.github.io/</ulink></emphasis>),
+is for using X509 client certificates.
+</para>
+<para>
+It thus overlaps in function with the TLS authenticator
+(see <xref linkend="CHAPtlsauth"/>)
+but is a full SMTP SASL authenticator
+rather than being implicit for TLS-connection carried
+client certificates only.
+</para>
+<para>
+The examples and discussion in this chapter assume that
+client-certificate authentication is being done.
+</para>
+<para>
+The client must present a certificate,
+for which it must have been requested via the
+<option>tls_verify_hosts</option> or <option>tls_try_verify_hosts</option> main options
+(see <xref linkend="CHAPTLS"/>).
+For authentication to be effective the certificate should be
+verifiable against a trust-anchor certificate known to the server.
+</para>
+<section id="SECTexternsoptions">
+<title>External options</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>external</command> authenticator (server)</secondary>
+</indexterm>
+The <command>external</command> authenticator has two server options:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_param2</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_param2</option></entry>
+<entry>Use: <emphasis>external</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="option">
+<primary><option>server_param3</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_param3</option></entry>
+<entry>Use: <emphasis>external</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>variables (<varname>$auth1</varname> <varname>$auth2</varname> etc)</primary>
+<secondary>in <command>external</command> authenticator</secondary>
+</indexterm>
+These options are expanded before the <option>server_condition</option> option
+and the result are placed in <varname>$auth2</varname> and <varname>$auth3</varname> resectively.
+If the expansion is forced to fail, authentication fails. Any other expansion
+failure causes a temporary error code to be returned.
+</para>
+<para>
+They can be used to clarify the coding of a complex <option>server_condition</option>.
+</para>
+</section>
+<section id="SECTexternserver">
+<title>Using external in a server</title>
+<para>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>in <command>external</command> authenticator</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>numerical variables (<varname>$1</varname> <varname>$2</varname> etc)</primary>
+<secondary>in <command>external</command> authenticator</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$auth1</varname>, <varname>$auth2</varname>, etc</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>base64 encoding</primary>
+<secondary>in <command>external</command> authenticator</secondary>
+</indexterm>
+</para>
+<para>
+When running as a server, <command>external</command> performs the authentication test by
+expanding a string. The data sent by the client with the AUTH command, or in
+response to subsequent prompts, is base64 encoded, and so may contain any byte
+values when decoded. The decoded value is treated as
+an identity for authentication and
+placed in the expansion variable <varname>$auth1</varname>.
+</para>
+<para>
+For compatibility with previous releases of Exim, the value is also placed in
+the expansion variable <varname>$1</varname>. However, the use of this
+variable for this purpose is now deprecated, as it can lead to confusion in
+string expansions that also use them for other things.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$authenticated_id</varname></primary>
+</indexterm>
+Once an identity has been received,
+<option>server_condition</option> is expanded. If the expansion is forced to fail,
+authentication fails. Any other expansion failure causes a temporary error code
+to be returned. If the result of a successful expansion is an empty string,
+<quote>0</quote>, <quote>no</quote>, or <quote>false</quote>, authentication fails. If the result of the
+expansion is <quote>1</quote>, <quote>yes</quote>, or <quote>true</quote>, authentication succeeds and the
+generic <option>server_set_id</option> option is expanded and saved in <varname>$authenticated_id</varname>.
+For any other result, a temporary error code is returned, with the expanded
+string as the error text.
+</para>
+<para>
+Example:
+</para>
+<literallayout class="monospaced">
+ext_ccert_san_mail:
+ driver = external
+ public_name = EXTERNAL
+
+ server_advertise_condition = $tls_in_certificate_verified
+ server_param2 = ${certextract {subj_altname,mail,>:} \
+ {$tls_in_peercert}}
+ server_condition = ${if forany {$auth2} \
+ {eq {$item}{$auth1}}}
+ server_set_id = $auth1
+</literallayout>
+<para>
+This accepts a client certificate that is verifiable against any
+of your configured trust-anchors
+(which usually means the full set of public CAs)
+and which has a mail-SAN matching the claimed identity sent by the client.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: up to TLS1.2, the client cert is on the wire in-clear, including the SAN.
+The account name is therefore guessable by an opponent.
+TLS 1.3 protects both server and client certificates, and is not vulnerable
+in this way.
+</para>
+</section>
+<section id="SECTexternclient">
+<title>Using external in a client</title>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>external</command> authenticator (client)</secondary>
+</indexterm>
+The <command>external</command> authenticator has one client option:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>client_send</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>client_send</option></entry>
+<entry>Use: <emphasis>external</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option is expanded and sent with the AUTH command as the
+identity being asserted.
+</para>
+<para>
+Example:
+</para>
+<literallayout class="monospaced">
+ext_ccert:
+ driver = external
+ public_name = EXTERNAL
+
+ client_condition = ${if !eq{$tls_out_cipher}{}}
+ client_send = myaccount@smarthost.example.net
+</literallayout>
+<para>
+<indexterm role="concept" startref="IIDexternauth1" class="endofrange"/>
+<indexterm role="concept" startref="IIDexternauth2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPtlsauth">
+<title>The tls authenticator</title>
+<para>
+<indexterm role="concept" id="IIDtlsauth1" class="startofrange">
+<primary><command>tls</command> authenticator</primary>
+</indexterm>
+<indexterm role="concept" id="IIDtlsauth2" class="startofrange">
+<primary>authenticators</primary>
+<secondary><command>tls</command></secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>Client Certificate</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>X509</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Certificate-based authentication</primary>
+</indexterm>
+The <command>tls</command> authenticator provides server support for
+authentication based on client certificates.
+</para>
+<para>
+It is not an SMTP authentication mechanism and is not
+advertised by the server as part of the SMTP EHLO response.
+It is an Exim authenticator in the sense that it affects
+the protocol element of the log line, can be tested for
+by the <option>authenticated</option> ACL condition, and can set
+the <varname>$authenticated_id</varname> variable.
+</para>
+<para>
+The client must present a verifiable certificate,
+for which it must have been requested via the
+<option>tls_verify_hosts</option> or <option>tls_try_verify_hosts</option> main options
+(see <xref linkend="CHAPTLS"/>).
+</para>
+<para>
+If an authenticator of this type is configured it is
+run before any SMTP-level communication is done,
+and can authenticate the connection.
+If it does, SMTP authentication is not offered.
+</para>
+<para>
+A maximum of one authenticator of this type may be present.
+</para>
+<para>
+<indexterm role="concept">
+<primary>options</primary>
+<secondary><command>tls</command> authenticator (server)</secondary>
+</indexterm>
+The <command>tls</command> authenticator has three server options:
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_param1</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_param1</option></entry>
+<entry>Use: <emphasis>tls</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="concept">
+<primary>variables (<varname>$auth1</varname> <varname>$auth2</varname> etc)</primary>
+<secondary>in <command>tls</command> authenticator</secondary>
+</indexterm>
+This option is expanded after the TLS negotiation and
+the result is placed in <varname>$auth1</varname>.
+If the expansion is forced to fail, authentication fails. Any other expansion
+failure causes a temporary error code to be returned.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>server_param2</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_param2</option></entry>
+<entry>Use: <emphasis>tls</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+<indexterm role="option">
+<primary><option>server_param3</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>server_param3</option></entry>
+<entry>Use: <emphasis>tls</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+As above, for <varname>$auth2</varname> and <varname>$auth3</varname>.
+</para>
+<para>
+<option>server_param1</option> may also be spelled <option>server_param</option>.
+</para>
+<para>
+Example:
+</para>
+<literallayout class="monospaced">
+tls:
+ driver = tls
+ server_param1 = ${certextract {subj_altname,mail,>:} \
+ {$tls_in_peercert}}
+ server_condition = ${if and { {eq{$tls_in_certificate_verified}{1}} \
+ {forany {$auth1} \
+ {!= {0} \
+ {${lookup ldap{ldap:///\
+ mailname=${quote_ldap_dn:${lc:$item}},\
+ ou=users,LDAP_DC?mailid} {$value}{0} \
+ } } } }}}
+ server_set_id = ${if = {1}{${listcount:$auth1}} {$auth1}{}}
+</literallayout>
+<para>
+This accepts a client certificate that is verifiable against any
+of your configured trust-anchors
+(which usually means the full set of public CAs)
+and which has a SAN with a good account name.
+</para>
+<para>
+Note that, up to TLS1.2, the client cert is on the wire in-clear, including the SAN,
+The account name is therefore guessable by an opponent.
+TLS 1.3 protects both server and client certificates, and is not vulnerable
+in this way.
+Likewise, a traditional plaintext SMTP AUTH done inside TLS is not.
+</para>
+<para>
+<indexterm role="concept" startref="IIDtlsauth1" class="endofrange"/>
+<indexterm role="concept" startref="IIDtlsauth2" class="endofrange"/>
+</para>
+<para>
+Note that because authentication is traditionally an SMTP operation,
+the <option>authenticated</option> ACL condition cannot be used in
+a connect- or helo-ACL.
+</para>
+</chapter>
+
+<chapter id="CHAPTLS">
+<title>Encrypted SMTP connections using TLS/SSL</title>
+<titleabbrev>Encrypted SMTP connections</titleabbrev>
+<para>
+<indexterm role="concept" id="IIDencsmtp1" class="startofrange">
+<primary>encryption</primary>
+<secondary>on SMTP connection</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDencsmtp2" class="startofrange">
+<primary>SMTP</primary>
+<secondary>encryption</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>on SMTP connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>OpenSSL</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>GnuTLS</primary>
+</indexterm>
+Support for TLS (Transport Layer Security), formerly known as SSL (Secure
+Sockets Layer), is implemented by making use of the OpenSSL library or the
+GnuTLS library (Exim requires GnuTLS release 1.0 or later). There is no
+cryptographic code in the Exim distribution itself for implementing TLS. In
+order to use this feature you must install OpenSSL or GnuTLS, and then build a
+version of Exim that includes TLS support (see section <xref linkend="SECTinctlsssl"/>).
+You also need to understand the basic concepts of encryption at a managerial
+level, and in particular, the way that public keys, private keys, and
+certificates are used.
+</para>
+<para>
+RFC 3207 defines how SMTP connections can make use of encryption. Once a
+connection is established, the client issues a STARTTLS command. If the
+server accepts this, the client and the server negotiate an encryption
+mechanism. If the negotiation succeeds, the data that subsequently passes
+between them is encrypted.
+</para>
+<para>
+Exim’s ACLs can detect whether the current SMTP session is encrypted or not,
+and if so, what cipher suite is in use, whether the client supplied a
+certificate, and whether or not that certificate was verified. This makes it
+possible for an Exim server to deny or accept certain commands based on the
+encryption state.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: Certain types of firewall and certain anti-virus products can
+disrupt TLS connections. You need to turn off SMTP scanning for these products
+in order to get TLS to work.
+</para>
+<section id="SECID284">
+<title>Support for the <quote>submissions</quote> (aka <quote>ssmtp</quote> and <quote>smtps</quote>) protocol</title>
+<para>
+<indexterm role="concept">
+<primary>submissions protocol</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>ssmtp protocol</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>smtps protocol</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>submissions protocol</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>ssmtp protocol</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>smtps protocol</secondary>
+</indexterm>
+The history of port numbers for TLS in SMTP is a little messy and has been
+contentious. As of RFC 8314, the common practice of using the historically
+allocated port 465 for "email submission but with TLS immediately upon connect
+instead of using STARTTLS" is officially blessed by the IETF, and recommended
+by them in preference to STARTTLS.
+</para>
+<para>
+The name originally assigned to the port was <quote>ssmtp</quote> or <quote>smtps</quote>, but as
+clarity emerged over the dual roles of SMTP, for MX delivery and Email
+Submission, nomenclature has shifted. The modern name is now <quote>submissions</quote>.
+</para>
+<para>
+This approach was, for a while, officially abandoned when encrypted SMTP was
+standardized, but many clients kept using it, even as the TCP port number was
+reassigned for other use.
+Thus you may encounter guidance claiming that you shouldn’t enable use of
+this port.
+In practice, a number of mail-clients have only ever supported submissions,
+not submission with STARTTLS upgrade.
+Ideally, offer both submission (587) and submissions (465) service.
+</para>
+<para>
+Exim supports TLS-on-connect by means of the <option>tls_on_connect_ports</option>
+global option. Its value must be a list of port numbers;
+the most common use is expected to be:
+</para>
+<literallayout class="monospaced">
+tls_on_connect_ports = 465
+</literallayout>
+<para>
+The port numbers specified by this option apply to all SMTP connections, both
+via the daemon and via <emphasis>inetd</emphasis>. You still need to specify all the ports that
+the daemon uses (by setting <option>daemon_smtp_ports</option> or <option>local_interfaces</option> or
+the <option>-oX</option> command line option) because <option>tls_on_connect_ports</option> does not add
+an extra port – rather, it specifies different behaviour on a port that is
+defined elsewhere.
+</para>
+<para>
+There is also a <option>-tls-on-connect</option> command line option. This overrides
+<option>tls_on_connect_ports</option>; it forces the TLS-only behaviour for all ports.
+</para>
+</section>
+<section id="SECTopenvsgnu">
+<title>OpenSSL vs GnuTLS</title>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>OpenSSL <emphasis>vs</emphasis> GnuTLS</secondary>
+</indexterm>
+TLS is supported in Exim using either the OpenSSL or GnuTLS library.
+To build Exim to use OpenSSL you need to set
+</para>
+<literallayout class="monospaced">
+USE_OPENSSL=yes
+</literallayout>
+<para>
+in Local/Makefile.
+</para>
+<para>
+To build Exim to use GnuTLS, you need to set
+</para>
+<literallayout class="monospaced">
+USE_GNUTLS=yes
+</literallayout>
+<para>
+in Local/Makefile.
+</para>
+<para>
+You must also set TLS_LIBS and TLS_INCLUDE appropriately, so that the
+include files and libraries for GnuTLS can be found.
+</para>
+<para>
+There are some differences in usage when using GnuTLS instead of OpenSSL:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The <option>tls_verify_certificates</option> option
+cannot be the path of a directory
+for GnuTLS versions before 3.3.6
+(for later versions, or OpenSSL, it can be either).
+</para>
+</listitem>
+<listitem>
+<para>
+The default value for <option>tls_dhparam</option> differs for historical reasons.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_peerdn</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tls_out_peerdn</varname></primary>
+</indexterm>
+Distinguished Name (DN) strings reported by the OpenSSL library use a slash for
+separating fields; GnuTLS uses commas, in accordance with RFC 2253. This
+affects the value of the <varname>$tls_in_peerdn</varname> and <varname>$tls_out_peerdn</varname> variables.
+</para>
+</listitem>
+<listitem>
+<para>
+OpenSSL identifies cipher suites using hyphens as separators, for example:
+DES-CBC3-SHA. GnuTLS historically used underscores, for example:
+RSA_ARCFOUR_SHA. What is more, OpenSSL complains if underscores are present
+in a cipher list. To make life simpler, Exim changes underscores to hyphens
+for OpenSSL and passes the string unchanged to GnuTLS (expecting the library
+to handle its own older variants) when processing lists of cipher suites in the
+<option>tls_require_ciphers</option> options (the global option and the <command>smtp</command> transport
+option).
+</para>
+</listitem>
+<listitem>
+<para>
+The <option>tls_require_ciphers</option> options operate differently, as described in the
+sections <xref linkend="SECTreqciphssl"/> and <xref linkend="SECTreqciphgnu"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+The <option>tls_dh_min_bits</option> SMTP transport option is only honoured by GnuTLS.
+When using OpenSSL, this option is ignored.
+(If an API is found to let OpenSSL be configured in this way,
+let the Exim Maintainers know and we’ll likely use it).
+</para>
+</listitem>
+<listitem>
+<para>
+With GnuTLS, if an explicit list is used for the <option>tls_privatekey</option> main option
+main option, it must be ordered to match the <option>tls_certificate</option> list.
+</para>
+</listitem>
+<listitem>
+<para>
+Some other recently added features may only be available in one or the other.
+This should be documented with the feature. If the documentation does not
+explicitly state that the feature is infeasible in the other TLS
+implementation, then patches are welcome.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECTgnutlsparam">
+<title>GnuTLS parameter computation</title>
+<para>
+This section only applies if <option>tls_dhparam</option> is set to <literal>historic</literal> or to
+an explicit path; if the latter, then the text about generation still applies,
+but not the chosen filename.
+By default, as of Exim 4.80 a hard-coded D-H prime is used.
+See the documentation of <option>tls_dhparam</option> for more information.
+</para>
+<para>
+GnuTLS uses D-H parameters that may take a substantial amount of time
+to compute. It is unreasonable to re-compute them for every TLS session.
+Therefore, Exim keeps this data in a file in its spool directory, called
+<filename>gnutls-params-NNNN</filename> for some value of NNNN, corresponding to the number
+of bits requested.
+The file is owned by the Exim user and is readable only by
+its owner. Every Exim process that start up GnuTLS reads the D-H
+parameters from this file. If the file does not exist, the first Exim process
+that needs it computes the data and writes it to a temporary file which is
+renamed once it is complete. It does not matter if several Exim processes do
+this simultaneously (apart from wasting a few resources). Once a file is in
+place, new Exim processes immediately start using it.
+</para>
+<para>
+For maximum security, the parameters that are stored in this file should be
+recalculated periodically, the frequency depending on your paranoia level.
+If you are avoiding using the fixed D-H primes published in RFCs, then you
+are concerned about some advanced attacks and will wish to do this; if you do
+not regenerate then you might as well stick to the standard primes.
+</para>
+<para>
+Arranging this is easy in principle; just delete the file when you want new
+values to be computed. However, there may be a problem. The calculation of new
+parameters needs random numbers, and these are obtained from <filename>/dev/random</filename>.
+If the system is not very active, <filename>/dev/random</filename> may delay returning data
+until enough randomness (entropy) is available. This may cause Exim to hang for
+a substantial amount of time, causing timeouts on incoming connections.
+</para>
+<para>
+The solution is to generate the parameters externally to Exim. They are stored
+in <filename>gnutls-params-N</filename> in PEM format, which means that they can be
+generated externally using the <command>certtool</command> command that is part of GnuTLS.
+</para>
+<para>
+To replace the parameters with new ones, instead of deleting the file
+and letting Exim re-create it, you can generate new parameters using
+<command>certtool</command> and, when this has been done, replace Exim’s cache file by
+renaming. The relevant commands are something like this:
+</para>
+<literallayout class="monospaced">
+# ls
+[ look for file; assume gnutls-params-2236 is the most recent ]
+# rm -f new-params
+# touch new-params
+# chown exim:exim new-params
+# chmod 0600 new-params
+# certtool --generate-dh-params --bits 2236 >>new-params
+# openssl dhparam -noout -text -in new-params | head
+[ check the first line, make sure it's not more than 2236;
+ if it is, then go back to the start ("rm") and repeat
+ until the size generated is at most the size requested ]
+# chmod 0400 new-params
+# mv new-params gnutls-params-2236
+</literallayout>
+<para>
+If Exim never has to generate the parameters itself, the possibility of
+stalling is removed.
+</para>
+<para>
+The filename changed in Exim 4.80, to gain the -bits suffix. The value which
+Exim will choose depends upon the version of GnuTLS in use. For older GnuTLS,
+the value remains hard-coded in Exim as 1024. As of GnuTLS 2.12.x, there is
+a way for Exim to ask for the "normal" number of bits for D-H public-key usage,
+and Exim does so. This attempt to remove Exim from TLS policy decisions
+failed, as GnuTLS 2.12 returns a value higher than the current hard-coded limit
+of the NSS library. Thus Exim gains the <option>tls_dh_max_bits</option> global option,
+which applies to all D-H usage, client or server. If the value returned by
+GnuTLS is greater than <option>tls_dh_max_bits</option> then the value will be clamped down
+to <option>tls_dh_max_bits</option>. The default value has been set at the current NSS
+limit, which is still much higher than Exim historically used.
+</para>
+<para>
+The filename and bits used will change as the GnuTLS maintainers change the
+value for their parameter <literal>GNUTLS_SEC_PARAM_NORMAL</literal>, as clamped by
+<option>tls_dh_max_bits</option>. At the time of writing (mid 2012), GnuTLS 2.12 recommends
+2432 bits, while NSS is limited to 2236 bits.
+</para>
+<para>
+In fact, the requested value will be *lower* than <option>tls_dh_max_bits</option>, to
+increase the chance of the generated prime actually being within acceptable
+bounds, as GnuTLS has been observed to overshoot. Note the check step in the
+procedure above. There is no sane procedure available to Exim to double-check
+the size of the generated prime, so it might still be too large.
+</para>
+</section>
+<section id="SECTreqciphssl">
+<title>Requiring specific ciphers in OpenSSL</title>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>requiring specific ciphers (OpenSSL)</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>tls_require_ciphers</option></primary>
+<secondary>OpenSSL</secondary>
+</indexterm>
+There is a function in the OpenSSL library that can be passed a list of cipher
+suites before the cipher negotiation takes place. This specifies which ciphers
+are acceptable for TLS versions prior to 1.3.
+The list is colon separated and may contain names like
+DES-CBC3-SHA. Exim passes the expanded value of <option>tls_require_ciphers</option>
+directly to this function call.
+Many systems will install the OpenSSL manual-pages, so you may have
+<emphasis>ciphers(1)</emphasis> available to you.
+The following quotation from the OpenSSL
+documentation specifies what forms of item are allowed in the cipher string:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+It can consist of a single cipher suite such as RC4-SHA.
+</para>
+</listitem>
+<listitem>
+<para>
+It can represent a list of cipher suites containing a certain algorithm,
+or cipher suites of a certain type. For example SHA1 represents all
+ciphers suites using the digest algorithm SHA1 and SSLv3 represents all
+SSL v3 algorithms.
+</para>
+</listitem>
+<listitem>
+<para>
+Lists of cipher suites can be combined in a single cipher string using
+the + character. This is used as a logical and operation. For example
+SHA1+DES represents all cipher suites containing the SHA1 and the DES
+algorithms.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Each cipher string can be optionally preceded by one of the characters <literal>!</literal>,
+<literal>-</literal> or <literal>+</literal>.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If <literal>!</literal> is used, the ciphers are permanently deleted from the list. The
+ciphers deleted can never reappear in the list even if they are explicitly
+stated.
+</para>
+</listitem>
+<listitem>
+<para>
+If <literal>-</literal> is used, the ciphers are deleted from the list, but some or all
+of the ciphers can be added again by later options.
+</para>
+</listitem>
+<listitem>
+<para>
+If <literal>+</literal> is used, the ciphers are moved to the end of the list. This
+option does not add any new ciphers; it just moves matching existing ones.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+If none of these characters is present, the string is interpreted as
+a list of ciphers to be appended to the current preference list. If the list
+includes any ciphers already present they will be ignored: that is, they will
+not be moved to the end of the list.
+</para>
+<para>
+The OpenSSL <emphasis>ciphers(1)</emphasis> command may be used to test the results of a given
+string:
+</para>
+<literallayout class="monospaced">
+# note single-quotes to get ! past any shell history expansion
+$ openssl ciphers 'HIGH:!MD5:!SHA1'
+</literallayout>
+<para>
+This example will let the library defaults be permitted on the MX port, where
+there’s probably no identity verification anyway, but ups the ante on the
+submission ports where the administrator might have some influence on the
+choice of clients used:
+</para>
+<literallayout class="monospaced">
+# OpenSSL variant; see man ciphers(1)
+tls_require_ciphers = ${if =={$received_port}{25}\
+ {DEFAULT}\
+ {HIGH:!MD5:!SHA1}}
+</literallayout>
+<para>
+This example will prefer ECDSA-authenticated ciphers over RSA ones:
+</para>
+<literallayout class="monospaced">
+tls_require_ciphers = ECDSA:RSA:!COMPLEMENTOFDEFAULT
+</literallayout>
+<para>
+For TLS version 1.3 the control available is less fine-grained
+and Exim does not provide access to it at present.
+The value of the <option>tls_require_ciphers</option> option is ignored when
+TLS version 1.3 is negotiated.
+</para>
+<para>
+As of writing the library default cipher suite list for TLSv1.3 is
+</para>
+<literallayout class="monospaced">
+TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
+</literallayout>
+</section>
+<section id="SECTreqciphgnu">
+<title>Requiring specific ciphers or other parameters in GnuTLS</title>
+<para>
+<indexterm role="concept">
+<primary>GnuTLS</primary>
+<secondary>specifying parameters for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>specifying ciphers (GnuTLS)</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>specifying key exchange methods (GnuTLS)</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>specifying MAC algorithms (GnuTLS)</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>specifying protocols (GnuTLS)</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>specifying priority string (GnuTLS)</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>tls_require_ciphers</option></primary>
+<secondary>GnuTLS</secondary>
+</indexterm>
+The GnuTLS library allows the caller to provide a "priority string", documented
+as part of the <function>gnutls_priority_init</function> function. This is very similar to the
+ciphersuite specification in OpenSSL.
+</para>
+<para>
+The <option>tls_require_ciphers</option> option is treated as the GnuTLS priority string
+and controls both protocols and ciphers.
+</para>
+<para>
+The <option>tls_require_ciphers</option> option is available both as an global option,
+controlling how Exim behaves as a server, and also as an option of the
+<command>smtp</command> transport, controlling how Exim behaves as a client. In both cases
+the value is string expanded. The resulting string is not an Exim list and
+the string is given to the GnuTLS library, so that Exim does not need to be
+aware of future feature enhancements of GnuTLS.
+</para>
+<para>
+Documentation of the strings accepted may be found in the GnuTLS manual, under
+"Priority strings". This is online as
+<emphasis role="bold"><ulink url="https://www.gnutls.org/manual/html_node/Priority-Strings.html">https://www.gnutls.org/manual/html_node/Priority-Strings.html</ulink></emphasis>,
+but beware that this relates to GnuTLS 3, which may be newer than the version
+installed on your system. If you are using GnuTLS 3,
+then the example code
+<emphasis role="bold"><ulink url="https://www.gnutls.org/manual/gnutls.html#Listing-the-ciphersuites-in-a-priority-string">https://www.gnutls.org/manual/gnutls.html#Listing-the-ciphersuites-in-a-priority-string</ulink></emphasis>
+on that site can be used to test a given string.
+</para>
+<para>
+For example:
+</para>
+<literallayout class="monospaced">
+# Disable older versions of protocols
+tls_require_ciphers = NORMAL:%LATEST_RECORD_VERSION:-VERS-SSL3.0
+</literallayout>
+<para>
+Prior to Exim 4.80, an older API of GnuTLS was used, and Exim supported three
+additional options, "<option>gnutls_require_kx</option>", "<option>gnutls_require_mac</option>" and
+"<option>gnutls_require_protocols</option>". <option>tls_require_ciphers</option> was an Exim list.
+</para>
+<para>
+This example will let the library defaults be permitted on the MX port, where
+there’s probably no identity verification anyway, and lowers security further
+by increasing compatibility; but this ups the ante on the submission ports
+where the administrator might have some influence on the choice of clients
+used:
+</para>
+<literallayout class="monospaced">
+# GnuTLS variant
+tls_require_ciphers = ${if =={$received_port}{25}\
+ {NORMAL:%COMPAT}\
+ {SECURE128}}
+</literallayout>
+</section>
+<section id="SECID182">
+<title>Configuring an Exim server to use TLS</title>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>configuring an Exim server</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>STARTTLS</secondary>
+</indexterm>
+When Exim has been built with TLS support, it advertises the availability of
+the STARTTLS command to client hosts that match <option>tls_advertise_hosts</option>,
+but not to any others. The default value of this option is *, which means
+that STARTTLS is always advertised. Set it to blank to never advertise;
+this is reasonable for systems that want to use TLS only as a client.
+</para>
+<para>
+If STARTTLS is to be used you
+need to set some other options in order to make TLS available.
+</para>
+<para>
+If a client issues a STARTTLS command and there is some configuration
+problem in the server, the command is rejected with a 454 error. If the client
+persists in trying to issue SMTP commands, all except QUIT are rejected
+with the error
+</para>
+<literallayout class="monospaced">
+554 Security failure
+</literallayout>
+<para>
+If a STARTTLS command is issued within an existing TLS session, it is
+rejected with a 554 error code.
+</para>
+<para>
+To enable TLS operations on a server, the <option>tls_advertise_hosts</option> option
+must be set to match some hosts. The default is * which matches all hosts.
+</para>
+<para>
+If this is all you do, TLS encryption will be enabled but not authentication -
+meaning that the peer has no assurance it is actually you he is talking to.
+You gain protection from a passive sniffer listening on the wire but not
+from someone able to intercept the communication.
+</para>
+<para>
+Further protection requires some further configuration at the server end.
+</para>
+<para>
+To make TLS work you need to set, in the server,
+</para>
+<literallayout class="monospaced">
+tls_certificate = /some/file/name
+tls_privatekey = /some/file/name
+</literallayout>
+<para>
+These options are, in fact, expanded strings, so you can make them depend on
+the identity of the client that is connected if you wish. The first file
+contains the server’s X509 certificate, and the second contains the private key
+that goes with it. These files need to be
+PEM format and readable by the Exim user, and must
+always be given as full path names.
+The key must not be password-protected.
+They can be the same file if both the
+certificate and the key are contained within it. If <option>tls_privatekey</option> is not
+set, or if its expansion is forced to fail or results in an empty string, this
+is assumed to be the case. The certificate file may also contain intermediate
+certificates that need to be sent to the client to enable it to authenticate
+the server’s certificate.
+</para>
+<para>
+For dual-stack (eg. RSA and ECDSA) configurations, these options can be
+colon-separated lists of file paths. Ciphers using given authentication
+algorithms require the presence of a suitable certificate to supply the
+public-key. The server selects among the certificates to present to the
+client depending on the selected cipher, hence the priority ordering for
+ciphers will affect which certificate is used.
+</para>
+<para>
+If you do not understand about certificates and keys, please try to find a
+source of this background information, which is not Exim-specific. (There are a
+few comments below in section <xref linkend="SECTcerandall"/>.)
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: These options do not apply when Exim is operating as a client –
+they apply only in the case of a server. If you need to use a certificate in an
+Exim client, you must set the options of the same names in an <command>smtp</command>
+transport.
+</para>
+<para>
+With just these options, an Exim server will be able to use TLS. It does not
+require the client to have a certificate (but see below for how to insist on
+this). There is one other option that may be needed in other situations. If
+</para>
+<literallayout class="monospaced">
+tls_dhparam = /some/file/name
+</literallayout>
+<para>
+is set, the SSL library is initialized for the use of Diffie-Hellman ciphers
+with the parameters contained in the file.
+Set this to <literal>none</literal> to disable use of DH entirely, by making no prime
+available:
+</para>
+<literallayout class="monospaced">
+tls_dhparam = none
+</literallayout>
+<para>
+This may also be set to a string identifying a standard prime to be used for
+DH; if it is set to <literal>default</literal> or, for OpenSSL, is unset, then the prime
+used is <literal>ike23</literal>. There are a few standard primes available, see the
+documentation for <option>tls_dhparam</option> for the complete list.
+</para>
+<para>
+See the command
+</para>
+<literallayout class="monospaced">
+openssl dhparam
+</literallayout>
+<para>
+for a way of generating file data.
+</para>
+<para>
+The strings supplied for these three options are expanded every time a client
+host connects. It is therefore possible to use different certificates and keys
+for different hosts, if you so wish, by making use of the client’s IP address
+in <varname>$sender_host_address</varname> to control the expansion. If a string expansion is
+forced to fail, Exim behaves as if the option is not set.
+</para>
+<para>
+<indexterm role="concept">
+<primary>cipher</primary>
+<secondary>logging</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>TLS cipher</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tls_in_cipher</varname></primary>
+</indexterm>
+The variable <varname>$tls_in_cipher</varname> is set to the cipher suite that was negotiated for
+an incoming TLS connection. It is included in the <emphasis>Received:</emphasis> header of an
+incoming message (by default – you can, of course, change this), and it is
+also included in the log line that records a message’s arrival, keyed by
+<quote>X=</quote>, unless the <option>tls_cipher</option> log selector is turned off. The <option>encrypted</option>
+condition can be used to test for specific cipher suites in ACLs.
+</para>
+<para>
+Once TLS has been established, the ACLs that run for subsequent SMTP commands
+can check the name of the cipher suite and vary their actions accordingly. The
+cipher suite names vary, depending on which TLS library is being used. For
+example, OpenSSL uses the name DES-CBC3-SHA for the cipher suite which in other
+contexts is known as TLS_RSA_WITH_3DES_EDE_CBC_SHA. Check the OpenSSL or GnuTLS
+documentation for more details.
+</para>
+<para>
+For outgoing SMTP deliveries, <varname>$tls_out_cipher</varname> is used and logged
+(again depending on the <option>tls_cipher</option> log selector).
+</para>
+</section>
+<section id="SECID183">
+<title>Requesting and verifying client certificates</title>
+<para>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>verification of client</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>client certificate verification</secondary>
+</indexterm>
+If you want an Exim server to request a certificate when negotiating a TLS
+session with a client, you must set either <option>tls_verify_hosts</option> or
+<option>tls_try_verify_hosts</option>. You can, of course, set either of them to * to
+apply to all TLS connections. For any host that matches one of these options,
+Exim requests a certificate as part of the setup of the TLS session. The
+contents of the certificate are verified by comparing it with a list of
+expected trust-anchors or certificates.
+These may be the system default set (depending on library version),
+an explicit file or,
+depending on library version, a directory, identified by
+<option>tls_verify_certificates</option>.
+</para>
+<para>
+A file can contain multiple certificates, concatenated end to end. If a
+directory is used
+(OpenSSL only),
+each certificate must be in a separate file, with a name (or a symbolic link)
+of the form <<emphasis>hash</emphasis>>.0, where <<emphasis>hash</emphasis>> is a hash value constructed from the
+certificate. You can compute the relevant hash by running the command
+</para>
+<literallayout class="monospaced">
+openssl x509 -hash -noout -in /cert/file
+</literallayout>
+<para>
+where <filename>/cert/file</filename> contains a single certificate.
+</para>
+<para>
+There is no checking of names of the client against the certificate
+Subject Name or Subject Alternate Names.
+</para>
+<para>
+The difference between <option>tls_verify_hosts</option> and <option>tls_try_verify_hosts</option> is
+what happens if the client does not supply a certificate, or if the certificate
+does not match any of the certificates in the collection named by
+<option>tls_verify_certificates</option>. If the client matches <option>tls_verify_hosts</option>, the
+attempt to set up a TLS session is aborted, and the incoming connection is
+dropped. If the client matches <option>tls_try_verify_hosts</option>, the (encrypted) SMTP
+session continues. ACLs that run for subsequent SMTP commands can detect the
+fact that no certificate was verified, and vary their actions accordingly. For
+example, you can insist on a certificate before accepting a message for
+relaying, but not when the message is destined for local delivery.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_in_peerdn</varname></primary>
+</indexterm>
+When a client supplies a certificate (whether it verifies or not), the value of
+the Distinguished Name of the certificate is made available in the variable
+<varname>$tls_in_peerdn</varname> during subsequent processing of the message.
+</para>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>distinguished name</secondary>
+</indexterm>
+Because it is often a long text string, it is not included in the log line or
+<emphasis>Received:</emphasis> header by default. You can arrange for it to be logged, keyed by
+<quote>DN=</quote>, by setting the <option>tls_peerdn</option> log selector, and you can use
+<option>received_header_text</option> to change the <emphasis>Received:</emphasis> header. When no
+certificate is supplied, <varname>$tls_in_peerdn</varname> is empty.
+</para>
+</section>
+<section id="SECID184">
+<title>Revoked certificates</title>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>revoked certificates</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>revocation list</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>revocation list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>OCSP</primary>
+<secondary>stapling</secondary>
+</indexterm>
+Certificate issuing authorities issue Certificate Revocation Lists (CRLs) when
+certificates are revoked. If you have such a list, you can pass it to an Exim
+server using the global option called <option>tls_crl</option> and to an Exim client using
+an identically named option for the <command>smtp</command> transport. In each case, the value
+of the option is expanded and must then be the name of a file that contains a
+CRL in PEM format.
+The downside is that clients have to periodically re-download a potentially huge
+file from every certificate authority they know of.
+</para>
+<para>
+The way with most moving parts at query time is Online Certificate
+Status Protocol (OCSP), where the client verifies the certificate
+against an OCSP server run by the CA. This lets the CA track all
+usage of the certs. It requires running software with access to the
+private key of the CA, to sign the responses to the OCSP queries. OCSP
+is based on HTTP and can be proxied accordingly.
+</para>
+<para>
+The only widespread OCSP server implementation (known to this writer)
+comes as part of OpenSSL and aborts on an invalid request, such as
+connecting to the port and then disconnecting. This requires
+re-entering the passphrase each time some random client does this.
+</para>
+<para>
+The third way is OCSP Stapling; in this, the server using a certificate
+issued by the CA periodically requests an OCSP proof of validity from
+the OCSP server, then serves it up inline as part of the TLS
+negotiation. This approach adds no extra round trips, does not let the
+CA track users, scales well with number of certs issued by the CA and is
+resilient to temporary OCSP server failures, as long as the server
+starts retrying to fetch an OCSP proof some time before its current
+proof expires. The downside is that it requires server support.
+</para>
+<para>
+Unless Exim is built with the support disabled,
+or with GnuTLS earlier than version 3.3.16 / 3.4.8
+support for OCSP stapling is included.
+</para>
+<para>
+There is a global option called <option>tls_ocsp_file</option>.
+The file specified therein is expected to be in DER format, and contain
+an OCSP proof. Exim will serve it as part of the TLS handshake. This
+option will be re-expanded for SNI, if the <option>tls_certificate</option> option
+contains <literal>tls_in_sni</literal>, as per other TLS options.
+</para>
+<para>
+Exim does not at this time implement any support for fetching a new OCSP
+proof. The burden is on the administrator to handle this, outside of
+Exim. The file specified should be replaced atomically, so that the
+contents are always valid. Exim will expand the <option>tls_ocsp_file</option> option
+on each connection, so a new file will be handled transparently on the
+next connection.
+</para>
+<para>
+When built with OpenSSL Exim will check for a valid next update timestamp
+in the OCSP proof; if not present, or if the proof has expired, it will be
+ignored.
+</para>
+<para>
+For the client to be able to verify the stapled OCSP the server must
+also supply, in its stapled information, any intermediate
+certificates for the chain leading to the OCSP proof from the signer
+of the server certificate. There may be zero or one such. These
+intermediate certificates should be added to the server OCSP stapling
+file named by <option>tls_ocsp_file</option>.
+</para>
+<para>
+Note that the proof only covers the terminal server certificate,
+not any of the chain from CA to it.
+</para>
+<para>
+There is no current way to staple a proof for a client certificate.
+</para>
+<literallayout class="monospaced">
+ A helper script "ocsp_fetch.pl" for fetching a proof from a CA
+ OCSP server is supplied. The server URL may be included in the
+ server certificate, if the CA is helpful.
+
+ One failure mode seen was the OCSP Signer cert expiring before the end
+ of validity of the OCSP proof. The checking done by Exim/OpenSSL
+ noted this as invalid overall, but the re-fetch script did not.
+</literallayout>
+</section>
+<section id="SECTclientTLS">
+<title>Configuring an Exim client to use TLS</title>
+<para>
+<indexterm role="concept">
+<primary>cipher</primary>
+<secondary>logging</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>TLS cipher</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>distinguished name</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>configuring an Exim client</secondary>
+</indexterm>
+The <option>tls_cipher</option> and <option>tls_peerdn</option> log selectors apply to outgoing SMTP
+deliveries as well as to incoming, the latter one causing logging of the
+server certificate’s DN. The remaining client configuration for TLS is all
+within the <command>smtp</command> transport.
+</para>
+<para>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>STARTTLS</secondary>
+</indexterm>
+It is not necessary to set any options to have TLS work in the <command>smtp</command>
+transport. If Exim is built with TLS support, and TLS is advertised by a
+server, the <command>smtp</command> transport always tries to start a TLS session. However,
+this can be prevented by setting <option>hosts_avoid_tls</option> (an option of the
+transport) to a list of server hosts for which TLS should not be used.
+</para>
+<para>
+If you do not want Exim to attempt to send messages unencrypted when an attempt
+to set up an encrypted connection fails in any way, you can set
+<option>hosts_require_tls</option> to a list of hosts for which encryption is mandatory. For
+those hosts, delivery is always deferred if an encrypted connection cannot be
+set up. If there are any other hosts for the address, they are tried in the
+usual way.
+</para>
+<para>
+When the server host is not in <option>hosts_require_tls</option>, Exim may try to deliver
+the message unencrypted. It always does this if the response to STARTTLS is
+a 5<emphasis>xx</emphasis> code. For a temporary error code, or for a failure to negotiate a TLS
+session after a success response code, what happens is controlled by the
+<option>tls_tempfail_tryclear</option> option of the <command>smtp</command> transport. If it is false,
+delivery to this host is deferred, and other hosts (if available) are tried. If
+it is true, Exim attempts to deliver unencrypted after a 4<emphasis>xx</emphasis> response to
+STARTTLS, and if STARTTLS is accepted, but the subsequent TLS
+negotiation fails, Exim closes the current connection (because it is in an
+unknown state), opens a new one to the same host, and then tries the delivery
+unencrypted.
+</para>
+<para>
+The <option>tls_certificate</option> and <option>tls_privatekey</option> options of the <command>smtp</command>
+transport provide the client with a certificate, which is passed to the server
+if it requests it. If the server is Exim, it will request a certificate only if
+<option>tls_verify_hosts</option> or <option>tls_try_verify_hosts</option> matches the client.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: Do not use a certificate which has the OCSP-must-staple extension,
+for client use (they are usable for server use).
+As the TLS protocol has no means for the client to staple before TLS 1.3 it will result
+in failed connections.
+</para>
+<para>
+If the <option>tls_verify_certificates</option> option is set on the <command>smtp</command> transport, it
+specifies a collection of expected server certificates.
+These may be
+the system default set (depending on library version),
+a file,
+or (depending on library version) a directory.
+The client verifies the server’s certificate
+against this collection, taking into account any revoked certificates that are
+in the list defined by <option>tls_crl</option>.
+Failure to verify fails the TLS connection unless either of the
+<option>tls_verify_hosts</option> or <option>tls_try_verify_hosts</option> options are set.
+</para>
+<para>
+The <option>tls_verify_hosts</option> and <option>tls_try_verify_hosts</option> options restrict
+certificate verification to the listed servers. Verification either must
+or need not succeed respectively.
+</para>
+<para>
+The <option>tls_verify_cert_hostnames</option> option lists hosts for which additional
+checks are made: that the host name (the one in the DNS A record)
+is valid for the certificate.
+The option defaults to always checking.
+</para>
+<para>
+The <command>smtp</command> transport has two OCSP-related options:
+<option>hosts_require_ocsp</option>; a host-list for which a Certificate Status
+is requested and required for the connection to proceed. The default
+value is empty.
+<option>hosts_request_ocsp</option>; a host-list for which (additionally)
+a Certificate Status is requested (but not necessarily verified). The default
+value is "*" meaning that requests are made unless configured
+otherwise.
+</para>
+<para>
+The host(s) should also be in <option>hosts_require_tls</option>, and
+<option>tls_verify_certificates</option> configured for the transport,
+for OCSP to be relevant.
+</para>
+<para>
+If
+<option>tls_require_ciphers</option> is set on the <command>smtp</command> transport, it must contain a
+list of permitted cipher suites. If either of these checks fails, delivery to
+the current host is abandoned, and the <command>smtp</command> transport tries to deliver to
+alternative hosts, if any.
+</para>
+<para>
+ <emphasis role="bold">Note</emphasis>:
+These options must be set in the <command>smtp</command> transport for Exim to use TLS when it
+is operating as a client. Exim does not assume that a server certificate (set
+by the global options of the same name) should also be used when operating as a
+client.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$host_address</varname></primary>
+</indexterm>
+All the TLS options in the <command>smtp</command> transport are expanded before use, with
+<varname>$host</varname> and <varname>$host_address</varname> containing the name and address of the server to
+which the client is connected. Forced failure of an expansion causes Exim to
+behave as if the relevant option were unset.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$tls_out_bits</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tls_out_cipher</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tls_out_peerdn</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tls_out_sni</varname></primary>
+</indexterm>
+Before an SMTP connection is established, the
+<varname>$tls_out_bits</varname>, <varname>$tls_out_cipher</varname>, <varname>$tls_out_peerdn</varname> and <varname>$tls_out_sni</varname>
+variables are emptied. (Until the first connection, they contain the values
+that were set when the message was received.) If STARTTLS is subsequently
+successfully obeyed, these variables are set to the relevant values for the
+outgoing connection.
+</para>
+</section>
+<section id="SECTtlssni">
+<title>Use of TLS Server Name Indication</title>
+<para>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>Server Name Indication</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$tls_in_sni</varname></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>tls_in_sni</option></primary>
+</indexterm>
+With TLS1.0 or above, there is an extension mechanism by which extra
+information can be included at various points in the protocol. One of these
+extensions, documented in RFC 6066 (and before that RFC 4366) is
+<quote>Server Name Indication</quote>, commonly <quote>SNI</quote>. This extension is sent by the
+client in the initial handshake, so that the server can examine the servername
+within and possibly choose to use different certificates and keys (and more)
+for this session.
+</para>
+<para>
+This is analogous to HTTP’s <quote>Host:</quote> header, and is the main mechanism by
+which HTTPS-enabled web-sites can be virtual-hosted, many sites to one IP
+address.
+</para>
+<para>
+With SMTP to MX, there are the same problems here as in choosing the identity
+against which to validate a certificate: you can’t rely on insecure DNS to
+provide the identity which you then cryptographically verify. So this will
+be of limited use in that environment.
+</para>
+<para>
+With SMTP to Submission, there is a well-defined hostname which clients are
+connecting to and can validate certificates against. Thus clients <emphasis role="bold">can</emphasis>
+choose to include this information in the TLS negotiation. If this becomes
+wide-spread, then hosters can choose to present different certificates to
+different clients. Or even negotiate different cipher suites.
+</para>
+<para>
+The <option>tls_sni</option> option on an SMTP transport is an expanded string; the result,
+if not empty, will be sent on a TLS session as part of the handshake. There’s
+nothing more to it. Choosing a sensible value not derived insecurely is the
+only point of caution. The <varname>$tls_out_sni</varname> variable will be set to this string
+for the lifetime of the client connection (including during authentication).
+</para>
+<para>
+Except during SMTP client sessions, if <varname>$tls_in_sni</varname> is set then it is a string
+received from a client.
+It can be logged with the <option>log_selector</option> item <literal>+tls_sni</literal>.
+</para>
+<para>
+If the string <literal>tls_in_sni</literal> appears in the main section’s <option>tls_certificate</option>
+option (prior to expansion) then the following options will be re-expanded
+during TLS session handshake, to permit alternative values to be chosen:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<option>tls_certificate</option>
+</para>
+</listitem>
+<listitem>
+<para>
+<option>tls_crl</option>
+</para>
+</listitem>
+<listitem>
+<para>
+<option>tls_privatekey</option>
+</para>
+</listitem>
+<listitem>
+<para>
+<option>tls_verify_certificates</option>
+</para>
+</listitem>
+<listitem>
+<para>
+<option>tls_ocsp_file</option>
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Great care should be taken to deal with matters of case, various injection
+attacks in the string (<literal>../</literal> or SQL), and ensuring that a valid filename
+can always be referenced; it is important to remember that <varname>$tls_in_sni</varname> is
+arbitrary unverified data provided prior to authentication.
+Further, the initial certificate is loaded before SNI has arrived, so
+an expansion for <option>tls_certificate</option> must have a default which is used
+when <varname>$tls_in_sni</varname> is empty.
+</para>
+<para>
+The Exim developers are proceeding cautiously and so far no other TLS options
+are re-expanded.
+</para>
+<para>
+When Exim is built against OpenSSL, OpenSSL must have been built with support
+for TLS Extensions. This holds true for OpenSSL 1.0.0+ and 0.9.8+ with
+enable-tlsext in EXTRACONFIGURE. If you invoke <command>openssl s_client -h</command> and
+see <literal>-servername</literal> in the output, then OpenSSL has support.
+</para>
+<para>
+When Exim is built against GnuTLS, SNI support is available as of GnuTLS
+0.5.10. (Its presence predates the current API which Exim uses, so if Exim
+built, then you have SNI support).
+</para>
+</section>
+<section id="SECTmulmessam">
+<title>Multiple messages on the same encrypted TCP/IP connection</title>
+<para>
+<indexterm role="concept">
+<primary>multiple SMTP deliveries with TLS</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>multiple message deliveries</secondary>
+</indexterm>
+Exim sends multiple messages down the same TCP/IP connection by starting up
+an entirely new delivery process for each message, passing the socket from
+one process to the next. This implementation does not fit well with the use
+of TLS, because there is quite a lot of state information associated with a TLS
+connection, not just a socket identification. Passing all the state information
+to a new process is not feasible. Consequently, for sending using TLS Exim
+starts an additional proxy process for handling the encryption, piping the
+unencrypted data stream from and to the delivery processes.
+</para>
+<para>
+An older mode of operation can be enabled on a per-host basis by the
+<option>hosts_noproxy_tls</option> option on the <command>smtp</command> transport. If the host matches
+this list the proxy process described above is not used; instead Exim
+shuts down an existing TLS session being run by the delivery process
+before passing the socket to a new process. The new process may then
+try to start a new TLS session, and if successful, may try to re-authenticate
+if AUTH is in use, before sending the next message.
+</para>
+<para>
+The RFC is not clear as to whether or not an SMTP session continues in clear
+after TLS has been shut down, or whether TLS may be restarted again later, as
+just described. However, if the server is Exim, this shutdown and
+reinitialization works. It is not known which (if any) other servers operate
+successfully if the client closes a TLS session and continues with unencrypted
+SMTP, but there are certainly some that do not work. For such servers, Exim
+should not pass the socket to another process, because the failure of the
+subsequent attempt to use it would cause Exim to record a temporary host error,
+and delay other deliveries to that host.
+</para>
+<para>
+To test for this case, Exim sends an EHLO command to the server after
+closing down the TLS session. If this fails in any way, the connection is
+closed instead of being passed to a new delivery process, but no retry
+information is recorded.
+</para>
+<para>
+There is also a manual override; you can set <option>hosts_nopass_tls</option> on the
+<command>smtp</command> transport to match those hosts for which Exim should not pass
+connections to new processes if TLS has been used.
+</para>
+</section>
+<section id="SECTcerandall">
+<title>Certificates and all that</title>
+<para>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>references to discussion</secondary>
+</indexterm>
+In order to understand fully how TLS works, you need to know about
+certificates, certificate signing, and certificate authorities.
+This is a large topic and an introductory guide is unsuitable for the Exim
+reference manual, so instead we provide pointers to existing documentation.
+</para>
+<para>
+The Apache web-server was for a long time the canonical guide, so their
+documentation is a good place to start; their SSL module’s Introduction
+document is currently at
+</para>
+<literallayout>
+<emphasis role="bold"><ulink url="https://httpd.apache.org/docs/current/ssl/ssl_intro.html">https://httpd.apache.org/docs/current/ssl/ssl_intro.html</ulink></emphasis>
+</literallayout>
+<para>
+and their FAQ is at
+</para>
+<literallayout>
+<emphasis role="bold"><ulink url="https://httpd.apache.org/docs/current/ssl/ssl_faq.html">https://httpd.apache.org/docs/current/ssl/ssl_faq.html</ulink></emphasis>
+</literallayout>
+<para>
+Eric Rescorla’s book, <emphasis>SSL and TLS</emphasis>, published by Addison-Wesley (ISBN
+0-201-61598-3) in 2001, contains both introductory and more in-depth
+descriptions.
+More recently Ivan Ristić’s book <emphasis>Bulletproof SSL and TLS</emphasis>,
+published by Feisty Duck (ISBN 978-1907117046) in 2013 is good.
+Ivan is the author of the popular TLS testing tools at
+<emphasis role="bold"><ulink url="https://www.ssllabs.com/">https://www.ssllabs.com/</ulink></emphasis>.
+</para>
+</section>
+<section id="SECID186">
+<title>Certificate chains</title>
+<para>
+The file named by <option>tls_certificate</option> may contain more than one
+certificate. This is useful in the case where the certificate that is being
+sent is validated by an intermediate certificate which the other end does
+not have. Multiple certificates must be in the correct order in the file.
+First the host’s certificate itself, then the first intermediate
+certificate to validate the issuer of the host certificate, then the next
+intermediate certificate to validate the issuer of the first intermediate
+certificate, and so on, until finally (optionally) the root certificate.
+The root certificate must already be trusted by the recipient for
+validation to succeed, of course, but if it’s not preinstalled, sending the
+root certificate along with the rest makes it available for the user to
+install if the receiving end is a client MUA that can interact with a user.
+</para>
+<para>
+Note that certificates using MD5 are unlikely to work on today’s Internet;
+even if your libraries allow loading them for use in Exim when acting as a
+server, increasingly clients will not accept such certificates. The error
+diagnostics in such a case can be frustratingly vague.
+</para>
+</section>
+<section id="SECID187">
+<title>Self-signed certificates</title>
+<para>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>self-signed</secondary>
+</indexterm>
+You can create a self-signed certificate using the <emphasis>req</emphasis> command provided
+with OpenSSL, like this:
+</para>
+<literallayout class="monospaced">
+openssl req -x509 -newkey rsa:1024 -keyout file1 -out file2 \
+ -days 9999 -nodes
+</literallayout>
+<para>
+<filename>file1</filename> and <filename>file2</filename> can be the same file; the key and the certificate are
+delimited and so can be identified independently. The <option>-days</option> option
+specifies a period for which the certificate is valid. The <option>-nodes</option> option is
+important: if you do not set it, the key is encrypted with a passphrase
+that you are prompted for, and any use that is made of the key causes more
+prompting for the passphrase. This is not helpful if you are going to use
+this certificate and key in an MTA, where prompting is not possible.
+</para>
+<para>
+NB: we are now past the point where 9999 days takes us past the 32-bit Unix
+epoch. If your system uses unsigned time_t (most do) and is 32-bit, then
+the above command might produce a date in the past. Think carefully about
+the lifetime of the systems you’re deploying, and either reduce the duration
+of the certificate or reconsider your platform deployment. (At time of
+writing, reducing the duration is the most likely choice, but the inexorable
+progression of time takes us steadily towards an era where this will not
+be a sensible resolution).
+</para>
+<para>
+A self-signed certificate made in this way is sufficient for testing, and
+may be adequate for all your requirements if you are mainly interested in
+encrypting transfers, and not in secure identification.
+</para>
+<para>
+However, many clients require that the certificate presented by the server be a
+user (also called <quote>leaf</quote> or <quote>site</quote>) certificate, and not a self-signed
+certificate. In this situation, the self-signed certificate described above
+must be installed on the client host as a trusted root <emphasis>certification
+authority</emphasis> (CA), and the certificate used by Exim must be a user certificate
+signed with that self-signed certificate.
+</para>
+<para>
+For information on creating self-signed CA certificates and using them to sign
+user certificates, see the <emphasis>General implementation overview</emphasis> chapter of the
+Open-source PKI book, available online at
+<emphasis role="bold"><ulink url="https://sourceforge.net/projects/ospkibook/">https://sourceforge.net/projects/ospkibook/</ulink></emphasis>.
+<indexterm role="concept" startref="IIDencsmtp1" class="endofrange"/>
+<indexterm role="concept" startref="IIDencsmtp2" class="endofrange"/>
+</para>
+</section>
+<section id="SECDANE">
+<title>DANE</title>
+<para>
+<indexterm role="concept">
+<primary>DANE</primary>
+</indexterm>
+DNS-based Authentication of Named Entities, as applied to SMTP over TLS, provides assurance to a client that
+it is actually talking to the server it wants to rather than some attacker operating a Man In The Middle (MITM)
+operation. The latter can terminate the TLS connection you make, and make another one to the server (so both
+you and the server still think you have an encrypted connection) and, if one of the "well known" set of
+Certificate Authorities has been suborned - something which *has* been seen already (2014), a verifiable
+certificate (if you’re using normal root CAs, eg. the Mozilla set, as your trust anchors).
+</para>
+<para>
+What DANE does is replace the CAs with the DNS as the trust anchor. The assurance is limited to a) the possibility
+that the DNS has been suborned, b) mistakes made by the admins of the target server. The attack surface presented
+by (a) is thought to be smaller than that of the set of root CAs.
+</para>
+<para>
+It also allows the server to declare (implicitly) that connections to it should use TLS. An MITM could simply
+fail to pass on a server’s STARTTLS.
+</para>
+<para>
+DANE scales better than having to maintain (and side-channel communicate) copies of server certificates
+for every possible target server. It also scales (slightly) better than having to maintain on an SMTP
+client a copy of the standard CAs bundle. It also means not having to pay a CA for certificates.
+</para>
+<para>
+DANE requires a server operator to do three things: 1) run DNSSEC. This provides assurance to clients
+that DNS lookups they do for the server have not been tampered with. The domain MX record applying
+to this server, its A record, its TLSA record and any associated CNAME records must all be covered by
+DNSSEC.
+2) add TLSA DNS records. These say what the server certificate for a TLS connection should be.
+3) offer a server certificate, or certificate chain, in TLS connections which is is anchored by one of the TLSA records.
+</para>
+<para>
+There are no changes to Exim specific to server-side operation of DANE.
+Support for client-side operation of DANE can be included at compile time by defining SUPPORT_DANE=yes
+in <filename>Local/Makefile</filename>.
+If it has been included, the macro "_HAVE_DANE" will be defined.
+</para>
+<para>
+A TLSA record consist of 4 fields, the "Certificate Usage", the
+"Selector", the "Matching type", and the "Certificate Association Data".
+For a detailed description of the TLSA record see
+<emphasis role="bold"><ulink url="https://tools.ietf.org/html/rfc7671#page-5">RFC 7671</ulink></emphasis>.
+</para>
+<para>
+The TLSA record for the server may have "Certificate Usage" (1st) field of DANE-TA(2) or DANE-EE(3).
+These are the "Trust Anchor" and "End Entity" variants.
+The latter specifies the End Entity directly, i.e. the certificate involved is that of the server
+(and if only DANE-EE is used then it should be the sole one transmitted during the TLS handshake);
+this is appropriate for a single system, using a self-signed certificate.
+DANE-TA usage is effectively declaring a specific CA to be used; this might be a private CA or a public,
+well-known one.
+A private CA at simplest is just a self-signed certificate (with certain
+attributes) which is used to sign server certificates, but running one securely
+does require careful arrangement.
+With DANE-TA, as implemented in Exim and commonly in other MTAs,
+the server TLS handshake must transmit the entire certificate chain from CA to server-certificate.
+DANE-TA is commonly used for several services and/or servers, each having a TLSA query-domain CNAME record,
+all of which point to a single TLSA record.
+DANE-TA and DANE-EE can both be used together.
+</para>
+<para>
+Our recommendation is to use DANE with a certificate from a public CA,
+because this enables a variety of strategies for remote clients to verify
+your certificate.
+You can then publish information both via DANE and another technology,
+"MTA-STS", described below.
+</para>
+<para>
+When you use DANE-TA to publish trust anchor information, you ask entities
+outside your administrative control to trust the Certificate Authority for
+connections to you.
+If using a private CA then you should expect others to still apply the
+technical criteria they’d use for a public CA to your certificates.
+In particular, you should probably try to follow current best practices for CA
+operation around hash algorithms and key sizes.
+Do not expect other organizations to lower their security expectations just
+because a particular profile might be reasonable for your own internal use.
+</para>
+<para>
+When this text was last updated, this in practice means to avoid use of SHA-1
+and MD5; if using RSA to use key sizes of at least 2048 bits (and no larger
+than 4096, for interoperability); to use keyUsage fields correctly; to use
+random serial numbers.
+The list of requirements is subject to change as best practices evolve.
+If you’re not already using a private CA, or it doesn’t meet these
+requirements, then we encourage you to avoid all these issues and use a public
+CA such as <emphasis role="bold"><ulink url="https://letsencrypt.org/">Let’s Encrypt</ulink></emphasis> instead.
+</para>
+<para>
+The TLSA record should have a "Selector" (2nd) field of SPKI(1) and
+a "Matching Type" (3rd) field of SHA2-512(2).
+</para>
+<para>
+For the "Certificate Authority Data" (4th) field, commands like
+</para>
+<literallayout class="monospaced">
+ openssl x509 -pubkey -noout <certificate.pem \
+ | openssl rsa -outform der -pubin 2>/dev/null \
+ | openssl sha512 \
+ | awk '{print $2}'
+</literallayout>
+<para>
+are workable to create a hash of the certificate’s public key.
+</para>
+<para>
+An example TLSA record for DANE-EE(3), SPKI(1), and SHA-512 (2) looks like
+</para>
+<literallayout class="monospaced">
+ _25._tcp.mail.example.com. TLSA 3 1 2 8BA8A336E...
+</literallayout>
+<para>
+At the time of writing, <emphasis role="bold"><ulink url="https://www.huque.com/bin/gen_tlsa">https://www.huque.com/bin/gen_tlsa</ulink></emphasis>
+is useful for quickly generating TLSA records.
+</para>
+<para>
+For use with the DANE-TA model, server certificates must have a correct name (SubjectName or SubjectAltName).
+</para>
+<para>
+The Certificate issued by the CA published in the DANE-TA model should be
+issued using a strong hash algorithm.
+Exim, and importantly various other MTAs sending to you, will not
+re-enable hash algorithms which have been disabled by default in TLS
+libraries.
+This means no MD5 and no SHA-1. SHA2-256 is the minimum for reliable
+interoperability (and probably the maximum too, in 2018).
+</para>
+<para>
+The use of OCSP-stapling should be considered, allowing for fast revocation of certificates (which would otherwise
+be limited by the DNS TTL on the TLSA records). However, this is likely to only be usable with DANE-TA. NOTE: the
+default of requesting OCSP for all hosts is modified iff DANE is in use, to:
+</para>
+<literallayout class="monospaced">
+ hosts_request_ocsp = ${if or { {= {0}{$tls_out_tlsa_usage}} \
+ {= {4}{$tls_out_tlsa_usage}} } \
+ {*}{}}
+</literallayout>
+<para>
+The (new) variable <varname>$tls_out_tlsa_usage</varname> is a bitfield with numbered bits set for TLSA record usage codes.
+The zero above means DANE was not in use, the four means that only DANE-TA usage TLSA records were
+found. If the definition of <option>hosts_request_ocsp</option> includes the
+string "tls_out_tlsa_usage", they are re-expanded in time to
+control the OCSP request.
+</para>
+<para>
+This modification of hosts_request_ocsp is only done if it has the default value of "*". Admins who change it, and
+those who use <option>hosts_require_ocsp</option>, should consider the interaction with DANE in their OCSP settings.
+</para>
+<para>
+For client-side DANE there are three new smtp transport options, <option>hosts_try_dane</option>, <option>hosts_require_dane</option>
+and <option>dane_require_tls_ciphers</option>.
+The <quote>require</quote> variant will result in failure if the target host is not
+DNSSEC-secured. To get DNSSEC-secured hostname resolution, use
+the <option>dnssec_request_domains</option> router or transport option.
+</para>
+<para>
+DANE will only be usable if the target host has DNSSEC-secured MX, A and TLSA records.
+</para>
+<para>
+A TLSA lookup will be done if either of the above options match and the host-lookup succeeded using dnssec.
+If a TLSA lookup is done and succeeds, a DANE-verified TLS connection
+will be required for the host. If it does not, the host will not
+be used; there is no fallback to non-DANE or non-TLS.
+</para>
+<para>
+If DANE is requested and usable, then the TLS cipher list configuration
+prefers to use the option <option>dane_require_tls_ciphers</option> and falls
+back to <option>tls_require_ciphers</option> only if that is unset.
+This lets you configure "decent crypto" for DANE and "better than nothing
+crypto" as the default. Note though that while GnuTLS lets the string control
+which versions of TLS/SSL will be negotiated, OpenSSL does not and you’re
+limited to ciphersuite constraints.
+</para>
+<para>
+If DANE is requested and useable (see above) the following transport options are ignored:
+</para>
+<literallayout class="monospaced">
+ hosts_require_tls
+ tls_verify_hosts
+ tls_try_verify_hosts
+ tls_verify_certificates
+ tls_crl
+ tls_verify_cert_hostnames
+</literallayout>
+<para>
+If DANE is not usable, whether requested or not, and CA-anchored
+verification evaluation is wanted, the above variables should be set appropriately.
+</para>
+<para>
+The router and transport option <option>dnssec_request_domains</option> must not be
+set to <quote>never</quote>, and <option>dnssec_require_domains</option> is ignored.
+</para>
+<para>
+If verification was successful using DANE then the "CV" item in the delivery log line will show as "CV=dane".
+</para>
+<para>
+There is a new variable <varname>$tls_out_dane</varname> which will have "yes" if
+verification succeeded using DANE and "no" otherwise (only useful
+in combination with events; see <xref linkend="CHAPevents"/>),
+and a new variable <varname>$tls_out_tlsa_usage</varname> (detailed above).
+</para>
+<para>
+<indexterm role="concept">
+<primary>DANE</primary>
+<secondary>reporting</secondary>
+</indexterm>
+An event (see <xref linkend="CHAPevents"/>) of type "dane:fail" will be raised on failures
+to achieve DANE-verified connection, if one was either requested and offered, or
+required. This is intended to support TLS-reporting as defined in
+<emphasis role="bold"><ulink url="https://tools.ietf.org/html/draft-ietf-uta-smtp-tlsrpt-17">https://tools.ietf.org/html/draft-ietf-uta-smtp-tlsrpt-17</ulink></emphasis>.
+The <varname>$event_data</varname> will be one of the Result Types defined in
+Section 4.3 of that document.
+</para>
+<para>
+Under GnuTLS, DANE is only supported from version 3.0.0 onwards.
+</para>
+<para>
+DANE is specified in published RFCs and decouples certificate authority trust
+selection from a "race to the bottom" of "you must trust everything for mail
+to get through". There is an alternative technology called MTA-STS, which
+instead publishes MX trust anchor information on an HTTPS website. At the
+time this text was last updated, MTA-STS was still a draft, not yet an RFC.
+Exim has no support for MTA-STS as a client, but Exim mail server operators
+can choose to publish information describing their TLS configuration using
+MTA-STS to let those clients who do use that protocol derive trust
+information.
+</para>
+<para>
+The MTA-STS design requires a certificate from a public Certificate Authority
+which is recognized by clients sending to you.
+That selection of which CAs are trusted by others is outside your control.
+</para>
+<para>
+The most interoperable course of action is probably to use
+<emphasis role="bold"><ulink url="https://letsencrypt.org/">Let’s Encrypt</ulink></emphasis>, with automated certificate
+renewal; to publish the anchor information in DNSSEC-secured DNS via TLSA
+records for DANE clients (such as Exim and Postfix) and to publish anchor
+information for MTA-STS as well. This is what is done for the <emphasis>exim.org</emphasis>
+domain itself (with caveats around occasionally broken MTA-STS because of
+incompatible specification changes prior to reaching RFC status).
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPACL">
+<title>Access control lists</title>
+<para>
+<indexterm role="concept" id="IIDacl" class="startofrange">
+<primary>access control lists (ACLs)</primary>
+<secondary>description</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>control of incoming mail</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>controlling incoming</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>policy control</primary>
+<secondary>access control lists</secondary>
+</indexterm>
+Access Control Lists (ACLs) are defined in a separate section of the runtime
+configuration file, headed by <quote>begin acl</quote>. Each ACL definition starts with a
+name, terminated by a colon. Here is a complete ACL section that contains just
+one very small ACL:
+</para>
+<literallayout class="monospaced">
+begin acl
+small_acl:
+ accept hosts = one.host.only
+</literallayout>
+<para>
+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.
+</para>
+<para>
+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 <option>-bs</option>
+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
+<xref linkend="CHAPdefconfil"/>.
+</para>
+<section id="SECID188">
+<title>Testing ACLs</title>
+<para>
+The <option>-bh</option> command line option provides a way of testing your ACL
+configuration locally by running a fake SMTP session with which you interact.
+</para>
+</section>
+<section id="SECID189">
+<title>Specifying when ACLs are used</title>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>options for specifying</secondary>
+</indexterm>
+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:
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DATA</primary>
+<secondary>ACLs for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ETRN</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>EXPN</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>HELO</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>EHLO</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DKIM</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>MAIL</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>QUIT, ACL for</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>RCPT</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>STARTTLS, ACL for</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>VRFY</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>connection, ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>non-SMTP messages</primary>
+<secondary>ACLs for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>MIME content scanning</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>PRDR</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+</para>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="140pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry> <option>acl_not_smtp</option></entry>
+<entry>ACL for non-SMTP messages</entry>
+</row>
+<row>
+<entry> <option>acl_not_smtp_mime</option></entry>
+<entry>ACL for non-SMTP MIME parts</entry>
+</row>
+<row>
+<entry> <option>acl_not_smtp_start</option></entry>
+<entry>ACL at start of non-SMTP message</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_auth</option></entry>
+<entry>ACL for AUTH</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_connect</option></entry>
+<entry>ACL for start of SMTP connection</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_data</option></entry>
+<entry>ACL after DATA is complete</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_data_prdr</option></entry>
+<entry>ACL for each recipient, after DATA is complete</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_dkim</option></entry>
+<entry>ACL for each DKIM signer</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_etrn</option></entry>
+<entry>ACL for ETRN</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_expn</option></entry>
+<entry>ACL for EXPN</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_helo</option></entry>
+<entry>ACL for HELO or EHLO</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_mail</option></entry>
+<entry>ACL for MAIL</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_mailauth</option></entry>
+<entry>ACL for the AUTH parameter of MAIL</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_mime</option></entry>
+<entry>ACL for content-scanning MIME parts</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_notquit</option></entry>
+<entry>ACL for non-QUIT terminations</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_predata</option></entry>
+<entry>ACL at start of DATA command</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_quit</option></entry>
+<entry>ACL for QUIT</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_rcpt</option></entry>
+<entry>ACL for RCPT</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_starttls</option></entry>
+<entry>ACL for STARTTLS</entry>
+</row>
+<row>
+<entry> <option>acl_smtp_vrfy</option></entry>
+<entry>ACL for VRFY</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+For example, if you set
+</para>
+<literallayout class="monospaced">
+acl_smtp_rcpt = small_acl
+</literallayout>
+<para>
+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.
+</para>
+</section>
+<section id="SECID190">
+<title>The non-SMTP ACLs</title>
+<para>
+<indexterm role="concept">
+<primary>non-SMTP messages</primary>
+<secondary>ACLs for</secondary>
+</indexterm>
+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 <option>senders</option> and <option>sender_domains</option> conditions and the
+<varname>$sender_address</varname> and <varname>$recipients</varname> variables can be used. Variables such as
+<varname>$authenticated_sender</varname> are also available. You can specify added header lines
+in any of these ACLs.
+</para>
+<para>
+The <option>acl_not_smtp_start</option> 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 <option>acl_smtp_predata</option> 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 <option>acl_not_smtp</option> ACL. However, this ACL can be used to set
+controls, and in particular, it can be used to set
+</para>
+<literallayout class="monospaced">
+control = suppress_local_fixups
+</literallayout>
+<para>
+This cannot be used in the other non-SMTP ACLs because by the time they are
+run, it is too late.
+</para>
+<para>
+The <option>acl_not_smtp_mime</option> ACL is available only when Exim is compiled with the
+content-scanning extension. For details, see chapter <xref linkend="CHAPexiscan"/>.
+</para>
+<para>
+The <option>acl_not_smtp</option> ACL is run just before the <function>local_scan()</function> function. Any
+kind of rejection is treated as permanent, because there is no way of sending a
+temporary error for these kinds of message.
+</para>
+</section>
+<section id="SECID191">
+<title>The SMTP connect ACL</title>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>connection, ACL for</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>smtp_banner</option></primary>
+</indexterm>
+The ACL test specified by <option>acl_smtp_connect</option> happens at the start of an SMTP
+session, after the test specified by <option>host_reject_connection</option> (which is now
+an anomaly) and any TCP Wrappers testing (if configured). If the connection is
+accepted by an <option>accept</option> verb that has a <option>message</option> modifier, the contents of
+the message override the banner message that is otherwise specified by the
+<option>smtp_banner</option> option.
+</para>
+</section>
+<section id="SECID192">
+<title>The EHLO/HELO ACL</title>
+<para>
+<indexterm role="concept">
+<primary>EHLO</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>HELO</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+The ACL test specified by <option>acl_smtp_helo</option> happens when the client issues an
+EHLO or HELO command, after the tests specified by <option>helo_accept_junk_hosts</option>,
+<option>helo_allow_chars</option>, <option>helo_verify_hosts</option>, and <option>helo_try_verify_hosts</option>.
+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.
+</para>
+<para>
+Note also that a deny neither forces the client to go away nor means that
+mail will be refused on the connection. Consider checking for
+<varname>$sender_helo_name</varname> being defined in a MAIL or RCPT ACL to do that.
+</para>
+<para>
+If the command is accepted by an <option>accept</option> verb that has a <option>message</option>
+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.
+</para>
+</section>
+<section id="SECID193">
+<title>The DATA ACLs</title>
+<para>
+<indexterm role="concept">
+<primary>DATA</primary>
+<secondary>ACLs for</secondary>
+</indexterm>
+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 <option>acl_smtp_predata</option>
+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 <option>acl_smtp_data</option> ACL is run.
+</para>
+<para>
+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 <option>acl_smtp_data</option>, which is the second ACL that is
+associated with the DATA command.
+</para>
+<para>
+<indexterm role="concept">
+<primary>CHUNKING</primary>
+<secondary>BDAT command</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>BDAT</primary>
+<secondary>SMTP command</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>RFC 3030</primary>
+<secondary>CHUNKING</secondary>
+</indexterm>
+If CHUNKING was advertised and a BDAT command sequence is received,
+the <option>acl_smtp_predata</option> ACL is not run.
+The <option>acl_smtp_data</option> is run after the last BDAT command and all of
+the data specified is received.
+</para>
+<para>
+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<emphasis>xx</emphasis>) 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.
+</para>
+<para>
+The <option>acl_smtp_data</option> ACL is run after
+the <option>acl_smtp_data_prdr</option>,
+the <option>acl_smtp_dkim</option>
+and the <option>acl_smtp_mime</option> ACLs.
+</para>
+</section>
+<section id="SECTDKIMACL">
+<title>The SMTP DKIM ACL</title>
+<para>
+The <option>acl_smtp_dkim</option> ACL is available only when Exim is compiled with DKIM support
+enabled (which is the default).
+</para>
+<para>
+The ACL test specified by <option>acl_smtp_dkim</option> happens after a message has been
+received, and is executed for each DKIM signature found in a message. If not
+otherwise specified, the default action is to accept.
+</para>
+<para>
+This ACL is evaluated before <option>acl_smtp_mime</option> and <option>acl_smtp_data</option>.
+</para>
+<para>
+For details on the operation of DKIM, see section <xref linkend="SECDKIM"/>.
+</para>
+</section>
+<section id="SECID194">
+<title>The SMTP MIME ACL</title>
+<para>
+The <option>acl_smtp_mime</option> option is available only when Exim is compiled with the
+content-scanning extension. For details, see chapter <xref linkend="CHAPexiscan"/>.
+</para>
+<para>
+This ACL is evaluated after <option>acl_smtp_dkim</option> but before <option>acl_smtp_data</option>.
+</para>
+</section>
+<section id="SECTPRDRACL">
+<title>The SMTP PRDR ACL</title>
+<para>
+<indexterm role="concept">
+<primary>PRDR</primary>
+<secondary>ACL for</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>prdr_enable</option></primary>
+</indexterm>
+The <option>acl_smtp_data_prdr</option> ACL is available only when Exim is compiled
+with PRDR support enabled (which is the default).
+It becomes active only when the PRDR feature is negotiated between
+client and server for a message, and more than one recipient
+has been accepted.
+</para>
+<para>
+The ACL test specified by <option>acl_smtp_data_prdr</option> happens after a message
+has been received, and is executed once for each recipient of the message
+with <varname>$local_part</varname> and <varname>$domain</varname> valid.
+The test may accept, defer or deny for individual recipients.
+The <option>acl_smtp_data</option> will still be called after this ACL and
+can reject the message overall, even if this ACL has accepted it
+for some or all recipients.
+</para>
+<para>
+PRDR may be used to support per-user content filtering. Without it
+one must defer any recipient after the first that has a different
+content-filter configuration. With PRDR, the RCPT-time check
+<indexterm role="concept">
+<primary>PRDR</primary>
+<secondary>variable for</secondary>
+</indexterm>
+for this can be disabled when the variable <varname>$prdr_requested</varname>
+is <quote>yes</quote>.
+Any required difference in behaviour of the main DATA-time
+ACL should however depend on the PRDR-time ACL having run, as Exim
+will avoid doing so in some situations (e.g. single-recipient mails).
+</para>
+<para>
+See also the <option>prdr_enable</option> global option
+and the <option>hosts_try_prdr</option> smtp transport option.
+</para>
+<para>
+This ACL is evaluated after <option>acl_smtp_dkim</option> but before <option>acl_smtp_data</option>.
+If the ACL is not defined, processing completes as if
+the feature was not requested by the client.
+</para>
+</section>
+<section id="SECTQUITACL">
+<title>The QUIT ACL</title>
+<para>
+<indexterm role="concept">
+<primary>QUIT, ACL for</primary>
+</indexterm>
+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, it may only accept
+or warn as its final result.
+</para>
+<para>
+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 <option>logwrite</option> modifiers on a <option>warn</option> verb.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: Only the <varname>$acl_c</varname><emphasis>x</emphasis> variables can be used for this, because
+the <varname>$acl_m</varname><emphasis>x</emphasis> variables are reset at the end of each incoming message.
+</para>
+<para>
+You do not need to have a final <option>accept</option>, but if you do, you can use a
+<option>message</option> modifier to specify custom text that is sent as part of the 221
+response to QUIT.
+</para>
+<para>
+This ACL is run only for a <quote>normal</quote> 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.
+</para>
+</section>
+<section id="SECTNOTQUITACL">
+<title>The not-QUIT ACL</title>
+<para>
+<indexterm role="variable">
+<primary><varname>$acl_smtp_notquit</varname></primary>
+</indexterm>
+The not-QUIT ACL, specified by <option>acl_smtp_notquit</option>, is run in most cases when
+an SMTP session ends without sending QUIT. However, when Exim itself is in 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.
+</para>
+<para>
+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 <option>delay</option>
+modifier is forbidden in this ACL, and the only permitted verbs are <option>accept</option>
+and <option>warn</option>.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$smtp_notquit_reason</varname></primary>
+</indexterm>
+When the not-QUIT ACL is running, the variable <varname>$smtp_notquit_reason</varname> is set
+to a string that indicates the reason for the termination of the SMTP
+connection. The possible values are:
+</para>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="196pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry> <literal>acl-drop</literal></entry>
+<entry>Another ACL issued a <option>drop</option> command</entry>
+</row>
+<row>
+<entry> <literal>bad-commands</literal></entry>
+<entry>Too many unknown or non-mail commands</entry>
+</row>
+<row>
+<entry> <literal>command-timeout</literal></entry>
+<entry>Timeout while reading SMTP commands</entry>
+</row>
+<row>
+<entry> <literal>connection-lost</literal></entry>
+<entry>The SMTP connection has been lost</entry>
+</row>
+<row>
+<entry> <literal>data-timeout</literal></entry>
+<entry>Timeout while reading message data</entry>
+</row>
+<row>
+<entry> <literal>local-scan-error</literal></entry>
+<entry>The <function>local_scan()</function> function crashed</entry>
+</row>
+<row>
+<entry> <literal>local-scan-timeout</literal></entry>
+<entry>The <function>local_scan()</function> function timed out</entry>
+</row>
+<row>
+<entry> <literal>signal-exit</literal></entry>
+<entry>SIGTERM or SIGINT</entry>
+</row>
+<row>
+<entry> <literal>synchronization-error</literal></entry>
+<entry>SMTP synchronization error</entry>
+</row>
+<row>
+<entry> <literal>tls-failed</literal></entry>
+<entry>TLS failed to start</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+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 <literal>acl-drop</literal> case, the default message can be
+overridden by the <option>message</option> modifier in the not-QUIT ACL. In the case of a
+<option>drop</option> verb in another ACL, it is the message from the other ACL that is
+used.
+</para>
+</section>
+<section id="SECID195">
+<title>Finding an ACL to use</title>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>finding which to use</secondary>
+</indexterm>
+The value of an <option>acl_smtp_</option><emphasis>xxx</emphasis> option is expanded before use, so
+you can use different ACLs in different circumstances. For example,
+</para>
+<literallayout class="monospaced">
+acl_smtp_rcpt = ${if ={25}{$interface_port} \
+ {acl_check_rcpt} {acl_check_rcpt_submit} }
+</literallayout>
+<para>
+In the default configuration file there are some example settings for
+providing an RFC 4409 message <quote>submission</quote> service on port 587 and
+an RFC 8314 <quote>submissions</quote> 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.
+</para>
+<para>
+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:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If the string begins with a slash, Exim uses it as a filename, 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 <quote>#</quote>.
+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:
+</para>
+<literallayout class="monospaced">
+acl_smtp_data = /etc/acls/\
+ ${lookup{$sender_host_address}lsearch\
+ {/etc/acllist}{$value}{default}}
+</literallayout>
+<para>
+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.
+</para>
+</listitem>
+<listitem>
+<para>
+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.
+</para>
+</listitem>
+<listitem>
+<para>
+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
+</para>
+<literallayout class="monospaced">
+acl_smtp_vrfy = accept
+</literallayout>
+<para>
+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.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID196">
+<title>ACL return codes</title>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>return codes</secondary>
+</indexterm>
+Except for the QUIT ACL, which does not affect the SMTP return code (see
+section <xref linkend="SECTQUITACL"/> above), the result of running an ACL is either
+<quote>accept</quote> or <quote>deny</quote>, or, if some test cannot be completed (for example, if a
+database is down), <quote>defer</quote>. These results cause 2<emphasis>xx</emphasis>, 5<emphasis>xx</emphasis>, and 4<emphasis>xx</emphasis>
+return codes, respectively, to be used in the SMTP dialogue. A fourth return,
+<quote>error</quote>, occurs when there is an error such as invalid syntax in the ACL.
+This also causes a 4<emphasis>xx</emphasis> return code.
+</para>
+<para>
+For the non-SMTP ACL, <quote>defer</quote> and <quote>error</quote> are treated in the same way as
+<quote>deny</quote>, because there is no mechanism for passing temporary errors to the
+submitters of non-SMTP messages.
+</para>
+<para>
+ACLs that are relevant to message reception may also return <quote>discard</quote>. This
+has the effect of <quote>accept</quote>, 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.
+</para>
+<para>
+If the ACL for MAIL returns <quote>discard</quote>, all recipients are discarded, and no
+ACL is run for subsequent RCPT commands. The effect of <quote>discard</quote> 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 <quote>discard</quote> return from the DATA or the non-SMTP ACL discards all the
+remaining recipients. The <quote>discard</quote> return is not permitted for the
+<option>acl_smtp_predata</option> ACL.
+</para>
+<para>
+If the ACL for VRFY returns <quote>accept</quote>, a recipient verify (without callout)
+is done on the address and the result determines the SMTP response.
+</para>
+<para>
+<indexterm role="concept">
+<primary><function>local_scan()</function> function</primary>
+<secondary>when all recipients discarded</secondary>
+</indexterm>
+The <function>local_scan()</function> function is always run, even if there are no remaining
+recipients; it may create new recipients.
+</para>
+</section>
+<section id="SECID197">
+<title>Unset ACL options</title>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>unset options</secondary>
+</indexterm>
+The default actions when any of the <option>acl_</option><emphasis>xxx</emphasis> options are unset are not
+all the same. <emphasis role="bold">Note</emphasis>: 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 <quote>deny</quote>.
+</para>
+<para>
+For <option>acl_smtp_quit</option> and <option>acl_not_smtp_start</option> 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.
+</para>
+<para>
+For <option>acl_not_smtp</option>, <option>acl_smtp_auth</option>, <option>acl_smtp_connect</option>,
+<option>acl_smtp_data</option>, <option>acl_smtp_helo</option>, <option>acl_smtp_mail</option>, <option>acl_smtp_mailauth</option>,
+<option>acl_smtp_mime</option>, <option>acl_smtp_predata</option>, and <option>acl_smtp_starttls</option>, the action
+when the ACL is not defined is <quote>accept</quote>.
+</para>
+<para>
+For the others (<option>acl_smtp_etrn</option>, <option>acl_smtp_expn</option>, <option>acl_smtp_rcpt</option>, and
+<option>acl_smtp_vrfy</option>), the action when the ACL is not defined is <quote>deny</quote>.
+This means that <option>acl_smtp_rcpt</option> must be defined in order to receive any
+messages over an SMTP connection. For an example, see the ACL in the default
+configuration file.
+</para>
+</section>
+<section id="SECID198">
+<title>Data for message ACLs</title>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>data for message ACL</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$sender_address</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$sender_host_address</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$smtp_command</varname></primary>
+</indexterm>
+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,
+<varname>$sender_host_address</varname> and <varname>$sender_address</varname>) are set, and can be used in ACL
+statements. In the case of RCPT (but not MAIL or DATA), <varname>$domain</varname> and
+<varname>$local_part</varname> are set from the argument address. The entire SMTP command
+is available in <varname>$smtp_command</varname>.
+</para>
+<para>
+When an ACL for the AUTH parameter of MAIL is running, the variables that
+contain information about the host are set, but <varname>$sender_address</varname> is not yet
+set. Section <xref linkend="SECTauthparamail"/> contains a discussion of this parameter and
+how it is used.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$message_size</varname></primary>
+</indexterm>
+The <varname>$message_size</varname> 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).
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$rcpt_count</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$recipients_count</varname></primary>
+</indexterm>
+The <varname>$rcpt_count</varname> variable increases by one for each RCPT command received.
+The <varname>$recipients_count</varname> 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),
+<varname>$rcpt_count</varname> contains the total number of RCPT commands, and
+<varname>$recipients_count</varname> contains the total number of accepted recipients.
+</para>
+</section>
+<section id="SECTdatfornon">
+<title>Data for non-message ACLs</title>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>data for non-message ACL</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$smtp_command_argument</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$smtp_command</varname></primary>
+</indexterm>
+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 <varname>$smtp_command_argument</varname>,
+and the entire SMTP command is available in <varname>$smtp_command</varname>.
+These variables can be tested using a <option>condition</option> 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.
+</para>
+<literallayout class="monospaced">
+acl_check_auth:
+ accept encrypted = *
+ accept condition = ${if eq{${uc:$smtp_command_argument}}\
+ {CRAM-MD5}}
+ deny message = TLS encryption or CRAM-MD5 required
+</literallayout>
+<para>
+(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 <option>server_advertise_condition</option> authenticator
+option to do this.)
+</para>
+</section>
+<section id="SECID199">
+<title>Format of an ACL</title>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>format of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>verbs, definition of</secondary>
+</indexterm>
+An individual ACL consists of a number of statements. Each statement starts
+with a verb, optionally followed by a number of conditions and <quote>modifiers</quote>.
+Modifiers can change the way the verb operates, define error and log messages,
+set variables, insert delays, and vary the processing of accepted messages.
+</para>
+<para>
+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 <quote>and</quote> conjunction between conditions. For
+example:
+</para>
+<literallayout class="monospaced">
+deny dnslists = list1.example
+ dnslists = list2.example
+</literallayout>
+<para>
+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.
+</para>
+</section>
+<section id="SECID200">
+<title>ACL verbs</title>
+<para>
+The ACL verbs are as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>accept</option> ACL verb</primary>
+</indexterm>
+<option>accept</option>: If all the conditions are met, the ACL returns <quote>accept</quote>. If any
+of the conditions are not met, what happens depends on whether <option>endpass</option>
+appears among the conditions (for syntax see below). If the failing condition
+is before <option>endpass</option>, control is passed to the next ACL statement; if it is
+after <option>endpass</option>, the ACL returns <quote>deny</quote>. Consider this statement, used to
+check a RCPT command:
+</para>
+<literallayout class="monospaced">
+accept domains = +local_domains
+ endpass
+ verify = recipient
+</literallayout>
+<para>
+If the recipient domain does not match the <option>domains</option> 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 <quote>deny</quote>, because the failing condition is after
+<option>endpass</option>.
+</para>
+<para>
+The <option>endpass</option> 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 <option>endpass</option> is not needed, and it is no longer used in the default
+configuration.
+</para>
+<para>
+<indexterm role="concept">
+<primary><option>message</option> ACL modifier</primary>
+<secondary>with <option>accept</option></secondary>
+</indexterm>
+If a <option>message</option> modifier appears on an <option>accept</option> statement, its action
+depends on whether or not <option>endpass</option> is present. In the absence of <option>endpass</option>
+(when an <option>accept</option> verb either accepts or passes control to the next
+statement), <option>message</option> 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:
+</para>
+<literallayout>
+<literal>accept </literal><<emphasis>some conditions</emphasis>>
+<literal> message = OK, I will allow you through today</literal>
+</literallayout>
+<para>
+You can specify an SMTP response code, optionally followed by an <quote>extended
+response code</quote> 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 <option>accept</option> verb.
+</para>
+<para>
+If <option>endpass</option> is present in an <option>accept</option> statement, <option>message</option> specifies
+an error message that is used when access is denied. This behaviour is retained
+for backward compatibility, but current <quote>best practice</quote> is to avoid the use
+of <option>endpass</option>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>defer</option> ACL verb</primary>
+</indexterm>
+<option>defer</option>: If all the conditions are true, the ACL returns <quote>defer</quote> which, in
+an SMTP session, causes a 4<emphasis>xx</emphasis> response to be given. For a non-SMTP ACL,
+<option>defer</option> is the same as <option>deny</option>, because there is no way of sending a
+temporary error. For a RCPT command, <option>defer</option> is much the same as using a
+<command>redirect</command> router and <literal>:defer:</literal> while verifying, but the <option>defer</option> verb can
+be used in any ACL, and even for a recipient it might be a simpler approach.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>deny</option> ACL verb</primary>
+</indexterm>
+<option>deny</option>: If all the conditions are met, the ACL returns <quote>deny</quote>. If any of
+the conditions are not met, control is passed to the next ACL statement. For
+example,
+</para>
+<literallayout class="monospaced">
+deny dnslists = blackholes.mail-abuse.org
+</literallayout>
+<para>
+rejects commands from hosts that are on a DNS black list.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>discard</option> ACL verb</primary>
+</indexterm>
+<option>discard</option>: This verb behaves like <option>accept</option>, except that it returns
+<quote>discard</quote> from the ACL instead of <quote>accept</quote>. It is permitted only on ACLs
+that are concerned with receiving messages. When all the conditions are true,
+the sending entity receives a <quote>success</quote> response. However, <option>discard</option> 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 <option>received_recipients</option> log selector is set.
+</para>
+<para>
+If the <option>log_message</option> modifier is set when <option>discard</option> operates,
+its contents are added to the line that is automatically written to the log.
+The <option>message</option> modifier operates exactly as it does for <option>accept</option>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>drop</option> ACL verb</primary>
+</indexterm>
+<option>drop</option>: This verb behaves like <option>deny</option>, except that an SMTP connection is
+forcibly closed after the 5<emphasis>xx</emphasis> error message has been sent. For example:
+</para>
+<literallayout class="monospaced">
+drop condition = ${if > {$rcpt_count}{20}}
+ message = I don't take more than 20 RCPTs
+</literallayout>
+<para>
+There is no difference between <option>deny</option> and <option>drop</option> for the connect-time ACL.
+The connection is always dropped after sending a 550 response.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>require</option> ACL verb</primary>
+</indexterm>
+<option>require</option>: 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 <quote>deny</quote>. For
+example, when checking a RCPT command,
+</para>
+<literallayout class="monospaced">
+require message = Sender did not verify
+ verify = sender
+</literallayout>
+<para>
+passes control to subsequent statements only if the message’s sender can be
+verified. Otherwise, it rejects the command. Note the positioning of the
+<option>message</option> modifier, before the <option>verify</option> condition. The reason for this is
+discussed in section <xref linkend="SECTcondmodproc"/>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>warn</option> ACL verb</primary>
+</indexterm>
+<option>warn</option>: If all the conditions are true, a line specified by the
+<option>log_message</option> 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 <option>logwrite</option> modifier instead.
+</para>
+<para>
+If <option>log_message</option> is not present, a <option>warn</option> verb just checks its conditions
+and obeys any <quote>immediate</quote> modifiers (such as <option>control</option>, <option>set</option>,
+<option>logwrite</option>, <option>add_header</option>, and <option>remove_header</option>) that appear before the
+first failing condition. There is more about adding header lines in section
+<xref linkend="SECTaddheadacl"/>.
+</para>
+<para>
+If any condition on a <option>warn</option> statement cannot be completed (that is, there is
+some sort of defer), the log line specified by <option>log_message</option> 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 <option>warn</option> statement are processed. The incident
+is logged, and the ACL continues to be processed, from the next statement
+onwards.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$acl_verify_message</varname></primary>
+</indexterm>
+When one of the <option>warn</option> conditions is an address verification that fails, the
+text of the verification failure message is in <varname>$acl_verify_message</varname>. If you
+want this logged, you must set it up explicitly. For example:
+</para>
+<literallayout class="monospaced">
+warn !verify = sender
+ log_message = sender verify failed: $acl_verify_message
+</literallayout>
+</listitem>
+</itemizedlist>
+<para>
+At the end of each ACL there is an implicit unconditional <option>deny</option>.
+</para>
+<para>
+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.
+</para>
+</section>
+<section id="SECTaclvariables">
+<title>ACL variables</title>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>variables</secondary>
+</indexterm>
+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 <varname>$acl_c</varname> or <varname>$acl_m</varname>, 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:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The values of those variables whose names begin with <varname>$acl_c</varname> 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.
+</para>
+</listitem>
+<listitem>
+<para>
+The values of those variables whose names begin with <varname>$acl_m</varname> 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.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+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 <option>set</option>. For example:
+</para>
+<literallayout class="monospaced">
+accept hosts = whatever
+ set acl_m4 = some value
+accept authenticated = *
+ set acl_c_auth = yes
+</literallayout>
+<para>
+<emphasis role="bold">Note</emphasis>: 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
+<option>warn</option> verb without any other modifiers or conditions.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>strict_acl_vars</option></primary>
+</indexterm>
+What happens if a syntactically valid but undefined ACL variable is
+referenced depends on the setting of the <option>strict_acl_vars</option> option. If it is
+false (the default), an empty string is substituted; if it is true, an
+error is generated.
+</para>
+<para>
+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.
+</para>
+</section>
+<section id="SECTcondmodproc">
+<title>Condition and modifier processing</title>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>conditions; processing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>modifiers; processing</secondary>
+</indexterm>
+An exclamation mark preceding a condition negates its result. For example:
+</para>
+<literallayout class="monospaced">
+deny domains = *.dom.example
+ !verify = recipient
+</literallayout>
+<para>
+causes the ACL to return <quote>deny</quote> if the recipient domain ends in
+<emphasis>dom.example</emphasis> 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:
+</para>
+<literallayout class="monospaced">
+deny hosts = !192.168.3.4
+deny !hosts = 192.168.3.4
+</literallayout>
+<para>
+However, for many conditions (<option>verify</option> being a good example), only left-hand
+side negation of the whole condition is possible.
+</para>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+accept senders = ${lookup{$host_name}lsearch\
+ {/some/file}{$value}fail}
+accept senders = ${lookup{$host_name}lsearch\
+ {/some/file}{$value}{}}
+</literallayout>
+<para>
+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 <option>fail</option> in the first statement causes the
+condition to be ignored, leaving no further conditions. The <option>accept</option> 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 <option>accept</option> also fails.
+</para>
+<para>
+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 <option>control</option> modifier affects the way an incoming
+message is handled.
+</para>
+<para>
+The positioning of the modifiers in an ACL statement is 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 <option>message</option> modifier:
+</para>
+<literallayout class="monospaced">
+require message = Can't verify sender
+ verify = sender
+ message = Can't verify recipient
+ verify = recipient
+ message = This message cannot be used
+</literallayout>
+<para>
+If sender verification fails, Exim knows that the result of the statement is
+<quote>deny</quote>, so it goes no further. The first <option>message</option> 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 <quote>current</quote>, but is never used
+because there are no more conditions to cause failure.
+</para>
+<para>
+For the <option>deny</option> verb, on the other hand, it is always the last <option>message</option>
+modifier that is used, because all the conditions must be true for rejection to
+happen. Specifying more than one <option>message</option> modifier does not make sense, and
+the message can even be specified after all the conditions. For example:
+</para>
+<literallayout class="monospaced">
+deny hosts = ...
+ !senders = *@my.domain.example
+ message = Invalid sender from client host
+</literallayout>
+<para>
+The <quote>deny</quote> result does not happen until the end of the statement is reached,
+by which time Exim has set up the message.
+</para>
+</section>
+<section id="SECTACLmodi">
+<title>ACL modifiers</title>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>modifiers; list of</secondary>
+</indexterm>
+The ACL modifiers are as follows:
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">add_header</emphasis> = <<emphasis>text</emphasis>></term>
+<listitem>
+<para>
+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 <xref linkend="SECTaddheadacl"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">continue</emphasis> = <<emphasis>text</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>continue</option> ACL modifier</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>database</primary>
+<secondary>updating in ACL</secondary>
+</indexterm>
+This modifier does nothing of itself, and processing of the ACL always
+continues with the next condition or modifier. The value of <option>continue</option> 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:
+</para>
+<literallayout>
+<literal>condition = ${if eq{0}{</literal><<emphasis>some expansion</emphasis>><literal>}{true}{true}}</literal>
+</literallayout>
+<para>
+Instead, all you need is
+</para>
+<literallayout>
+<literal>continue = </literal><<emphasis>some expansion</emphasis>>
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control</emphasis> = <<emphasis>text</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>control</option> ACL modifier</primary>
+</indexterm>
+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 <option>control</option> modifier appears in a RCPT ACL.
+</para>
+<para>
+As there are now quite a few controls that can be applied, they are described
+separately in section <xref linkend="SECTcontrols"/>. The <option>control</option> modifier can be used
+in several different ways. For example:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+It can be at the end of an <option>accept</option> statement:
+</para>
+<literallayout class="monospaced">
+ accept ...some conditions
+ control = queue
+</literallayout>
+<para>
+In this case, the control is applied when this statement yields <quote>accept</quote>, in
+other words, when the conditions are all true.
+</para>
+</listitem>
+<listitem>
+<para>
+It can be in the middle of an <option>accept</option> statement:
+</para>
+<literallayout class="monospaced">
+ accept ...some conditions...
+ control = queue
+ ...some more conditions...
+</literallayout>
+<para>
+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 <quote>accept</quote> for the control
+to be relevant.
+</para>
+</listitem>
+<listitem>
+<para>
+It can be used with <option>warn</option> to apply the control, leaving the
+decision about accepting or denying to a subsequent verb. For
+example:
+</para>
+<literallayout class="monospaced">
+ warn ...some conditions...
+ control = freeze
+ accept ...
+</literallayout>
+<para>
+This example of <option>warn</option> does not contain <option>message</option>, <option>log_message</option>, or
+<option>logwrite</option>, so it does not add anything to the message and does not write a
+log entry.
+</para>
+</listitem>
+<listitem>
+<para>
+If you want to apply a control unconditionally, you can use it with a
+<option>require</option> verb. For example:
+</para>
+<literallayout class="monospaced">
+ require control = no_multiline_responses
+</literallayout>
+</listitem>
+</itemizedlist>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">delay</emphasis> = <<emphasis>time</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>delay</option> ACL modifier</primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-bh</option></primary>
+</indexterm>
+This modifier may appear in any ACL except notquit. It causes Exim to wait for
+the time interval before proceeding. However, when testing Exim using the
+<option>-bh</option> 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.
+</para>
+<para>
+Like <option>control</option>, <option>delay</option> can be used with <option>accept</option> or <option>deny</option>, for
+example:
+</para>
+<literallayout class="monospaced">
+deny ...some conditions...
+ delay = 30s
+</literallayout>
+<para>
+The delay happens if all the conditions are true, before the statement returns
+<quote>deny</quote>. Compare this with:
+</para>
+<literallayout class="monospaced">
+deny delay = 30s
+ ...some conditions...
+</literallayout>
+<para>
+which waits for 30s before processing the conditions. The <option>delay</option> modifier
+can also be used with <option>warn</option> and together with <option>control</option>:
+</para>
+<literallayout class="monospaced">
+warn ...some conditions...
+ delay = 2m
+ control = freeze
+accept ...
+</literallayout>
+<para>
+If <option>delay</option> 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 <option>delay</option> by
+using a <option>control</option> modifier to set <option>no_delay_flush</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">endpass</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>endpass</option> ACL modifier</primary>
+</indexterm>
+This modifier, which has no argument, is recognized only in <option>accept</option> and
+<option>discard</option> 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 <quote>deny</quote>. This concept has proved to be
+confusing to some people, so the use of <option>endpass</option> is no longer recommended as
+<quote>best practice</quote>. See the description of <option>accept</option> above for more details.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">log_message</emphasis> = <<emphasis>text</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>log_message</option> ACL modifier</primary>
+</indexterm>
+This modifier sets up a message that is used as part of the log message if the
+ACL denies access or a <option>warn</option> statement’s conditions are true. For example:
+</para>
+<literallayout class="monospaced">
+require log_message = wrong cipher suite $tls_in_cipher
+ encrypted = DES-CBC3-SHA
+</literallayout>
+<para>
+<option>log_message</option> is also used when recipients are discarded by <option>discard</option>. For
+example:
+</para>
+<literallayout>
+<literal>discard </literal><<emphasis>some conditions</emphasis>>
+<literal> log_message = Discarded $local_part@$domain because...</literal>
+</literallayout>
+<para>
+When access is denied, <option>log_message</option> adds to any underlying error message
+that may exist because of a condition failure. For example, while verifying a
+recipient address, a <emphasis>:fail:</emphasis> redirection might have already set up a
+message.
+</para>
+<para>
+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 <varname>$dnslist_</varname><<emphasis>xxx</emphasis>>
+variables are set after a DNS black list lookup succeeds. If the expansion of
+<option>log_message</option> fails, or if the result is an empty string, the modifier is
+ignored.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$acl_verify_message</varname></primary>
+</indexterm>
+If you want to use a <option>warn</option> statement to log the result of an address
+verification, you can use <varname>$acl_verify_message</varname> to include the verification
+error message.
+</para>
+<para>
+If <option>log_message</option> is used with a <option>warn</option> statement, <quote>Warning:</quote> 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 <option>logwrite</option> instead
+of <option>log_message</option>. In the absence of <option>log_message</option> and <option>logwrite</option>, nothing
+is logged for a successful <option>warn</option> statement.
+</para>
+<para>
+If <option>log_message</option> is not present and there is no underlying error message (for
+example, from the failure of address verification), but <option>message</option> is present,
+the <option>message</option> 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 <option>log_message</option> and <option>message</option>, a default built-in message is used for
+logging rejections.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">log_reject_target</emphasis> = <<emphasis>log name list</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>log_reject_target</option> ACL modifier</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>logging in ACL</primary>
+<secondary>specifying which log</secondary>
+</indexterm>
+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 <quote>main</quote>, <quote>reject</quote>, or <quote>panic</quote>. The default is <literal>main:reject</literal>. 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:
+</para>
+<literallayout>
+<literal>deny </literal><<emphasis>some conditions</emphasis>>
+<literal> log_reject_target =</literal>
+</literallayout>
+<para>
+This modifier can be used in SMTP and non-SMTP ACLs. It applies to both
+permanent and temporary rejections. Its effect lasts for the rest of the
+current ACL.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">logwrite</emphasis> = <<emphasis>text</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>logwrite</option> ACL modifier</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>logging in ACL</primary>
+<secondary>immediate</secondary>
+</indexterm>
+This modifier writes a message to a log file as soon as it is encountered when
+processing an ACL. (Compare <option>log_message</option>, which, except in the case of
+<option>warn</option> and <option>discard</option>, is used only if the ACL statement denies
+access.) The <option>logwrite</option> modifier can be used to log special incidents in
+ACLs. For example:
+</para>
+<literallayout>
+<literal>accept </literal><<emphasis>some special conditions</emphasis>>
+<literal> control = freeze</literal>
+<literal> logwrite = froze message because ...</literal>
+</literallayout>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+logwrite = :main,reject: text for main and reject logs
+logwrite = :panic: text for panic log only
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">message</emphasis> = <<emphasis>text</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>message</option> ACL modifier</primary>
+</indexterm>
+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 <quote>accept</quote>, <quote>deny</quote>,
+or <quote>defer</quote> response. (In the case of the <option>accept</option> and <option>discard</option> verbs,
+there is some complication if <option>endpass</option> is involved; see the description of
+<option>accept</option> for details.)
+</para>
+<para>
+The expansion of the message happens at the time Exim decides that the ACL is
+to end, not at the time it processes <option>message</option>. If the expansion fails, or
+generates an empty string, the modifier is ignored. Here is an example where
+<option>message</option> must be specified first, because the ACL ends with a rejection if
+the <option>hosts</option> condition fails:
+</para>
+<literallayout class="monospaced">
+require message = Host not recognized
+ hosts = 10.0.0.0/8
+</literallayout>
+<para>
+(Once a condition has failed, no further conditions or modifiers are
+processed.)
+</para>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>error codes</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>smtp_banner</option></primary>
+</indexterm>
+For ACLs that are triggered by SMTP commands, the message is returned as part
+of the SMTP response. The use of <option>message</option> with <option>accept</option> (or <option>discard</option>)
+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 <option>smtp_banner</option>. 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.
+</para>
+<para>
+When SMTP is involved, the message may begin with an overriding response code,
+consisting of three digits optionally followed by an <quote>extended response code</quote>
+of the form <emphasis>n.n.n</emphasis>, each code being followed by a space. For example:
+</para>
+<literallayout class="monospaced">
+deny message = 599 1.2.3 Host not welcome
+ hosts = 192.168.34.0/24
+</literallayout>
+<para>
+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<emphasis>xx</emphasis>.
+</para>
+<para>
+Notwithstanding the previous paragraph, for the QUIT ACL, unlike the others,
+the message modifier cannot override the 221 response code.
+</para>
+<para>
+The text in a <option>message</option> 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.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$acl_verify_message</varname></primary>
+</indexterm>
+For ACLs that are called by an <option>acl =</option> ACL condition, the message is
+stored in <varname>$acl_verify_message</varname>, from which the calling ACL may use it.
+</para>
+<para>
+If <option>message</option> 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
+<varname>$acl_verify_message</varname>, so you can incorporate it into your message if you
+wish. In particular, if you want the text from <option>:fail:</option> items in <command>redirect</command>
+routers to be passed back as part of the SMTP response, you should either not
+use a <option>message</option> modifier, or make use of <varname>$acl_verify_message</varname>.
+</para>
+<para>
+For compatibility with previous releases of Exim, a <option>message</option> modifier that
+is used with a <option>warn</option> verb behaves in a similar way to the <option>add_header</option>
+modifier, but this usage is now deprecated. However, <option>message</option> acts only when
+all the conditions are true, wherever it appears in an ACL command, whereas
+<option>add_header</option> acts as soon as it is encountered. If <option>message</option> is used with
+<option>warn</option> in an ACL that is not concerned with receiving a message, it has no
+effect.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">queue</emphasis> = <<emphasis>text</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>queue</option> ACL modifier</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>named queues</primary>
+<secondary>selecting in ACL</secondary>
+</indexterm>
+This modifier specifies the use of a named queue for spool files
+for the message.
+It can only be used before the message is received (i.e. not in
+the DATA ACL).
+This could be used, for example, for known high-volume burst sources
+of traffic, or for quarantine of messages.
+Separate queue-runner processes will be needed for named queues.
+If the text after expansion is empty, the default queue is used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">remove_header</emphasis> = <<emphasis>text</emphasis>></term>
+<listitem>
+<para>
+This modifier specifies one or more header names in a colon-separated list
+ that are to be removed from an incoming message, assuming, of course, that
+the message is ultimately accepted. For details, see section <xref linkend="SECTremoveheadacl"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">set</emphasis> <<emphasis>acl_name</emphasis>> = <<emphasis>value</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>set</option> ACL modifier</primary>
+</indexterm>
+This modifier puts a value into one of the ACL variables (see section
+<xref linkend="SECTaclvariables"/>).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">udpsend</emphasis> = <<emphasis>parameters</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>UDP communications</primary>
+</indexterm>
+This modifier sends a UDP packet, for purposes such as statistics
+collection or behaviour monitoring. The parameters are expanded, and
+the result of the expansion must be a colon-separated list consisting
+of a destination server, port number, and the packet contents. The
+server can be specified as a host name or IPv4 or IPv6 address. The
+separator can be changed with the usual angle bracket syntax. For
+example, you might want to collect information on which hosts connect
+when:
+</para>
+<literallayout class="monospaced">
+udpsend = <; 2001:dB8::dead:beef ; 1234 ;\
+ $tod_zulu $sender_host_address
+</literallayout>
+</listitem></varlistentry>
+</variablelist>
+</section>
+<section id="SECTcontrols">
+<title>Use of the control modifier</title>
+<para>
+<indexterm role="concept">
+<primary><option>control</option> ACL modifier</primary>
+</indexterm>
+The <option>control</option> modifier supports the following settings:
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">control = allow_auth_unadvertised</emphasis></term>
+<listitem>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+warn hosts = 192.168.34.25
+ control = allow_auth_unadvertised
+</literallayout>
+<para>
+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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = caseful_local_part</emphasis></term>
+<term><emphasis role="bold">control = caselower_local_part</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>case of local part in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>case of local parts</primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+These two controls are permitted only in the ACL specified by <option>acl_smtp_rcpt</option>
+(that is, during RCPT processing). By default, the contents of <varname>$local_part</varname>
+are lower cased before ACL processing. If <quote>caseful_local_part</quote> is specified,
+any uppercase letters in the original local part are restored in <varname>$local_part</varname>
+for the rest of the ACL, or until a control that sets <quote>caselower_local_part</quote>
+is encountered.
+</para>
+<para>
+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 <option>caseful_local_part</option> generic router option).
+</para>
+<para>
+This facility could be used, for example, to add a spam score to local parts
+containing upper case letters. For example, using <varname>$acl_m4</varname> to accumulate the
+spam score:
+</para>
+<literallayout class="monospaced">
+warn control = caseful_local_part
+ set acl_m4 = ${eval:\
+ $acl_m4 + \
+ ${if match{$local_part}{[A-Z]}{1}{0}}\
+ }
+ control = caselower_local_part
+</literallayout>
+<para>
+Notice that we put back the lower cased version afterwards, assuming that
+is what is wanted for subsequent tests.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = cutthrough_delivery/</emphasis><<emphasis>options</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>cutthrough routing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>cutthrough</primary>
+<secondary>requesting</secondary>
+</indexterm>
+This option requests delivery be attempted while the item is being received.
+</para>
+<para>
+The option is usable in the RCPT ACL.
+If enabled for a message received via smtp and routed to an smtp transport,
+and only one transport, interface, destination host and port combination
+is used for all recipients of the message,
+then the delivery connection is made while the receiving connection is open
+and data is copied from one to the other.
+</para>
+<para>
+An attempt to set this option for any recipient but the first
+for a mail will be quietly ignored.
+If a recipient-verify callout
+(with use_sender)
+connection is subsequently
+requested in the same ACL it is held open and used for
+any subsequent recipients and the data,
+otherwise one is made after the initial RCPT ACL completes.
+</para>
+<para>
+Note that routers are used in verify mode,
+and cannot depend on content of received headers.
+Note also that headers cannot be
+modified by any of the post-data ACLs (DATA, MIME and DKIM).
+Headers may be modified by routers (subject to the above) and transports.
+The <emphasis>Received-By:</emphasis> header is generated as soon as the body reception starts,
+rather than the traditional time after the full message is received;
+this will affect the timestamp.
+</para>
+<para>
+All the usual ACLs are called; if one results in the message being
+rejected, all effort spent in delivery (including the costs on
+the ultimate destination) will be wasted.
+Note that in the case of data-time ACLs this includes the entire
+message body.
+</para>
+<para>
+Cutthrough delivery is not supported via transport-filters or when DKIM signing
+of outgoing messages is done, because it sends data to the ultimate destination
+before the entire message has been received from the source.
+It is not supported for messages received with the SMTP PRDR
+or CHUNKING
+options in use.
+</para>
+<para>
+Should the ultimate destination system positively accept or reject the mail,
+a corresponding indication is given to the source system and nothing is queued.
+If the item is successfully delivered in cutthrough mode
+the delivery log lines are tagged with ">>" rather than "=>" and appear
+before the acceptance "<=" line.
+</para>
+<para>
+If there is a temporary error the item is queued for later delivery in the
+usual fashion.
+This behaviour can be adjusted by appending the option <emphasis role="bold">defer=</emphasis><<emphasis>value</emphasis>>
+to the control; the default value is <quote>spool</quote> and the alternate value
+<quote>pass</quote> copies an SMTP defer response from the target back to the initiator
+and does not queue the message.
+Note that this is independent of any recipient verify conditions in the ACL.
+</para>
+<para>
+Delivery in this mode avoids the generation of a bounce mail to a
+(possibly faked)
+sender when the destination system is doing content-scan based rejection.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = debug/</emphasis><<emphasis>options</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>enabling debug logging</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>debugging</primary>
+<secondary>enabling from an ACL</secondary>
+</indexterm>
+This control turns on debug logging, almost as though Exim had been invoked
+with <literal>-d</literal>, with the output going to a new logfile in the usual logs directory,
+by default called <emphasis>debuglog</emphasis>.
+The filename can be adjusted with the <emphasis>tag</emphasis> option, which
+may access any variables already defined. The logging may be adjusted with
+the <emphasis>opts</emphasis> option, which takes the same values as the <literal>-d</literal> command-line
+option.
+Logging started this way may be stopped, and the file removed,
+with the <emphasis>kill</emphasis> option.
+Some examples (which depend on variables that don’t exist in all
+contexts):
+</para>
+<literallayout class="monospaced">
+ control = debug
+ control = debug/tag=.$sender_host_address
+ control = debug/opts=+expand+acl
+ control = debug/tag=.$message_exim_id/opts=+expand
+ control = debug/kill
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = dkim_disable_verify</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>disable DKIM verify</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>DKIM</primary>
+<secondary>disable verify</secondary>
+</indexterm>
+This control turns off DKIM verification processing entirely. For details on
+the operation and configuration of DKIM, see section <xref linkend="SECDKIM"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = dmarc_disable_verify</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>disable DMARC verify</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>DMARC</primary>
+<secondary>disable verify</secondary>
+</indexterm>
+This control turns off DMARC verification processing entirely. For details on
+the operation and configuration of DMARC, see section <xref linkend="SECDMARC"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = dscp/</emphasis><<emphasis>value</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>setting DSCP value</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DSCP</primary>
+<secondary>inbound</secondary>
+</indexterm>
+This option causes the DSCP value associated with the socket for the inbound
+connection to be adjusted to a given value, given as one of a number of fixed
+strings or to numeric value.
+The <option>-bI:dscp</option> option may be used to ask Exim which names it knows of.
+Common values include <literal>throughput</literal>, <literal>mincost</literal>, and on newer systems
+<literal>ef</literal>, <literal>af41</literal>, etc. Numeric values may be in the range 0 to 0x3F.
+</para>
+<para>
+The outbound packets from Exim will be marked with this value in the header
+(for IPv4, the TOS field; for IPv6, the TCLASS field); there is no guarantee
+that these values will have any effect, not be stripped by networking
+equipment, or do much of anything without cooperation with your Network
+Engineer and those of all network operators between the source and destination.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = enforce_sync</emphasis></term>
+<term><emphasis role="bold">control = no_enforce_sync</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>synchronization checking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>synchronization checking in SMTP</primary>
+</indexterm>
+These controls make it possible to be selective about when SMTP synchronization
+is enforced. The global option <option>smtp_enforce_sync</option> specifies the initial
+state of the switch (it is true by default). See the description of this option
+in chapter <xref linkend="CHAPmainconfig"/> for details of SMTP synchronization checking.
+</para>
+<para>
+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
+<option>acl_smtp_connect</option>, 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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = fakedefer/</emphasis><<emphasis>message</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>fake defer</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>defer, fake</primary>
+</indexterm>
+This control works in exactly the same way as <option>fakereject</option> (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 <option>fakedefer</option> because it causes the
+messages to be duplicated when the sender retries. Therefore, you should not
+use <option>fakedefer</option> if the message is to be delivered normally.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = fakereject/</emphasis><<emphasis>message</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>fake rejection</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>rejection, fake</primary>
+</indexterm>
+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.
+</para>
+<para>
+The text for the 550 response is taken from the <option>control</option> modifier. If no
+message is supplied, the following is used:
+</para>
+<literallayout class="monospaced">
+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).
+</literallayout>
+<para>
+This facility should be used with extreme caution.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = freeze</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>forcing in ACL</secondary>
+</indexterm>
+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.
+</para>
+<para>
+This modifier can optionally be followed by <literal>/no_tell</literal>. If the global option
+<option>freeze_tell</option> is set, it is ignored for the current message (that is, nobody
+is told about the freezing), provided all the <emphasis role="bold">control=freeze</emphasis> modifiers that
+are obeyed for the current message have the <literal>/no_tell</literal> option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = no_delay_flush</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>output flushing, disabling for delay</secondary>
+</indexterm>
+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 <option>delay</option> modifier,
+disables such output flushing.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = no_callout_flush</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>output flushing, disabling for callout</secondary>
+</indexterm>
+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 <option>verify</option> condition
+that causes the callout, disables such output flushing.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = no_mbox_unspool</emphasis></term>
+<listitem>
+<para>
+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 <quote>mbox format</quote> 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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = no_multiline_responses</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>multiline responses, suppressing</primary>
+</indexterm>
+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.
+</para>
+<para>
+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
+(<quote>use multiline responses for more</quote> 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:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Extra information that is normally output as part of a rejection caused by
+sender verification failure is omitted. Only the final line (typically <quote>sender
+verification failed</quote>) is sent.
+</para>
+</listitem>
+<listitem>
+<para>
+If a <option>message</option> modifier supplies a multiline response, only the first
+line is output.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = no_pipelining</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>PIPELINING</primary>
+<secondary>suppressing advertising</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>PIPELINING</secondary>
+</indexterm>
+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 <option>acl_smtp_connect</option> or <option>acl_smtp_helo</option>. See also
+<option>pipelining_advertise_hosts</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry revisionflag="changed">
+<term><emphasis role="bold">control = queue/</emphasis><<emphasis>options</emphasis>>*</term>
+<term><emphasis role="bold">control = queue_only</emphasis></term>
+<listitem>
+<para revisionflag="changed">
+<indexterm role="option">
+<primary><option>queue</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>queue_only</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queueing incoming messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queueing</primary>
+<secondary>forcing in ACL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>first pass routing</primary>
+</indexterm>
+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.
+If used with no options set,
+no immediate delivery process is started. In other words, it has the
+effect as the <option>queue_only</option> global option or <emphasis>-odq</emphasis> command-line option.
+</para>
+<para revisionflag="changed">
+If the <emphasis>first_pass_route</emphasis> option is given then
+the behaviour is like the command-line <emphasis>-oqds</emphasis> option;
+a delivery process is started which stops short of making
+any SMTP delivery. The benefit is that the hints database will be updated for
+the message being waiting for a specific host, and a later queue run will be
+able to send all such messages on a single connection.
+</para>
+<para revisionflag="changed">
+The control only applies to the current message, not to any subsequent ones that
+ may be received in the same SMTP connection.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = submission/</emphasis><<emphasis>options</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>submission</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>submission mode</primary>
+</indexterm>
+This control is permitted only for the MAIL, RCPT, and start of data ACLs (the
+latter is the one defined by <option>acl_smtp_predata</option>). Setting it tells Exim that
+the current message is a submission from a local MUA. In this case, Exim
+operates in <quote>submission mode</quote>, and applies certain fixups to the message if
+necessary. For example, it adds a <emphasis>Date:</emphasis> header line if one is not present.
+This control is not permitted in the <option>acl_smtp_data</option> ACL, because that is too
+late (the message has already been created).
+</para>
+<para>
+Chapter <xref linkend="CHAPmsgproc"/> describes the processing that Exim applies to
+messages. Section <xref linkend="SECTsubmodnon"/> 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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = suppress_local_fixups</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>submission fixups, suppressing</primary>
+</indexterm>
+This control applies to locally submitted (non TCP/IP) messages, and is the
+complement of <literal>control = submission</literal>. It disables the fixups that are
+normally applied to locally-submitted messages. Specifically:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Any <emphasis>Sender:</emphasis> header line is left alone (in this respect, it is a
+dynamic version of <option>local_sender_retain</option>).
+</para>
+</listitem>
+<listitem>
+<para>
+No <emphasis>Message-ID:</emphasis>, <emphasis>From:</emphasis>, or <emphasis>Date:</emphasis> header lines are added.
+</para>
+</listitem>
+<listitem>
+<para>
+There is no check that <emphasis>From:</emphasis> corresponds to the actual sender.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+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 <option>acl_smtp_mail</option>, <option>acl_smtp_rcpt</option>, <option>acl_smtp_predata</option>,
+and <option>acl_not_smtp_start</option> ACLs, because it has to be set before the message’s
+data is read.
+</para>
+<para>
+<emphasis role="bold">Note:</emphasis> This control applies only to the current message, not to any others
+that are being submitted at the same time using <option>-bs</option> or <option>-bS</option>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">control = utf8_downconvert</emphasis></term>
+<listitem>
+<para>
+This control enables conversion of UTF-8 in message envelope addresses
+to a-label form.
+For details see section <xref linkend="SECTi18nMTA"/>.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</section>
+<section id="SECTsummesfix">
+<title>Summary of message fixup control</title>
+<para>
+All four possibilities for message fixups can be specified:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Locally submitted, fixups applied: the default.
+</para>
+</listitem>
+<listitem>
+<para>
+Locally submitted, no fixups applied: use
+<literal>control = suppress_local_fixups</literal>.
+</para>
+</listitem>
+<listitem>
+<para>
+Remotely submitted, no fixups applied: the default.
+</para>
+</listitem>
+<listitem>
+<para>
+Remotely submitted, fixups applied: use <literal>control = submission</literal>.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECTaddheadacl">
+<title>Adding header lines in ACLs</title>
+<para>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>adding in an ACL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>position of added lines</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>add_header</option> ACL modifier</primary>
+</indexterm>
+The <option>add_header</option> modifier can be used to add one or more extra header lines
+to an incoming message, as in this example:
+</para>
+<literallayout class="monospaced">
+warn dnslists = sbl.spamhaus.org : \
+ dialup.mail-abuse.org
+ add_header = X-blacklisted-at: $dnslist_domain
+</literallayout>
+<para>
+The <option>add_header</option> modifier is permitted in the MAIL, RCPT, PREDATA, DATA,
+MIME, DKIM, and non-SMTP ACLs (in other words, those that are concerned with
+receiving a message). The message must ultimately be accepted for
+<option>add_header</option> to have any significant effect. You can use <option>add_header</option> with
+any ACL verb, including <option>deny</option> (though this is potentially useful only in a
+RCPT ACL).
+</para>
+<para>
+Headers will not be added to the message if the modifier is used in
+DATA, MIME or DKIM ACLs for a message delivered by cutthrough routing.
+</para>
+<para>
+Leading and trailing newlines are removed from
+the data for the <option>add_header</option> modifier; if it then
+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; <literal>X-ACL-Warn:</literal> is added to the
+front of any line that is not a valid header line.
+</para>
+<para>
+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.
+</para>
+<para>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>added; visibility of</secondary>
+</indexterm>
+Header lines are not visible in string expansions
+of message headers
+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
+<xref linkend="SECTaclvariables"/>.
+</para>
+<para>
+The list of headers yet to be added is given by the <option>$headers_added</option> variable.
+</para>
+<para>
+The <option>add_header</option> modifier acts immediately as it is encountered during the
+processing of an ACL. Notice the difference between these two cases:
+</para>
+<literallayout>
+<literal>accept add_header = ADDED: some text</literal>
+<literal> </literal><<emphasis>some condition</emphasis>>
+
+<literal>accept </literal><<emphasis>some condition</emphasis>>
+<literal> add_header = ADDED: some text</literal>
+</literallayout>
+<para>
+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 <option>add_header</option> may occur in the same
+ACL statement. All those that are encountered before a condition fails are
+honoured.
+</para>
+<para>
+<indexterm role="concept">
+<primary><option>warn</option> ACL verb</primary>
+</indexterm>
+For compatibility with previous versions of Exim, a <option>message</option> modifier for a
+<option>warn</option> verb acts in the same way as <option>add_header</option>, 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 <option>message</option> is honoured. This
+usage of <option>message</option> is now deprecated. If both <option>add_header</option> and <option>message</option>
+are present on a <option>warn</option> verb, both are processed according to their
+specifications.
+</para>
+<para>
+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 <emphasis>Received:</emphasis> lines), immediately
+after the first block of <emphasis>Received:</emphasis> lines, or immediately before any line
+that is not a <emphasis>Received:</emphasis> or <emphasis>Resent-something:</emphasis> header.
+</para>
+<para>
+This is done by specifying <quote>:at_start:</quote>, <quote>:after_received:</quote>, or
+<quote>:at_start_rfc:</quote> (or, for completeness, <quote>:at_end:</quote>) 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:
+</para>
+<literallayout class="monospaced">
+warn add_header = \
+ :after_received:X-My-Header: something or other...
+</literallayout>
+<para>
+If more than one header line is supplied in a single <option>add_header</option> 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.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: 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.
+</para>
+</section>
+<section id="SECTremoveheadacl">
+<title>Removing header lines in ACLs</title>
+<para>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>removing in an ACL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>position of removed lines</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>remove_header</option> ACL modifier</primary>
+</indexterm>
+The <option>remove_header</option> modifier can be used to remove one or more header lines
+from an incoming message, as in this example:
+</para>
+<literallayout class="monospaced">
+warn message = Remove internal headers
+ remove_header = x-route-mail1 : x-route-mail2
+</literallayout>
+<para>
+The <option>remove_header</option> modifier is permitted in the MAIL, RCPT, PREDATA, DATA,
+MIME, DKIM, and non-SMTP ACLs (in other words, those that are concerned with
+receiving a message). The message must ultimately be accepted for
+<option>remove_header</option> to have any significant effect. You can use <option>remove_header</option>
+with any ACL verb, including <option>deny</option>, though this is really not useful for
+any verb that doesn’t result in a delivered message.
+</para>
+<para>
+Headers will not be removed from the message if the modifier is used in
+DATA, MIME or DKIM ACLs for a message delivered by cutthrough routing.
+</para>
+<para>
+More than one header can be removed at the same time by using a colon separated
+list of header names. The header matching is case insensitive. Wildcards are
+not permitted, nor is list expansion performed, so you cannot use hostlists to
+create a list of headers, however both connection and message variable expansion
+are performed (<option>$acl_c_*</option> and <option>$acl_m_*</option>), illustrated in this example:
+</para>
+<literallayout class="monospaced">
+warn hosts = +internal_hosts
+ set acl_c_ihdrs = x-route-mail1 : x-route-mail2
+warn message = Remove internal headers
+ remove_header = $acl_c_ihdrs
+</literallayout>
+<para>
+Header names for removal are accumulated during the MAIL, RCPT, and predata ACLs.
+Matching header lines are removed from the message before processing the DATA and MIME ACLs.
+If multiple header lines match, all are removed.
+There is no harm in attempting to remove the same header twice nor in removing
+a non-existent header. Further header lines to be removed may be accumulated
+during the DATA and MIME ACLs, after which they are removed from the message,
+if present. In the case of non-SMTP messages, headers to be removed are
+accumulated during the non-SMTP ACLs, and are removed from the message after
+all the ACLs have run. If a message is rejected after DATA or by the non-SMTP
+ACL, there really is no effect because there is no logging of what headers
+would have been removed.
+</para>
+<para>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>removed; visibility of</secondary>
+</indexterm>
+Header lines are not visible in string expansions until the DATA phase when it
+is received. Any header lines removed in the MAIL, RCPT, and predata ACLs are
+not visible in the DATA ACL and MIME ACLs. Similarly, header lines that are
+removed by the DATA or MIME ACLs are still visible in those ACLs. Because of
+this restriction, you cannot use header lines as a way of controlling data
+passed between (for example) the MAIL and RCPT ACLs. If you want to do this,
+you should instead use ACL variables, as described in section
+<xref linkend="SECTaclvariables"/>.
+</para>
+<para>
+The <option>remove_header</option> modifier acts immediately as it is encountered during the
+processing of an ACL. Notice the difference between these two cases:
+</para>
+<literallayout>
+<literal>accept remove_header = X-Internal</literal>
+<literal> </literal><<emphasis>some condition</emphasis>>
+
+<literal>accept </literal><<emphasis>some condition</emphasis>>
+<literal> remove_header = X-Internal</literal>
+</literallayout>
+<para>
+In the first case, the header line is always removed, whether or not the
+condition is true. In the second case, the header line is removed only if the
+condition is true. Multiple occurrences of <option>remove_header</option> may occur in the
+same ACL statement. All those that are encountered before a condition fails
+are honoured.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: This facility currently applies only to header lines that are
+present during ACL processing. It does NOT remove header lines that are added
+in a system filter or in a router or transport.
+</para>
+</section>
+<section id="SECTaclconditions">
+<title>ACL conditions</title>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>conditions; list of</secondary>
+</indexterm>
+Some of the 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 <xref linkend="CHAPexiscan"/>.
+</para>
+<para>
+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 <option>acl_smtp_data</option> and <option>acl_not_smtp</option>. You
+can use the same condition (with different parameters) more than once in the
+same ACL statement. This provides a way of specifying an <quote>and</quote> conjunction.
+The conditions are as follows:
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">acl = </emphasis><<emphasis>name of acl or ACL string or file name </emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>nested</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>indirect</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>arguments</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>acl</option> ACL condition</primary>
+</indexterm>
+The possible values of the argument are the same as for the
+<option>acl_smtp_</option><emphasis>xxx</emphasis> options. The named or inline ACL is run. If it returns
+<quote>accept</quote> the condition is true; if it returns <quote>deny</quote> the condition is
+false. If it returns <quote>defer</quote>, the current ACL returns <quote>defer</quote> unless the
+condition is on a <option>warn</option> verb. In that case, a <quote>defer</quote> return makes the
+condition false. This means that further processing of the <option>warn</option> verb
+ceases, but processing of the ACL continues.
+</para>
+<para>
+If the argument is a named ACL, up to nine space-separated optional values
+can be appended; they appear within the called ACL in $acl_arg1 to $acl_arg9,
+and $acl_narg is set to the count of values.
+Previous values of these variables are restored after the call returns.
+The name and values are expanded separately.
+Note that spaces in complex expansions which are used as arguments
+will act as argument separators.
+</para>
+<para>
+If the nested <option>acl</option> returns <quote>drop</quote> and the outer condition denies access,
+the connection is dropped. If it returns <quote>discard</quote>, the verb must be
+<option>accept</option> or <option>discard</option>, and the action is taken immediately – no further
+conditions are tested.
+</para>
+<para>
+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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">authenticated = </emphasis><<emphasis>string list</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>authenticated</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>ACL checking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing for authentication</secondary>
+</indexterm>
+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
+</para>
+<literallayout class="monospaced">
+authenticated = *
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">condition = </emphasis><<emphasis>string</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>condition</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>customizing</primary>
+<secondary>ACL condition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>customized test</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing, customized</secondary>
+</indexterm>
+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
+<quote>no</quote> or <quote>false</quote>, the condition is false. If the result is any non-zero
+number, or one of the strings <quote>yes</quote> or <quote>true</quote>, the condition is true. For
+any other value, some error is assumed to have occurred, and the ACL returns
+<quote>defer</quote>. 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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">decode = </emphasis><<emphasis>location</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>decode</option> ACL condition</primary>
+</indexterm>
+This condition is available only when Exim is compiled with the
+content-scanning extension, and it is allowed only in the ACL defined by
+<option>acl_smtp_mime</option>. 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 <xref linkend="CHAPexiscan"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">dnslists = </emphasis><<emphasis>list of domain names and other data</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>dnslists</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS list</primary>
+<secondary>in ACL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>black list (DNS)</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing a DNS list</secondary>
+</indexterm>
+This condition checks for entries in DNS black lists. These are also known as
+<quote>RBL lists</quote>, after the original Realtime Blackhole List, but note that the
+use of the lists at <emphasis>mail-abuse.org</emphasis> now carries a charge. There are too many
+different variants of this condition to describe briefly here. See sections
+<xref linkend="SECTmorednslists"/>–<xref linkend="SECTmorednslistslast"/> for details.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">domains = </emphasis><<emphasis>domain list</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>domains</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain</primary>
+<secondary>ACL checking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing a recipient domain</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$domain_data</varname></primary>
+</indexterm>
+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 <varname>$domain_data</varname> until the next
+<option>domains</option> test.
+</para>
+<para>
+<emphasis role="bold">Note carefully</emphasis> (because many people seem to fall foul of this): you cannot
+use <option>domains</option> in a DATA ACL.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">encrypted = </emphasis><<emphasis>string list</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>encrypted</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>encryption</primary>
+<secondary>checking in an ACL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing for encryption</secondary>
+</indexterm>
+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
+</para>
+<literallayout class="monospaced">
+encrypted = *
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">hosts = </emphasis><<emphasis>host list</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>hosts</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>ACL checking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing the client host</secondary>
+</indexterm>
+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:
+</para>
+<literallayout class="monospaced">
+accept hosts = 10.9.8.7 : dbm;/etc/friendly/hosts
+</literallayout>
+<para>
+The lookup in this example uses the host name for its key. This is implied by
+the lookup type <quote>dbm</quote>. (For a host address lookup you would use <quote>net-dbm</quote>
+and it wouldn’t matter which way round you had these two items.)
+</para>
+<para>
+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 <option>accept</option> statement fails for a host whose name cannot be
+found, even if its IP address is 10.9.8.7.
+</para>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+accept hosts = dbm;/etc/friendly/hosts
+accept hosts = 10.9.8.7
+</literallayout>
+<para>
+The default action on failing to find the host name is to assume that the host
+is not in the list, so the first <option>accept</option> statement fails. The second
+statement can then check the IP address.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$host_data</varname></primary>
+</indexterm>
+If a <option>hosts</option> condition is satisfied by means of a lookup, the result
+of the lookup is made available in the <varname>$host_data</varname> variable. This
+allows you, for example, to set up a statement like this:
+</para>
+<literallayout class="monospaced">
+deny hosts = net-lsearch;/some/file
+ message = $host_data
+</literallayout>
+<para>
+which gives a custom error message for each denied host.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">local_parts = </emphasis><<emphasis>local part list</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>local_parts</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>ACL checking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing a local part</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part_data</varname></primary>
+</indexterm>
+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 <varname>$local_part_data</varname>, which remains set until
+the next <option>local_parts</option> test.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">malware = </emphasis><<emphasis>option</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>malware</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>virus scanning</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>scanning for viruses</secondary>
+</indexterm>
+This condition is available only when Exim is compiled with the
+content-scanning extension
+and only after a DATA command.
+It causes the incoming message to be scanned for
+viruses. For details, see chapter <xref linkend="CHAPexiscan"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">mime_regex = </emphasis><<emphasis>list of regular expressions</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>mime_regex</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing by regex matching</secondary>
+</indexterm>
+This condition is available only when Exim is compiled with the
+content-scanning extension, and it is allowed only in the ACL defined by
+<option>acl_smtp_mime</option>. It causes the current MIME part to be scanned for a match
+with any of the regular expressions. For details, see chapter
+<xref linkend="CHAPexiscan"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">ratelimit = </emphasis><<emphasis>parameters</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>rate limiting</primary>
+</indexterm>
+This condition can be used to limit the rate at which a user or host submits
+messages. Details are given in section <xref linkend="SECTratelimiting"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">recipients = </emphasis><<emphasis>address list</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>recipients</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>recipient</primary>
+<secondary>ACL checking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing a recipient</secondary>
+</indexterm>
+This condition is relevant only after a RCPT command. It checks the entire
+recipient address against a list of recipients.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">regex = </emphasis><<emphasis>list of regular expressions</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>regex</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing by regex matching</secondary>
+</indexterm>
+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 <xref linkend="CHAPexiscan"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">sender_domains = </emphasis><<emphasis>domain list</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>sender_domains</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>ACL checking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing a sender domain</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$sender_address_domain</varname></primary>
+</indexterm>
+This condition tests the domain of the sender of the message against the given
+domain list. <emphasis role="bold">Note</emphasis>: The domain of the sender address is in
+<varname>$sender_address_domain</varname>. It is <emphasis>not</emphasis> put in <varname>$domain</varname> 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 <varname>$domain</varname>) can be used to
+influence the sender checking.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: 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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">senders = </emphasis><<emphasis>address list</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>senders</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>ACL checking</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing a sender</secondary>
+</indexterm>
+This condition tests the sender of the message against the given list. To test
+for a bounce message, which has an empty sender, set
+</para>
+<literallayout class="monospaced">
+senders = :
+</literallayout>
+<para>
+<emphasis role="bold">Warning</emphasis>: 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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">spam = </emphasis><<emphasis>username</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>spam</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>scanning for spam</secondary>
+</indexterm>
+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 <xref linkend="CHAPexiscan"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">verify = certificate</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>verify</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>client certificate verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>certificate</primary>
+<secondary>verification of client</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>certificate verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing a TLS certificate</secondary>
+</indexterm>
+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 <option>tls_verify_hosts</option>
+or <option>tls_try_verify_hosts</option> (see chapter <xref linkend="CHAPTLS"/>).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">verify = csa</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>CSA verification</primary>
+</indexterm>
+This condition checks whether the sending host (the client) is authorized to
+send email. Details of how this works are given in section
+<xref linkend="SECTverifyCSA"/>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">verify = header_names_ascii</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>verify</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>verifying header names only ASCII</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>verifying header names only ASCII</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>verifying</primary>
+<secondary>header names only ASCII</secondary>
+</indexterm>
+This condition is relevant only in an ACL that is run after a message has been
+received, that is, in an ACL specified by <option>acl_smtp_data</option> or
+<option>acl_not_smtp</option>. It checks all header names (not the content) to make sure
+there are no non-ASCII characters, also excluding control characters. The
+allowable characters are decimal ASCII values 33 through 126.
+</para>
+<para>
+Exim itself will handle headers with non-ASCII characters, but it can cause
+problems for downstream applications, so this option will allow their
+detection and rejection in the DATA ACL’s.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">verify = header_sender/</emphasis><<emphasis>options</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>verify</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>verifying sender in the header</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>verifying the sender in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>verifying in header</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>verifying</primary>
+<secondary>sender in header</secondary>
+</indexterm>
+This condition is relevant only in an ACL that is run after a message has been
+received, that is, in an ACL specified by <option>acl_smtp_data</option> or
+<option>acl_not_smtp</option>. It checks that there is a verifiable address in at least one
+of the <emphasis>Sender:</emphasis>, <emphasis>Reply-To:</emphasis>, or <emphasis>From:</emphasis> header lines. Such an address
+is loosely thought of as a <quote>sender</quote> 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.
+</para>
+<para>
+Details of address verification and the options are given later, starting at
+section <xref linkend="SECTaddressverification"/> (callouts are described in section
+<xref linkend="SECTcallver"/>). You can combine this condition with the <option>senders</option>
+condition to restrict it to bounce messages only:
+</para>
+<literallayout class="monospaced">
+deny senders = :
+ !verify = header_sender
+ message = A valid sender header is required for bounces
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">verify = header_syntax</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>verify</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>verifying header syntax</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>verifying syntax</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>verifying</primary>
+<secondary>header syntax</secondary>
+</indexterm>
+This condition is relevant only in an ACL that is run after a message has been
+received, that is, in an ACL specified by <option>acl_smtp_data</option> or
+<option>acl_not_smtp</option>. It checks the syntax of all header lines that can contain
+lists of addresses (<emphasis>Sender:</emphasis>, <emphasis>From:</emphasis>, <emphasis>Reply-To:</emphasis>, <emphasis>To:</emphasis>, <emphasis>Cc:</emphasis>,
+and <emphasis>Bcc:</emphasis>), returning true if there are no problems.
+Unqualified addresses (local parts without domains) are
+permitted only in locally generated messages and from hosts that match
+<option>sender_unqualified_hosts</option> or <option>recipient_unqualified_hosts</option>, as
+appropriate.
+</para>
+<para>
+Note that this condition is a syntax check only. However, a common spamming
+ploy used to be to send syntactically invalid headers such as
+</para>
+<literallayout class="monospaced">
+To: @
+</literallayout>
+<para>
+and this condition can be used to reject such messages, though they are not as
+common as they used to be.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">verify = helo</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>verify</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>verifying HELO/EHLO</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>HELO</primary>
+<secondary>verifying</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>EHLO</primary>
+<secondary>verifying</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>verifying</primary>
+<secondary>EHLO</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>verifying</primary>
+<secondary>HELO</secondary>
+</indexterm>
+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 <option>helo_verify_hosts</option> and
+<option>helo_try_verify_hosts</option> options for details of how to request verification
+independently of this condition, and for detail of the verification.
+</para>
+<para>
+For SMTP input that does not come over TCP/IP (the <option>-bs</option> command line
+option), this condition is always true.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">verify = not_blind/</emphasis><<emphasis>options</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>verifying</primary>
+<secondary>not blind</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>bcc recipients, verifying none</primary>
+</indexterm>
+This condition checks that there are no blind (bcc) recipients in the message.
+Every envelope recipient must appear either in a <emphasis>To:</emphasis> header line or in a
+<emphasis>Cc:</emphasis> header line for this condition to be true. Local parts are checked
+case-sensitively; domains are checked case-insensitively. If <emphasis>Resent-To:</emphasis> or
+<emphasis>Resent-Cc:</emphasis> header lines exist, they are also checked. This condition can be
+used only in a DATA or non-SMTP ACL.
+</para>
+<para>
+There is one possible option, <literal>case_insensitive</literal>. If this is present then
+local parts are checked case-insensitively.
+</para>
+<para>
+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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">verify = recipient/</emphasis><<emphasis>options</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>verify</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>verifying recipient</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>recipient</primary>
+<secondary>verifying</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>verifying</primary>
+<secondary>recipient</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$address_data</varname></primary>
+</indexterm>
+This condition is relevant only after a RCPT command. It verifies the current
+recipient. Details of address verification are given later, starting at section
+<xref linkend="SECTaddressverification"/>. After a recipient has been verified, the value
+of <varname>$address_data</varname> 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 <varname>$address_data</varname> is the
+value for the child address.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">verify = reverse_host_lookup/</emphasis><<emphasis>options</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>verify</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>verifying host reverse lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>verifying reverse lookup</secondary>
+</indexterm>
+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 <option>host_lookup</option>.)
+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.
+</para>
+<para>
+There is one possible option, <literal>defer_ok</literal>. If this is present and a
+DNS operation returns a temporary error, the verify condition succeeds.
+</para>
+<para>
+If this condition is used for a locally generated message (that is, when there
+is no client host involved), it always succeeds.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">verify = sender/</emphasis><<emphasis>options</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>verify</option> ACL condition</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>verifying sender</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>verifying</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>verifying</primary>
+<secondary>sender</secondary>
+</indexterm>
+This condition is relevant only after a MAIL or RCPT command, or after a
+message has been received (the <option>acl_smtp_data</option> or <option>acl_not_smtp</option> 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.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$address_data</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$sender_address_data</varname></primary>
+</indexterm>
+If there is data in the <varname>$address_data</varname> variable at the end of routing, its
+value is placed in <varname>$sender_address_data</varname> 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.
+</para>
+<para>
+Details of verification are given later, starting at section
+<xref linkend="SECTaddressverification"/>. Exim caches the result of sender verification,
+to avoid doing it more than once per message.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">verify = sender=</emphasis><<emphasis>address</emphasis>><emphasis role="bold">/</emphasis><<emphasis>options</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>verify</option> ACL condition</primary>
+</indexterm>
+This is a variation of the previous option, in which a modified address is
+verified as a sender.
+</para>
+<para>
+Note that ’/’ is legal in local-parts; if the address may have such
+(eg. is generated from the received message)
+they must be protected from the options parsing by doubling:
+</para>
+<literallayout class="monospaced">
+verify = sender=${sg{${address:$h_sender:}}{/}{//}}
+</literallayout>
+</listitem></varlistentry>
+</variablelist>
+</section>
+<section id="SECTmorednslists">
+<title>Using DNS lists</title>
+<para>
+<indexterm role="concept">
+<primary>DNS list</primary>
+<secondary>in ACL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>black list (DNS)</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>testing a DNS list</secondary>
+</indexterm>
+In its simplest form, the <option>dnslists</option> 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. (Note that DNS list domains are not mail
+domains, so the <literal>+</literal> syntax for named lists doesn’t work - it is used for
+special options instead.) For example, if the calling host’s IP
+address is 192.168.62.43, and the ACL statement is
+</para>
+<literallayout class="monospaced">
+deny dnslists = blackholes.mail-abuse.org : \
+ dialups.mail-abuse.org
+</literallayout>
+<para>
+the following records are looked up:
+</para>
+<literallayout class="monospaced">
+43.62.168.192.blackholes.mail-abuse.org
+43.62.168.192.dialups.mail-abuse.org
+</literallayout>
+<para>
+As soon as Exim finds an existing DNS record, processing of the list stops.
+Thus, multiple entries on the list provide an <quote>or</quote> conjunction. If you want
+to test that a host is on more than one list (an <quote>and</quote> conjunction), you can
+use two separate conditions:
+</para>
+<literallayout class="monospaced">
+deny dnslists = blackholes.mail-abuse.org
+ dnslists = dialups.mail-abuse.org
+</literallayout>
+<para>
+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.
+</para>
+<para>
+This is usually the required action when <option>dnslists</option> is used with <option>deny</option>
+(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:
+</para>
+<literallayout>
+<literal>+include_unknown </literal> behave as if the item is on the list
+<literal>+exclude_unknown </literal> behave as if the item is not on the list (default)
+<literal>+defer_unknown </literal> give a temporary error
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary><literal>+include_unknown</literal></primary>
+</indexterm>
+<indexterm role="concept">
+<primary><literal>+exclude_unknown</literal></primary>
+</indexterm>
+<indexterm role="concept">
+<primary><literal>+defer_unknown</literal></primary>
+</indexterm>
+Each of these applies to any subsequent items on the list. For example:
+</para>
+<literallayout class="monospaced">
+deny dnslists = +defer_unknown : foo.bar.example
+</literallayout>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+deny dnslists = blackholes.mail-abuse.org
+warn dnslists = dialups.mail-abuse.org
+ message = X-Warn: sending host is on dialups list
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>caching</primary>
+<secondary>of dns lookup</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>TTL</secondary>
+</indexterm>
+DNS list lookups are cached by Exim for the duration of the SMTP session
+(but limited by the DNS return TTL value),
+so a lookup based on the IP address is done at most once for any incoming
+connection (assuming long-enough TTL).
+Exim does not share information between multiple incoming
+connections (but your local name server cache should be active).
+</para>
+<para>
+There are a number of DNS lists to choose from, some commercial, some free,
+or free for small deployments. An overview can be found at
+<emphasis role="bold"><ulink url="https://en.wikipedia.org/wiki/Comparison_of_DNS_blacklists">https://en.wikipedia.org/wiki/Comparison_of_DNS_blacklists</ulink></emphasis>.
+</para>
+</section>
+<section id="SECID201">
+<title>Specifying the IP address for a DNS list lookup</title>
+<para>
+<indexterm role="concept">
+<primary>DNS list</primary>
+<secondary>keyed by explicit IP address</secondary>
+</indexterm>
+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:
+</para>
+<literallayout class="monospaced">
+deny dnslists = black.list.tld/192.168.1.2
+</literallayout>
+<para>
+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
+<xref linkend="SECTmulkeyfor"/> below.
+</para>
+</section>
+<section id="SECID202">
+<title>DNS lists keyed on domain names</title>
+<para>
+<indexterm role="concept">
+<primary>DNS list</primary>
+<secondary>keyed by domain name</secondary>
+</indexterm>
+There are some lists that are keyed on domain names rather than inverted IP
+addresses (see, e.g., the <emphasis>domain based zones</emphasis> link at
+<emphasis role="bold"><ulink url="http://www.rfc-ignorant.org/">http://www.rfc-ignorant.org/</ulink></emphasis>). 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,
+</para>
+<literallayout class="monospaced">
+deny dnslists = dsn.rfc-ignorant.org/$sender_address_domain
+ message = Sender's domain is listed at $dnslist_domain
+</literallayout>
+<para>
+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 <emphasis>user@tld.example</emphasis> the name that is looked
+up by this example is
+</para>
+<literallayout class="monospaced">
+tld.example.dsn.rfc-ignorant.org
+</literallayout>
+<para>
+A single <option>dnslists</option> condition can contain entries for both names and IP
+addresses. For example:
+</para>
+<literallayout class="monospaced">
+deny dnslists = sbl.spamhaus.org : \
+ dsn.rfc-ignorant.org/$sender_address_domain
+</literallayout>
+<para>
+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.
+</para>
+</section>
+<section id="SECTmulkeyfor">
+<title>Multiple explicit keys for a DNS list</title>
+<para>
+<indexterm role="concept">
+<primary>DNS list</primary>
+<secondary>multiple keys for</secondary>
+</indexterm>
+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:
+</para>
+<literallayout class="monospaced">
+dnslists = black.list.tld/name.1::name.2
+</literallayout>
+<para>
+or to change the separator character, like this:
+</para>
+<literallayout class="monospaced">
+dnslists = black.list.tld/<;name.1;name.2
+</literallayout>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+dnslists = black.list.tld/<;192.168.1.2;a.domain
+</literallayout>
+<para>
+The DNS lookups that occur are:
+</para>
+<literallayout class="monospaced">
+2.1.168.192.black.list.tld
+a.domain.black.list.tld
+</literallayout>
+<para>
+Once a DNS record has been found (that matches a specific IP return
+address, if specified – see section <xref linkend="SECTaddmatcon"/>), 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.
+</para>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+dnslists = black.list.tld/a.domain : black.list.tld/b.domain
+dnslists = black.list.tld/a.domain::b.domain
+</literallayout>
+<para>
+However, when the data for the list is obtained from a lookup, the second form
+is usually much more convenient. Consider this example:
+</para>
+<literallayout class="monospaced">
+deny dnslists = sbl.spamhaus.org/<|${lookup dnsdb {>|a=<|\
+ ${lookup dnsdb {>|mxh=\
+ $sender_address_domain} }} }
+ message = The mail servers for the domain \
+ $sender_address_domain \
+ are listed at $dnslist_domain ($dnslist_value); \
+ see $dnslist_text.
+</literallayout>
+<para>
+Note the use of <literal>>|</literal> 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:
+</para>
+<literallayout class="monospaced">
+dnslists = sbl.spamhaus.org/<|192.168.2.3|192.168.5.6|...
+</literallayout>
+<para>
+Thus, this example checks whether or not the IP addresses of the sender
+domain’s mail servers are on the Spamhaus black list.
+</para>
+<para>
+The key that was used for a successful DNS list lookup is put into the variable
+<varname>$dnslist_matched</varname> (see section <xref linkend="SECID204"/>).
+</para>
+</section>
+<section id="SECID203">
+<title>Data returned by DNS lists</title>
+<para>
+<indexterm role="concept">
+<primary>DNS list</primary>
+<secondary>data returned from</secondary>
+</indexterm>
+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:
+</para>
+<literallayout>
+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
+</literallayout>
+<para>
+Section <xref linkend="SECTaddmatcon"/> below describes how you can distinguish between
+different values. Some DNS lists may return more than one address record;
+see section <xref linkend="SECThanmuldnsrec"/> for details of how they are checked.
+</para>
+</section>
+<section id="SECID204">
+<title>Variables set from DNS lists</title>
+<para>
+<indexterm role="concept">
+<primary>expansion</primary>
+<secondary>variables, set from DNS list</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS list</primary>
+<secondary>variables set from</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$dnslist_domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$dnslist_matched</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$dnslist_text</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$dnslist_value</varname></primary>
+</indexterm>
+When an entry is found in a DNS list, the variable <varname>$dnslist_domain</varname> contains
+the name of the overall domain that matched (for example,
+<literal>spamhaus.example</literal>), <varname>$dnslist_matched</varname> contains the key within that domain
+(for example, <literal>192.168.5.3</literal>), and <varname>$dnslist_value</varname> contains the data from
+the DNS record. When the key is an IP address, it is not reversed in
+<varname>$dnslist_matched</varname> (though it is, of course, in the actual lookup). In simple
+cases, for example:
+</para>
+<literallayout class="monospaced">
+deny dnslists = spamhaus.example
+</literallayout>
+<para>
+the key is also available in another variable (in this case,
+<varname>$sender_host_address</varname>). In more complicated cases, however, this is not true.
+For example, using a data lookup (as described in section <xref linkend="SECTmulkeyfor"/>)
+might generate a dnslists lookup like this:
+</para>
+<literallayout class="monospaced">
+deny dnslists = spamhaus.example/<|192.168.1.2|192.168.6.7|...
+</literallayout>
+<para>
+If this condition succeeds, the value in <varname>$dnslist_matched</varname> might be
+<literal>192.168.6.7</literal> (for example).
+</para>
+<para>
+If more than one address record is returned by the DNS lookup, all the IP
+addresses are included in <varname>$dnslist_value</varname>, separated by commas and spaces.
+The variable <varname>$dnslist_text</varname> 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 <xref linkend="SECTmordetinf"/> for a way of obtaining more
+information.
+</para>
+<para>
+You can use the DNS list variables in <option>message</option> or <option>log_message</option> modifiers
+– even if these appear before the condition in the ACL, they are not
+expanded until after it has failed. For example:
+</para>
+<literallayout class="monospaced">
+deny hosts = !+local_networks
+ message = $sender_host_address is listed \
+ at $dnslist_domain
+ dnslists = rbl-plus.mail-abuse.example
+</literallayout>
+</section>
+<section id="SECTaddmatcon">
+<title>Additional matching conditions for DNS lists</title>
+<para>
+<indexterm role="concept">
+<primary>DNS list</primary>
+<secondary>matching specific returned data</secondary>
+</indexterm>
+You can add an equals sign and an IP address after a <option>dnslists</option> domain name
+in order to restrict its action to DNS records with a matching right hand side.
+For example,
+</para>
+<literallayout class="monospaced">
+deny dnslists = rblplus.mail-abuse.org=127.0.0.2
+</literallayout>
+<para>
+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 <xref linkend="SECThanmuldnsrec"/>
+describes how multiple records are handled.
+</para>
+<para>
+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
+<option>dnslists</option> condition is true. For example:
+</para>
+<literallayout class="monospaced">
+deny dnslists = a.b.c=127.0.0.2,127.0.0.3
+</literallayout>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+deny dnslists = dsn.rfc-ignorant.org\
+ =127.0.0.2/$sender_address_domain
+</literallayout>
+<para>
+If the character <literal>&</literal> is used instead of <literal>=</literal>, the comparison for each
+listed IP address is done by a bitwise <quote>and</quote> 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:
+</para>
+<literallayout class="monospaced">
+dnslists = a.b.c&0.0.0.3
+</literallayout>
+<para>
+matches if the address is <emphasis>x.x.x.</emphasis>3, <emphasis>x.x.x.</emphasis>7, <emphasis>x.x.x.</emphasis>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:
+</para>
+<literallayout class="monospaced">
+dnslists = a.b.c&0.0.0.1,0.0.0.2
+</literallayout>
+<para>
+matches if the final component of the address is an odd number or two times
+an odd number.
+</para>
+</section>
+<section id="SECID205">
+<title>Negated DNS matching conditions</title>
+<para>
+You can supply a negative list of IP addresses as part of a <option>dnslists</option>
+condition. Whereas
+</para>
+<literallayout class="monospaced">
+deny dnslists = a.b.c=127.0.0.2,127.0.0.3
+</literallayout>
+<para>
+means <quote>deny if the host is in the black list at the domain <emphasis>a.b.c</emphasis> and the
+IP address yielded by the list is either 127.0.0.2 or 127.0.0.3</quote>,
+</para>
+<literallayout class="monospaced">
+deny dnslists = a.b.c!=127.0.0.2,127.0.0.3
+</literallayout>
+<para>
+means <quote>deny if the host is in the black list at the domain <emphasis>a.b.c</emphasis> and the
+IP address yielded by the list is not 127.0.0.2 and not 127.0.0.3</quote>. In other
+words, the result of the test is inverted if an exclamation mark appears before
+the <literal>=</literal> (or the <literal>&</literal>) sign.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: This kind of negation is not the same as negation in a domain,
+host, or address list (which is why the syntax is different).
+</para>
+<para>
+If you are using just one list, the negation syntax does not gain you much. The
+previous example is precisely equivalent to
+</para>
+<literallayout class="monospaced">
+deny dnslists = a.b.c
+ !dnslists = a.b.c=127.0.0.2,127.0.0.3
+</literallayout>
+<para>
+However, if you are using multiple lists, the negation syntax is clearer.
+Consider this example:
+</para>
+<literallayout class="monospaced">
+deny dnslists = sbl.spamhaus.org : \
+ list.dsbl.org : \
+ dnsbl.njabl.org!=127.0.0.3 : \
+ relays.ordb.org
+</literallayout>
+<para>
+Using only positive lists, this would have to be:
+</para>
+<literallayout class="monospaced">
+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
+</literallayout>
+<para>
+which is less clear, and harder to maintain.
+</para>
+</section>
+<section id="SECThanmuldnsrec">
+<title>Handling multiple DNS records from a DNS list</title>
+<para>
+A DNS lookup for a <option>dnslists</option> condition may return more than one DNS record,
+thereby providing more than one IP address. When an item in a <option>dnslists</option> list
+is followed by <literal>=</literal> or <literal>&</literal> 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:
+</para>
+<literallayout class="monospaced">
+dnslists = a.b.c=127.0.0.1
+</literallayout>
+<para>
+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 <literal>==</literal> and <literal>=&</literal>.
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If <literal>=</literal> or <literal>&</literal> 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.
+</para>
+</listitem>
+<listitem>
+<para>
+If <literal>==</literal> or <literal>=&</literal> 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:
+</para>
+<literallayout class="monospaced">
+dnslists = a.b.c==127.0.0.1
+</literallayout>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+dnslists = a.b.c==127.0.0.1,127.0.0.2
+</literallayout>
+<para>
+for the condition to be true.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+When <literal>!</literal> is used to negate IP address matching, it inverts the result, giving
+the precise opposite of the behaviour above. Thus:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If <literal>!=</literal> or <literal>!&</literal> is used, the condition is true if none of the looked up IP
+addresses matches one of the listed addresses. Consider:
+</para>
+<literallayout class="monospaced">
+dnslists = a.b.c!&0.0.0.1
+</literallayout>
+<para>
+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.
+</para>
+</listitem>
+<listitem>
+<para>
+If <literal>!==</literal> or <literal>!=&</literal> is used, the condition is true if there is at least one
+looked up IP address that does not match. Consider:
+</para>
+<literallayout class="monospaced">
+dnslists = a.b.c!=&0.0.0.1
+</literallayout>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+dnslists = a.b.c!=&0.0.0.1,0.0.0.2
+</literallayout>
+<para>
+for the condition to be false.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+When the DNS lookup yields only a single IP address, there is no difference
+between <literal>=</literal> and <literal>==</literal> and between <literal>&</literal> and <literal>=&</literal>.
+</para>
+</section>
+<section id="SECTmordetinf">
+<title>Detailed information from merged DNS lists</title>
+<para>
+<indexterm role="concept">
+<primary>DNS list</primary>
+<secondary>information from merged</secondary>
+</indexterm>
+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 <varname>$dnslist_text</varname> 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.
+</para>
+<para>
+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 <varname>$dnslist_domain</varname>. For example:
+</para>
+<literallayout class="monospaced">
+deny dnslists = \
+ sbl.spamhaus.org,sbl-xbl.spamhaus.org=127.0.0.2 : \
+ dul.dnsbl.sorbs.net,dnsbl.sorbs.net=127.0.0.10
+ message = \
+ rejected because $sender_host_address is blacklisted \
+ at $dnslist_domain\n$dnslist_text
+</literallayout>
+<para>
+For the first blacklist item, this starts by doing a lookup in
+<emphasis>sbl-xbl.spamhaus.org</emphasis> and testing for a 127.0.0.2 return. If there is a
+match, it then looks in <emphasis>sbl.spamhaus.org</emphasis>, 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 <emphasis>sbl-xbl.spamhaus.org</emphasis>, nothing more is done.
+The second blacklist item is processed similarly.
+</para>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+deny 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
+</literallayout>
+<para>
+In this case there is one lookup in <emphasis>dnsbl.sorbs.net</emphasis>, 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.
+</para>
+</section>
+<section id="SECTmorednslistslast">
+<title>DNS lists and IPv6</title>
+<para>
+<indexterm role="concept">
+<primary>IPv6</primary>
+<secondary>DNS black lists</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS list</primary>
+<secondary>IPv6 usage</secondary>
+</indexterm>
+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
+</para>
+<literallayout class="monospaced">
+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
+</literallayout>
+<para>
+(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
+</para>
+<literallayout class="monospaced">
+*.3.some.list.example. A 127.0.0.1
+</literallayout>
+<para>
+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.
+</para>
+<para>
+You can exclude IPv6 addresses from DNS lookups by making use of a suitable
+<option>condition</option> condition, as in this example:
+</para>
+<literallayout class="monospaced">
+deny condition = ${if isip4{$sender_host_address}}
+ dnslists = some.list.example
+</literallayout>
+<para>
+If an explicit key is being used for a DNS lookup and it may be an IPv6
+address you should specify alternate list separators for both the outer
+(DNS list name) list and inner (lookup keys) list:
+</para>
+<literallayout class="monospaced">
+ dnslists = <; dnsbl.example.com/<|$acl_m_addrslist
+</literallayout>
+</section>
+<section id="SECTratelimiting">
+<title>Rate limiting incoming messages</title>
+<para>
+<indexterm role="concept">
+<primary>rate limiting</primary>
+<secondary>client sending</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>limiting client sending rates</primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>smtp_ratelimit_*</option></primary>
+</indexterm>
+The <option>ratelimit</option> ACL condition can be used to measure and control the rate at
+which clients can send email. This is more powerful than the
+<option>smtp_ratelimit_*</option> options, because those options control the rate of
+commands in a single SMTP session only, whereas the <option>ratelimit</option> condition
+works across all connections (concurrent and sequential) from the same client
+host. The syntax of the <option>ratelimit</option> condition is:
+</para>
+<literallayout>
+<literal>ratelimit =</literal> <<emphasis>m</emphasis>> <literal>/</literal> <<emphasis>p</emphasis>> <literal>/</literal> <<emphasis>options</emphasis>> <literal>/</literal> <<emphasis>key</emphasis>>
+</literallayout>
+<para>
+If the average client sending rate is less than <emphasis>m</emphasis> messages per time
+period <emphasis>p</emphasis> then the condition is false; otherwise it is true.
+</para>
+<para>
+As a side-effect, the <option>ratelimit</option> condition sets the expansion variable
+<varname>$sender_rate</varname> to the client’s computed rate, <varname>$sender_rate_limit</varname> to the
+configured value of <emphasis>m</emphasis>, and <varname>$sender_rate_period</varname> to the configured value
+of <emphasis>p</emphasis>.
+</para>
+<para>
+The parameter <emphasis>p</emphasis> is the smoothing time constant, in the form of an Exim
+time interval, for example, <literal>8h</literal> for eight hours. A larger time constant
+means that it takes Exim longer to forget a client’s past behaviour. The
+parameter <emphasis>m</emphasis> 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 <emphasis>m</emphasis> and <emphasis>p</emphasis> but keeping <emphasis>m/p</emphasis>
+constant, you can allow a client to send more messages in a burst without
+changing its long-term sending rate limit. Conversely, if <emphasis>m</emphasis> and <emphasis>p</emphasis> are
+both small, messages must be sent at an even rate.
+</para>
+<para>
+There is a script in <filename>util/ratelimit.pl</filename> which extracts sending rates from
+log files, to assist with choosing appropriate settings for <emphasis>m</emphasis> and <emphasis>p</emphasis>
+when deploying the <option>ratelimit</option> ACL condition. The script prints usage
+instructions when it is run with no arguments.
+</para>
+<para>
+The key is used to look up the data for calculating the client’s average
+sending rate. This data is stored in Exim’s spool directory, alongside the
+retry and other hints databases. The default key is <varname>$sender_host_address</varname>,
+which means Exim computes the sending rate of 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
+<varname>$authenticated_id</varname>. You must ensure that the lookup key is meaningful; for
+example, <varname>$authenticated_id</varname> is only meaningful if the client has
+authenticated (which you can check with the <option>authenticated</option> ACL condition).
+</para>
+<para>
+The lookup key does not have to identify clients: If you want to limit the
+rate at which a recipient receives messages, you can use the key
+<literal>$local_part@$domain</literal> with the <option>per_rcpt</option> option (see below) in a RCPT
+ACL.
+</para>
+<para>
+Each <option>ratelimit</option> condition can have up to four options. A <option>per_*</option> option
+specifies what Exim measures the rate of, for example, messages or recipients
+or bytes. You can adjust the measurement using the <option>unique=</option> and/or
+<option>count=</option> options. You can also control when Exim updates the recorded rate
+using a <option>strict</option>, <option>leaky</option>, or <option>readonly</option> option. The options are
+separated by a slash, like the other parameters. They may appear in any order.
+</para>
+<para>
+Internally, Exim appends the smoothing constant <emphasis>p</emphasis> onto the lookup key with
+any options that alter the meaning of the stored data. The limit <emphasis>m</emphasis> is not
+stored, so you can alter the configured maximum rate and Exim will still
+remember clients’ past behaviour. If you change the <option>per_*</option> mode or add or
+remove the <option>unique=</option> option, the lookup key changes so Exim will forget past
+behaviour. The lookup key is not affected by changes to the update mode and
+the <option>count=</option> option.
+</para>
+</section>
+<section id="ratoptmea">
+<title>Ratelimit options for what is being measured</title>
+<para>
+<indexterm role="concept">
+<primary>rate limiting</primary>
+<secondary>per_* options</secondary>
+</indexterm>
+The <option>per_conn</option> option limits the client’s connection rate. It is not
+normally used in the <option>acl_not_smtp</option>, <option>acl_not_smtp_mime</option>, or
+<option>acl_not_smtp_start</option> ACLs.
+</para>
+<para>
+The <option>per_mail</option> option limits the client’s rate of sending messages. This is
+the default if none of the <option>per_*</option> options is specified. It can be used in
+<option>acl_smtp_mail</option>, <option>acl_smtp_rcpt</option>, <option>acl_smtp_predata</option>, <option>acl_smtp_mime</option>,
+<option>acl_smtp_data</option>, or <option>acl_not_smtp</option>.
+</para>
+<para>
+The <option>per_byte</option> option limits the sender’s email bandwidth. It can be used in
+the same ACLs as the <option>per_mail</option> option, though it is best to use this option
+in the <option>acl_smtp_mime</option>, <option>acl_smtp_data</option> or <option>acl_not_smtp</option> ACLs; if it is
+used in an earlier ACL, Exim relies on the SIZE parameter given by the client
+in its MAIL command, which may be inaccurate or completely missing. You can
+follow the limit <emphasis>m</emphasis> in the configuration with K, M, or G to specify limits
+in kilobytes, megabytes, or gigabytes, respectively.
+</para>
+<para>
+The <option>per_rcpt</option> option causes Exim to limit the rate at which recipients are
+accepted. It can be used in the <option>acl_smtp_rcpt</option>, <option>acl_smtp_predata</option>,
+<option>acl_smtp_mime</option>, <option>acl_smtp_data</option>, or <option>acl_smtp_rcpt</option> ACLs. In
+<option>acl_smtp_rcpt</option> the rate is updated one recipient at a time; in the other
+ACLs the rate is updated with the total (accepted) recipient count in one go. Note that
+in either case the rate limiting engine will see a message with many
+recipients as a large high-speed burst.
+</para>
+<para>
+The <option>per_addr</option> option is like the <option>per_rcpt</option> option, except it counts the
+number of different recipients that the client has sent messages to in the
+last time period. That is, if the client repeatedly sends messages to the same
+recipient, its measured rate is not increased. This option can only be used in
+<option>acl_smtp_rcpt</option>.
+</para>
+<para>
+The <option>per_cmd</option> option causes Exim to recompute the rate every time the
+condition is processed. This can be used to limit the rate of any SMTP
+command. If it is used in multiple ACLs it can limit the aggregate rate of
+multiple different commands.
+</para>
+<para>
+The <option>count=</option> option can be used to alter how much Exim adds to the client’s
+measured rate. For example, the <option>per_byte</option> option is equivalent to
+<literal>per_mail/count=$message_size</literal>. If there is no <option>count=</option> option, Exim
+increases the measured rate by one (except for the <option>per_rcpt</option> option in ACLs
+other than <option>acl_smtp_rcpt</option>). The count does not have to be an integer.
+</para>
+<para>
+The <option>unique=</option> option is described in section <xref linkend="ratoptuniq"/> below.
+</para>
+</section>
+<section id="ratoptupd">
+<title>Ratelimit update modes</title>
+<para>
+<indexterm role="concept">
+<primary>rate limiting</primary>
+<secondary>reading data without updating</secondary>
+</indexterm>
+You can specify one of three options with the <option>ratelimit</option> condition to
+control when its database is updated. This section describes the <option>readonly</option>
+mode, and the next section describes the <option>strict</option> and <option>leaky</option> modes.
+</para>
+<para>
+If the <option>ratelimit</option> condition is used in <option>readonly</option> mode, Exim looks up a
+previously-computed rate to check against the limit.
+</para>
+<para>
+For example, you can test the client’s sending rate and deny it access (when
+it is too fast) in the connect ACL. If the client passes this check then it
+can go on to send a message, in which case its recorded rate will be updated
+in the MAIL ACL. Subsequent connections from the same client will check this
+new rate.
+</para>
+<literallayout class="monospaced">
+acl_check_connect:
+ deny ratelimit = 100 / 5m / readonly
+ log_message = RATE CHECK: $sender_rate/$sender_rate_period \
+ (max $sender_rate_limit)
+# ...
+acl_check_mail:
+ warn ratelimit = 100 / 5m / strict
+ log_message = RATE UPDATE: $sender_rate/$sender_rate_period \
+ (max $sender_rate_limit)
+</literallayout>
+<para>
+If Exim encounters multiple <option>ratelimit</option> conditions with the same key when
+processing a message then it may increase the client’s measured rate more than
+it should. For example, this will happen if you check the <option>per_rcpt</option> option
+in both <option>acl_smtp_rcpt</option> and <option>acl_smtp_data</option>. However it’s OK to check the
+same <option>ratelimit</option> condition multiple times in the same ACL. You can avoid any
+multiple update problems by using the <option>readonly</option> option on later ratelimit
+checks.
+</para>
+<para>
+The <option>per_*</option> options described above do not make sense in some ACLs. If you
+use a <option>per_*</option> option in an ACL where it is not normally permitted then the
+update mode defaults to <option>readonly</option> and you cannot specify the <option>strict</option> or
+<option>leaky</option> modes. In other ACLs the default update mode is <option>leaky</option> (see the
+next section) so you must specify the <option>readonly</option> option explicitly.
+</para>
+</section>
+<section id="ratoptfast">
+<title>Ratelimit options for handling fast clients</title>
+<para>
+<indexterm role="concept">
+<primary>rate limiting</primary>
+<secondary>strict and leaky modes</secondary>
+</indexterm>
+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
+<option>strict</option> or <option>leaky</option> update modes. This is independent of the other
+counter-measures (such as rejecting the message) that may be specified by the
+rest of the ACL.
+</para>
+<para>
+The <option>leaky</option> (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,
+up to the given limit.
+This is appropriate if the countermeasure when the condition is true
+consists of refusing the message, and
+is generally the better choice if you have clients that retry automatically.
+If the action when true is anything more complex then this option is
+likely not what is wanted.
+</para>
+<para>
+The <option>strict</option> 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 by the ACL. It must slow down and allow sufficient time to
+pass that its computed rate falls below the maximum before it can send email
+again. The time (the number of smoothing periods) it must wait and not
+attempt to send mail can be calculated with this formula:
+</para>
+<literallayout class="monospaced">
+ ln(peakrate/maxrate)
+</literallayout>
+</section>
+<section id="ratoptuniq">
+<title>Limiting the rate of different events</title>
+<para>
+<indexterm role="concept">
+<primary>rate limiting</primary>
+<secondary>counting unique events</secondary>
+</indexterm>
+The <option>ratelimit</option> <option>unique=</option> option controls a mechanism for counting the
+rate of different events. For example, the <option>per_addr</option> option uses this
+mechanism to count the number of different recipients that the client has
+sent messages to in the last time period; it is equivalent to
+<literal>per_rcpt/unique=$local_part@$domain</literal>. You could use this feature to
+measure the rate that a client uses different sender addresses with the
+options <literal>per_mail/unique=$sender_address</literal>.
+</para>
+<para>
+For each <option>ratelimit</option> key Exim stores the set of <option>unique=</option> values that it
+has seen for that key. The whole set is thrown away when it is older than the
+rate smoothing period <emphasis>p</emphasis>, so each different event is counted at most once
+per period. In the <option>leaky</option> update mode, an event that causes the client to
+go over the limit is not added to the set, in the same way that the client’s
+recorded rate is not updated in the same situation.
+</para>
+<para>
+When you combine the <option>unique=</option> and <option>readonly</option> options, the specific
+<option>unique=</option> value is ignored, and Exim just retrieves the client’s stored
+rate.
+</para>
+<para>
+The <option>unique=</option> mechanism needs more space in the ratelimit database than the
+other <option>ratelimit</option> options in order to store the event set. The number of
+unique values is potentially as large as the rate limit, so the extra space
+required increases with larger limits.
+</para>
+<para>
+The uniqueification is not perfect: there is a small probability that Exim
+will think a new event has happened before. If the sender’s rate is less than
+the limit, Exim should be more than 99.9% correct. However in <option>strict</option> mode
+the measured rate can go above the limit, in which case Exim may under-count
+events by a significant margin. Fortunately, if the rate is high enough (2.7
+times the limit) that the false positive rate goes above 9%, then Exim will
+throw away the over-full event set before the measured rate falls below the
+limit. Therefore the only harm should be that exceptionally high sending rates
+are logged incorrectly; any countermeasures you configure will be as effective
+as intended.
+</para>
+</section>
+<section id="useratlim">
+<title>Using rate limiting</title>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+# 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 ratelimit = 10 / 1s / $primary_hostname
+ message = Sorry, too busy. Try again later.
+
+# Restrict incoming rate from each host, with a default
+# set using a macro and special cases looked up in a table.
+defer ratelimit = ${lookup {$sender_host_address} \
+ cdb {DB/ratelimits.cdb} \
+ {$value} {RATELIMIT} }
+ message = Sender rate exceeds $sender_rate_limit \
+ messages per $sender_rate_period
+</literallayout>
+<para>
+<emphasis role="bold">Warning</emphasis>: If you have a busy server with a lot of <option>ratelimit</option> tests,
+especially with the <option>per_rcpt</option> 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 <filename>/var/spool/exim/db/</filename>). However
+this means that Exim will lose its hints data after a reboot (including retry
+hints, the callout cache, and ratelimit data).
+</para>
+</section>
+<section id="SECTaddressverification">
+<title>Address verification</title>
+<para>
+<indexterm role="concept">
+<primary>verifying address</primary>
+<secondary>options for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>policy control</primary>
+<secondary>address verification</secondary>
+</indexterm>
+Several of the <option>verify</option> conditions described in section
+<xref linkend="SECTaclconditions"/> cause addresses to be verified. Section
+<xref linkend="SECTsenaddver"/> 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:
+</para>
+<literallayout class="monospaced">
+verify = sender/callout
+verify = recipient/defer_ok/callout=10s,defer_ok
+</literallayout>
+<para>
+The first stage of address verification, which always happens, is to run the
+address through the routers, in <quote>verify mode</quote>. 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 <option>verify</option> and <option>verify_only</option>
+(see chapter <xref linkend="CHAProutergeneric"/>). If routing fails, verification fails.
+The available options are as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+If the <option>callout</option> option is specified, successful routing to one or more
+remote hosts is followed by a <quote>callout</quote> to those hosts as an additional
+check. Callouts and their sub-options are discussed in the next section.
+</para>
+</listitem>
+<listitem>
+<para>
+If there is a defer error while doing verification routing, the ACL
+normally returns <quote>defer</quote>. However, if you include <option>defer_ok</option> 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.
+</para>
+</listitem>
+<listitem>
+<para>
+The <option>no_details</option> option is covered in section <xref linkend="SECTsenaddver"/>, which
+discusses the reporting of sender address verification failures.
+</para>
+</listitem>
+<listitem>
+<para>
+The <option>success_on_redirect</option> 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 <xref linkend="SECTredirwhilveri"/>.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+<indexterm role="concept">
+<primary>verifying address</primary>
+<secondary>differentiating failures</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$recipient_verify_failure</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$sender_verify_failure</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$acl_verify_message</varname></primary>
+</indexterm>
+After an address verification failure, <varname>$acl_verify_message</varname> contains the
+error message that is associated with the failure. It can be preserved by
+coding like this:
+</para>
+<literallayout class="monospaced">
+warn !verify = sender
+ set acl_m0 = $acl_verify_message
+</literallayout>
+<para>
+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.
+</para>
+<para>
+In addition, <varname>$sender_verify_failure</varname> or <varname>$recipient_verify_failure</varname> (as
+appropriate) contains one of the following words:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<option>qualify</option>: The address was unqualified (no domain), and the message
+was neither local nor came from an exempted host.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>route</option>: Routing failed.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>mail</option>: Routing succeeded, and a callout was attempted; rejection
+occurred at or before the MAIL command (that is, on initial
+connection, HELO, or MAIL).
+</para>
+</listitem>
+<listitem>
+<para>
+<option>recipient</option>: The RCPT command in a callout was rejected.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>postmaster</option>: The postmaster check in a callout was rejected.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The main use of these variables is expected to be to distinguish between
+rejections of MAIL and rejections of RCPT in callouts.
+</para>
+<para>
+The above variables may also be set after a <emphasis role="bold">successful</emphasis>
+address verification to:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<option>random</option>: A random local-part callout succeeded
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECTcallver">
+<title>Callout verification</title>
+<para>
+<indexterm role="concept">
+<primary>verifying address</primary>
+<secondary>by callout</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary>verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>callout verification</secondary>
+</indexterm>
+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
+<emphasis>callback</emphasis> to a delivery host for the sender address or a <emphasis>callforward</emphasis> to
+a subsequent host for a recipient address, to see if the host accepts the
+address. We use the term <emphasis>callout</emphasis> 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.
+</para>
+<para>
+Exim does not do callouts by default. If you want them to happen, you must
+request them by setting appropriate options on the <option>verify</option> 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 <xref linkend="SECTcallvercache"/>.
+</para>
+<para>
+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.
+</para>
+<para>
+If the <option>callout</option> 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 <command>dnslookup</command> or a
+<command>manualroute</command> router, where the router specifies the hosts. However, if a
+router that does not set up hosts routes to an <command>smtp</command> transport with a
+<option>hosts</option> setting, the transport’s hosts are used. If an <command>smtp</command> transport has
+<option>hosts_override</option> set, its hosts are always used, whether or not the router
+supplies a host list.
+Callouts are only supported on <command>smtp</command> transports.
+</para>
+<para>
+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 <option>helo_data</option> option; if there is no transport, the value of
+<varname>$smtp_active_hostname</varname> is used.
+</para>
+<para>
+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:
+</para>
+<literallayout>
+<literal>HELO </literal><<emphasis>local host name</emphasis>>
+<literal>MAIL FROM:<></literal>
+<literal>RCPT TO:</literal><<emphasis>the address to be tested</emphasis>>
+<literal>QUIT</literal>
+</literallayout>
+<para>
+LHLO is used instead of HELO if the transport’s <option>protocol</option> option is
+set to <quote>lmtp</quote>.
+</para>
+<para>
+The callout may use EHLO, AUTH and/or STARTTLS given appropriate option
+settings.
+</para>
+<para>
+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
+<option>use_sender</option> and <option>use_postmaster</option> options, described in the next section.
+</para>
+<para>
+If the response to the RCPT command is a 2<emphasis>xx</emphasis> code, the verification
+succeeds. If it is 5<emphasis>xx</emphasis>, 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 <quote>defer</quote>, unless the <option>defer_ok</option> parameter of the
+<option>callout</option> option is given, in which case the condition is forced to succeed.
+</para>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>output flushing, disabling for callout</secondary>
+</indexterm>
+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 <option>control</option> modifier to set <option>no_callout_flush</option>.
+</para>
+</section>
+<section id="CALLaddparcall">
+<title>Additional parameters for callouts</title>
+<para>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary>additional parameters for</secondary>
+</indexterm>
+The <option>callout</option> option can be followed by an equals sign and a number of
+optional parameters, separated by commas. For example:
+</para>
+<literallayout class="monospaced">
+verify = recipient/callout=10s,defer_ok
+</literallayout>
+<para>
+The old syntax, which had <option>callout_defer_ok</option> and <option>check_postmaster</option> as
+separate verify options, is retained for backwards compatibility, but is now
+deprecated. The additional parameters for <option>callout</option> are as follows:
+</para>
+<variablelist>
+<varlistentry>
+<term><<emphasis>a time interval</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary>timeout, specifying</secondary>
+</indexterm>
+This specifies the timeout that applies for the callout attempt to each host.
+For example:
+</para>
+<literallayout class="monospaced">
+verify = sender/callout=5s
+</literallayout>
+<para>
+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 <option>connect</option> parameter.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">connect = </emphasis><<emphasis>time interval</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary>connection timeout, specifying</secondary>
+</indexterm>
+This parameter makes it possible to set a different (usually smaller) timeout
+for making the SMTP connection. For example:
+</para>
+<literallayout class="monospaced">
+verify = sender/callout=5s,connect=1s
+</literallayout>
+<para>
+If not specified, this timeout defaults to the general timeout value.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">defer_ok</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary>defer, action on</secondary>
+</indexterm>
+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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">fullpostmaster</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary>full postmaster check</secondary>
+</indexterm>
+This operates like the <option>postmaster</option> option (see below), but if the check for
+<emphasis>postmaster@domain</emphasis> fails, it tries just <emphasis>postmaster</emphasis>, without a domain, in
+accordance with the specification in RFC 2821. The RFC states that the
+unqualified address <emphasis>postmaster</emphasis> should be accepted.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">mailfrom = </emphasis><<emphasis>email address</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary>sender when verifying header</secondary>
+</indexterm>
+When verifying addresses in header lines using the <option>header_sender</option>
+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 <option>mailfrom</option> callout parameter allows you to specify what
+address to use in the MAIL command. For example:
+</para>
+<literallayout class="monospaced">
+require verify = header_sender/callout=mailfrom=abcd@x.y.z
+</literallayout>
+<para>
+This parameter is available only for the <option>header_sender</option> verification option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">maxwait = </emphasis><<emphasis>time interval</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary>overall timeout, specifying</secondary>
+</indexterm>
+This parameter sets an overall timeout for performing a callout verification.
+For example:
+</para>
+<literallayout class="monospaced">
+verify = sender/callout=5s,maxwait=30s
+</literallayout>
+<para>
+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).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">no_cache</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary>cache, suppressing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>caching callout, suppressing</primary>
+</indexterm>
+When this parameter is given, the callout cache is neither read nor updated.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">postmaster</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary>postmaster; checking</secondary>
+</indexterm>
+When this parameter is set, a successful callout check is followed by a similar
+check for the local part <emphasis>postmaster</emphasis> at the same domain. If this address is
+rejected, the callout fails (but see <option>fullpostmaster</option> 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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">postmaster_mailfrom = </emphasis><<emphasis>email address</emphasis>></term>
+<listitem>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+require verify = sender/callout=postmaster_mailfrom=abc@x.y.z
+</literallayout>
+<para>
+If both <option>postmaster</option> and <option>postmaster_mailfrom</option> are present, the rightmost
+one overrides. The <option>postmaster</option> parameter is equivalent to this example:
+</para>
+<literallayout class="monospaced">
+require verify = sender/callout=postmaster_mailfrom=
+</literallayout>
+<para>
+<emphasis role="bold">Warning</emphasis>: 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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">random</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary><quote>random</quote> check</secondary>
+</indexterm>
+When this parameter is set, before doing the normal callout check, Exim does a
+check for a <quote>random</quote> local part at the same domain. The local part is not
+really random – it is defined by the expansion of the option
+<option>callout_random_local_part</option>, which defaults to
+</para>
+<literallayout class="monospaced">
+$primary_hostname-$tod_epoch-testing
+</literallayout>
+<para>
+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 <quote>random</quote> 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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">use_postmaster</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary>sender for recipient check</secondary>
+</indexterm>
+This parameter applies to recipient callouts only. For example:
+</para>
+<literallayout class="monospaced">
+deny !verify = recipient/callout=use_postmaster
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$qualify_domain</varname></primary>
+</indexterm>
+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 <quote>random</quote> check if
+that is configured. The local part of the address is <literal>postmaster</literal> and the
+domain is the contents of <varname>$qualify_domain</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">use_sender</emphasis></term>
+<listitem>
+<para>
+This option applies to recipient callouts only. For example:
+</para>
+<literallayout class="monospaced">
+require verify = recipient/callout=use_sender
+</literallayout>
+<para>
+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.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">hold</emphasis></term>
+<listitem>
+<para>
+This option applies to recipient callouts only. For example:
+</para>
+<literallayout class="monospaced">
+require verify = recipient/callout=use_sender,hold
+</literallayout>
+<para>
+It causes the connection to be held open and used for any further recipients
+and for eventual delivery (should that be done quickly).
+Doing this saves on TCP and SMTP startup costs, and TLS costs also
+when that is used for the connections.
+The advantage is only gained if there are no callout cache hits
+(which could be enforced by the no_cache option),
+if the use_sender option is used,
+if neither the random nor the use_postmaster option is used,
+and if no other callouts intervene.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+If you use any of the parameters that set a non-empty sender for the MAIL
+command (<option>mailfrom</option>, <option>postmaster_mailfrom</option>, <option>use_postmaster</option>, or
+<option>use_sender</option>), 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 <option>use_postmaster</option> or <option>use_sender</option> in
+these circumstances.
+</para>
+<para>
+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.
+</para>
+<para>
+Another issue to think about when using non-empty senders for callouts is
+caching. When you set <option>mailfrom</option> or <option>use_sender</option>, 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.
+</para>
+</section>
+<section id="SECTcallvercache">
+<title>Callout caching</title>
+<para>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>callout cache</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>callout</primary>
+<secondary>cache, description of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>caching</primary>
+<secondary>callout</secondary>
+</indexterm>
+Exim caches the results of callouts in order to reduce the amount of resources
+used, unless you specify the <option>no_cache</option> parameter with the <option>callout</option>
+option. A hints database called <quote>callout</quote> 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 <emphasis>postmaster</emphasis>).
+</para>
+<para>
+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.
+</para>
+<para>
+The expiry times for negative and positive address cache records are
+independent, and can be set by the global options <option>callout_negative_expire</option>
+(default 2h) and <option>callout_positive_expire</option> (default 24h), respectively.
+</para>
+<para>
+If a host gives a negative response to an SMTP connection, or rejects any
+commands up to and including
+</para>
+<literallayout class="monospaced">
+MAIL FROM:<>
+</literallayout>
+<para>
+(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:
+<option>callout_domain_negative_expire</option> (default 3h) and
+<option>callout_domain_positive_expire</option> (default 7d).
+</para>
+<para>
+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 <quote>random</quote> local parts
+will eventually be noticed.
+</para>
+<para>
+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.
+</para>
+</section>
+<section id="SECTsenaddver">
+<title>Sender address verification reporting</title>
+<para>
+<indexterm role="concept">
+<primary>verifying</primary>
+<secondary>suppressing error details</secondary>
+</indexterm>
+See section <xref linkend="SECTaddressverification"/> 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:
+</para>
+<literallayout class="monospaced">
+MAIL FROM:<xyz@abc.example>
+250 OK
+RCPT TO:<pqr@def.example>
+550-Verification failed for <xyz@abc.example>
+550-Called: 192.168.34.43
+550-Sent: RCPT TO:<xyz@abc.example>
+550-Response: 550 Unknown local part xyz in <xyz@abc.example>
+550 Sender verification failed
+</literallayout>
+<para>
+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
+<literal>/no_details</literal> to the ACL statement that requests sender verification. For
+example:
+</para>
+<literallayout class="monospaced">
+verify = sender/no_details
+</literallayout>
+</section>
+<section id="SECTredirwhilveri">
+<title>Redirection while verifying</title>
+<para>
+<indexterm role="concept">
+<primary>verifying</primary>
+<secondary>redirection while</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>address redirection</primary>
+<secondary>while verifying</secondary>
+</indexterm>
+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:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+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.
+</para>
+</listitem>
+<listitem>
+<para>
+When an incoming address is redirected to more than one child address,
+verification does not continue. A success result is returned.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+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
+</para>
+<literallayout class="monospaced">
+A.Wol: aw123
+aw123: :fail: Gone away, no forwarding address
+</literallayout>
+<para>
+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.
+</para>
+<para>
+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 <option>success_on_redirect</option> verification
+option. For example:
+</para>
+<literallayout class="monospaced">
+require verify = recipient/success_on_redirect/callout=10s
+</literallayout>
+<para>
+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.
+</para>
+<para>
+When verification is being tested via the <option>-bv</option> option, the treatment of
+redirections is as just described, unless the <option>-v</option> 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.
+</para>
+</section>
+<section id="SECTverifyCSA">
+<title>Client SMTP authorization (CSA)</title>
+<para>
+<indexterm role="concept">
+<primary>CSA</primary>
+<secondary>verifying</secondary>
+</indexterm>
+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:
+</para>
+<literallayout class="monospaced">
+verify = csa
+</literallayout>
+<para>
+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
+<varname>$csa_status</varname>, which can take one of the values <quote>fail</quote>, <quote>defer</quote>,
+<quote>unknown</quote>, or <quote>ok</quote>. The condition does not itself defer because that would
+be likely to cause problems for legitimate email.
+</para>
+<para>
+The error messages produced by the CSA code include slightly more
+detail. If <varname>$csa_status</varname> is <quote>defer</quote>, 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 <varname>$csa_status</varname> being <quote>fail</quote>:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The client’s host name is explicitly not authorized.
+</para>
+</listitem>
+<listitem>
+<para>
+The client’s IP address does not match any of the CSA target IP addresses.
+</para>
+</listitem>
+<listitem>
+<para>
+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).
+</para>
+</listitem>
+<listitem>
+<para>
+The client’s host name has no CSA SRV record but a parent domain has asserted
+that all subdomains must be explicitly authorized.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The <option>csa</option> verification condition can take an argument which is the domain to
+use for the DNS query. The default is:
+</para>
+<literallayout class="monospaced">
+verify = csa/$sender_helo_name
+</literallayout>
+<para>
+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) <emphasis>95.2.0.192.in-addr.arpa</emphasis>. Therefore it is
+meaningful to say:
+</para>
+<literallayout class="monospaced">
+verify = csa/$sender_host_address
+</literallayout>
+<para>
+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
+<option>dns_csa_use_reverse</option> to be false.
+</para>
+<para>
+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 <option>dns_csa_search_limit</option>, 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
+(<emphasis>hostname.five.four.three.two.one.com</emphasis>). This encompasses the vast majority
+of legitimate HELO domains.
+</para>
+<para>
+The <emphasis>dnsdb</emphasis> lookup also has support for CSA. Although <emphasis>dnsdb</emphasis> also supports
+direct SRV lookups, this is not sufficient because of the extra parent domain
+search behaviour of CSA, and (as with PTR lookups) <emphasis>dnsdb</emphasis> also turns IP
+addresses into lookups in the reverse DNS space. The result of a successful
+lookup such as:
+</para>
+<literallayout class="monospaced">
+${lookup dnsdb {csa=$sender_helo_name}}
+</literallayout>
+<para>
+has two space-separated fields: an authorization code and a target host name.
+The authorization code can be <quote>Y</quote> for yes, <quote>N</quote> for no, <quote>X</quote> for explicit
+authorization required but absent, or <quote>?</quote> for unknown.
+</para>
+</section>
+<section id="SECTverifyPRVS">
+<title>Bounce address tag validation</title>
+<para>
+<indexterm role="concept">
+<primary>BATV, verifying</primary>
+</indexterm>
+Bounce address tag validation (BATV) is a scheme whereby the envelope senders
+of outgoing messages have a cryptographic, timestamped <quote>tag</quote> 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 <quote>collateral
+spam</quote>), because the recipients of such messages do not include valid tags.
+</para>
+<para>
+There are two expansion items to help with the implementation of the BATV
+<quote>prvs</quote> (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 <option>prvs</option> expansion
+item creates a signed address, and the <option>prvscheck</option> expansion item checks one.
+The syntax of these expansion items is described in section
+<xref linkend="SECTexpansionitems"/>.
+The validity period on signed addresses is seven days.
+</para>
+<para>
+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:
+</para>
+<literallayout class="monospaced">
+PRVSCHECK_SQL = ${lookup mysql{SELECT secret FROM batv_prvs \
+ WHERE sender='${quote_mysql:$prvscheck_address}'\
+ }{$value}}
+</literallayout>
+<para>
+Suppose also that the senders who make use of BATV are defined by an address
+list called <option>batv_senders</option>. Then, in the ACL for RCPT commands, you could
+use this:
+</para>
+<literallayout class="monospaced">
+# Bounces: drop unsigned addresses for BATV senders
+deny senders = :
+ recipients = +batv_senders
+ message = This address does not send an unsigned reverse path
+
+# Bounces: In case of prvs-signed address, check signature.
+deny senders = :
+ condition = ${prvscheck {$local_part@$domain}\
+ {PRVSCHECK_SQL}{1}}
+ !condition = $prvscheck_result
+ message = Invalid reverse path signature.
+</literallayout>
+<para>
+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).
+</para>
+<para>
+A non-prvs-signed address is not rejected by the second statement, because the
+<option>prvscheck</option> expansion yields an empty string if its first argument is not a
+prvs-signed address, thus causing the <option>condition</option> condition to be false. If
+the first argument is a syntactically valid prvs-signed address, the yield is
+the third string (in this case <quote>1</quote>), whether or not the cryptographic and
+timeout checks succeed. The <varname>$prvscheck_result</varname> variable contains the result
+of the checks (empty for failure, <quote>1</quote> for success).
+</para>
+<para>
+There is one more issue you must consider when implementing prvs-signing:
+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 <command>redirect</command>
+router to remove the signature with a configuration along these lines:
+</para>
+<literallayout class="monospaced">
+batv_redirect:
+ driver = redirect
+ data = ${prvscheck {$local_part@$domain}{PRVSCHECK_SQL}}
+</literallayout>
+<para>
+This works because, if the third argument of <option>prvscheck</option> 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.
+</para>
+<para>
+To create BATV-signed addresses in the first place, a transport of this form
+can be used:
+</para>
+<literallayout class="monospaced">
+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}}}
+</literallayout>
+<para>
+If no key can be found for the existing return path, no signing takes place.
+</para>
+</section>
+<section id="SECTrelaycontrol">
+<title>Using an ACL to control relaying</title>
+<para>
+<indexterm role="concept">
+<primary>access control lists (ACLs)</primary>
+<secondary>relay control</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>relaying</primary>
+<secondary>control by ACL</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>policy control</primary>
+<secondary>relay control</secondary>
+</indexterm>
+An MTA is said to <emphasis>relay</emphasis> 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,
+<indexterm role="concept">
+<primary><quote>percent hack</quote></primary>
+</indexterm>
+but a redirection as a result of the <quote>percent hack</quote> is.
+</para>
+<para>
+Two kinds of relaying exist, which are termed <quote>incoming</quote> and <quote>outgoing</quote>.
+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.
+</para>
+<para>
+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:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Deliver a number of domains to mailboxes on the local host (or process them
+locally in some other way). Let’s say these are <emphasis>my.dom1.example</emphasis> and
+<emphasis>my.dom2.example</emphasis>.
+</para>
+</listitem>
+<listitem>
+<para>
+Relay mail for a number of other domains for which you are the secondary MX.
+These might be <emphasis>friend1.example</emphasis> and <emphasis>friend2.example</emphasis>.
+</para>
+</listitem>
+<listitem>
+<para>
+Relay mail from the hosts on your local LAN, to whatever domains are involved.
+Suppose your LAN is 192.168.45.0/24.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+In the main part of the configuration, you put the following definitions:
+</para>
+<literallayout class="monospaced">
+domainlist local_domains = my.dom1.example : my.dom2.example
+domainlist relay_to_domains = friend1.example : friend2.example
+hostlist relay_from_hosts = 192.168.45.0/24
+</literallayout>
+<para>
+Now you can use these definitions in the ACL that is run for every RCPT
+command:
+</para>
+<literallayout class="monospaced">
+acl_check_rcpt:
+ accept domains = +local_domains : +relay_to_domains
+ accept hosts = +relay_from_hosts
+</literallayout>
+<para>
+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 <xref linkend="CHAPdefconfil"/>.
+</para>
+</section>
+<section id="SECTcheralcon">
+<title>Checking a relay configuration</title>
+<para>
+<indexterm role="concept">
+<primary>relaying</primary>
+<secondary>checking control of</secondary>
+</indexterm>
+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 <option>-bh</option> option to run a fake SMTP session with which you interact.
+<indexterm role="concept" startref="IIDacl" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPexiscan">
+<title>Content scanning at ACL time</title>
+<para>
+<indexterm role="concept" id="IIDcosca" class="startofrange">
+<primary>content scanning</primary>
+<secondary>at ACL time</secondary>
+</indexterm>
+The extension of Exim to include content scanning at ACL time, formerly known
+as <quote>exiscan</quote>, was originally implemented as a patch by Tom Kistner. The code
+was integrated into the main source for Exim release 4.50, and Tom continues to
+maintain it. Most of the wording of this chapter is taken from Tom’s
+specification.
+</para>
+<para>
+It is also possible to scan the content of messages at other times. The
+<function>local_scan()</function> function (see chapter <xref linkend="CHAPlocalscan"/>) allows for content
+scanning after all the ACLs have run. A transport filter can be used to scan
+messages at delivery time (see the <option>transport_filter</option> option, described in
+chapter <xref linkend="CHAPtransportgeneric"/>).
+</para>
+<para>
+If you want to include the ACL-time content-scanning features when you compile
+Exim, you need to arrange for WITH_CONTENT_SCAN to be defined in your
+<filename>Local/Makefile</filename>. When you do that, the Exim binary is built with:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Two additional ACLs (<option>acl_smtp_mime</option> and <option>acl_not_smtp_mime</option>) that are run
+for all MIME parts for SMTP and non-SMTP messages, respectively.
+</para>
+</listitem>
+<listitem>
+<para>
+Additional ACL conditions and modifiers: <option>decode</option>, <option>malware</option>,
+<option>mime_regex</option>, <option>regex</option>, and <option>spam</option>. These can be used in the ACL that is
+run at the end of message reception (the <option>acl_smtp_data</option> ACL).
+</para>
+</listitem>
+<listitem>
+<para>
+An additional control feature (<quote>no_mbox_unspool</quote>) that saves spooled copies
+of messages, or parts of messages, for debugging purposes.
+</para>
+</listitem>
+<listitem>
+<para>
+Additional expansion variables that are set in the new ACL and by the new
+conditions.
+</para>
+</listitem>
+<listitem>
+<para>
+Two new main configuration options: <option>av_scanner</option> and <option>spamd_address</option>.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Content-scanning is continually evolving, and new features are still being
+added. While such features are still unstable and liable to incompatible
+changes, they are made available in Exim by setting options whose names begin
+EXPERIMENTAL_ in <filename>Local/Makefile</filename>. Such features are not documented in
+this manual. You can find out about them by reading the file called
+<filename>doc/experimental.txt</filename>.
+</para>
+<para>
+All the content-scanning facilities work on a MBOX copy of the message that is
+temporarily created in a file called:
+</para>
+<literallayout>
+<<emphasis>spool_directory</emphasis>><literal>/scan/</literal><<emphasis>message_id</emphasis>>/<<emphasis>message_id</emphasis>><literal>.eml</literal>
+</literallayout>
+<para>
+The <filename>.eml</filename> extension is a friendly hint to virus scanners that they can
+expect an MBOX-like structure inside that file. The file is created when the
+first content scanning facility is called. Subsequent calls to content
+scanning conditions open the same file again. The directory is recursively
+removed when the <option>acl_smtp_data</option> ACL has finished running, unless
+</para>
+<literallayout class="monospaced">
+control = no_mbox_unspool
+</literallayout>
+<para>
+has been encountered. When the MIME ACL decodes files, they are put into the
+same directory by default.
+</para>
+<section id="SECTscanvirus">
+<title>Scanning for viruses</title>
+<para>
+<indexterm role="concept">
+<primary>virus scanning</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>content scanning</primary>
+<secondary>for viruses</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>content scanning</primary>
+<secondary>the <option>malware</option> condition</secondary>
+</indexterm>
+The <option>malware</option> ACL condition lets you connect virus scanner software to Exim.
+It supports a <quote>generic</quote> interface to scanners called via the shell, and
+specialized interfaces for <quote>daemon</quote> type virus scanners, which are resident
+in memory and thus are much faster.
+</para>
+<para>
+Since message data needs to have arrived,
+the condition may be only called in ACL defined by
+<option>acl_smtp_data</option>,
+<option>acl_smtp_data_prdr</option>,
+<option>acl_smtp_mime</option> or
+<option>acl_smtp_dkim</option>
+</para>
+<para>
+A timeout of 2 minutes is applied to a scanner call (by default);
+if it expires then a defer action is taken.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>av_scanner</option></primary>
+</indexterm>
+You can set the <option>av_scanner</option> option in the main part of the configuration
+to specify which scanner to use, together with any additional options that
+are needed. The basic syntax is as follows:
+</para>
+<literallayout>
+<literal>av_scanner = <</literal><emphasis>scanner-type</emphasis><literal>>:<</literal><emphasis>option1</emphasis><literal>>:<</literal><emphasis>option2</emphasis><literal>>:[...]</literal>
+</literallayout>
+<para>
+If you do not set <option>av_scanner</option>, it defaults to
+</para>
+<literallayout class="monospaced">
+av_scanner = sophie:/var/run/sophie
+</literallayout>
+<para>
+If the value of <option>av_scanner</option> starts with a dollar character, it is expanded
+before use.
+The usual list-parsing of the content (see <xref linkend="SECTlistconstruct"/>) applies.
+The following scanner types are supported in this release,
+though individual ones can be included or not at build time:
+</para>
+<variablelist>
+<varlistentry>
+<term><option>avast</option></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>virus scanners</primary>
+<secondary>avast</secondary>
+</indexterm>
+This is the scanner daemon of Avast. It has been tested with Avast Core
+Security (currently at version 2.2.0).
+You can get a trial version at <emphasis role="bold"><ulink url="https://www.avast.com">https://www.avast.com</ulink></emphasis> or for Linux
+at <emphasis role="bold"><ulink url="https://www.avast.com/linux-server-antivirus">https://www.avast.com/linux-server-antivirus</ulink></emphasis>.
+This scanner type takes one option,
+which can be either a full path to a UNIX socket,
+or host and port specifiers separated by white space.
+The host may be a name or an IP address; the port is either a
+single number or a pair of numbers with a dash between.
+A list of options may follow. These options are interpreted on the
+Exim’s side of the malware scanner, or are given on separate lines to
+the daemon as options before the main scan command.
+</para>
+<para>
+<indexterm role="concept">
+<primary><literal>pass_unscanned</literal></primary>
+<secondary>avast</secondary>
+</indexterm>
+If <literal>pass_unscanned</literal>
+is set, any files the Avast scanner can’t scan (e.g.
+decompression bombs, or invalid archives) are considered clean. Use with
+care.
+</para>
+<para>
+For example:
+</para>
+<literallayout class="monospaced">
+av_scanner = avast:/var/run/avast/scan.sock:FLAGS -fullfiles:SENSITIVITY -pup
+av_scanner = avast:/var/run/avast/scan.sock:pass_unscanned:FLAGS -fullfiles:SENSITIVITY -pup
+av_scanner = avast:192.168.2.22 5036
+</literallayout>
+<para>
+If you omit the argument, the default path
+<filename>/var/run/avast/scan.sock</filename>
+is used.
+If you use a remote host,
+you need to make Exim’s spool directory available to it,
+as the scanner is passed a file path, not file contents.
+For information about available commands and their options you may use
+</para>
+<literallayout class="monospaced">
+$ socat UNIX:/var/run/avast/scan.sock STDIO:
+ FLAGS
+ SENSITIVITY
+ PACK
+</literallayout>
+<para>
+If the scanner returns a temporary failure (e.g. license issues, or
+permission problems), the message is deferred and a paniclog entry is
+written. The usual <literal>defer_ok</literal> option is available.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>aveserver</option></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>virus scanners</primary>
+<secondary>Kaspersky</secondary>
+</indexterm>
+This is the scanner daemon of Kaspersky Version 5. You can get a trial version
+at <emphasis role="bold"><ulink url="https://www.kaspersky.com/">https://www.kaspersky.com/</ulink></emphasis>. This scanner type takes one option,
+which is the path to the daemon’s UNIX socket. The default is shown in this
+example:
+</para>
+<literallayout class="monospaced">
+av_scanner = aveserver:/var/run/aveserver
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>clamd</option></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>virus scanners</primary>
+<secondary>clamd</secondary>
+</indexterm>
+This daemon-type scanner is GPL and free. You can get it at
+<emphasis role="bold"><ulink url="https://www.clamav.net/">https://www.clamav.net/</ulink></emphasis>. Some older versions of clamd do not seem to
+unpack MIME containers, so it used to be recommended to unpack MIME attachments
+in the MIME ACL. This is no longer believed to be necessary.
+</para>
+<para>
+The options are a list of server specifiers, which may be
+a UNIX socket specification,
+a TCP socket specification,
+or a (global) option.
+</para>
+<para>
+A socket specification consists of a space-separated list.
+For a Unix socket the first element is a full path for the socket,
+for a TCP socket the first element is the IP address
+and the second a port number,
+Any further elements are per-server (non-global) options.
+These per-server options are supported:
+</para>
+<literallayout class="monospaced">
+retry=<timespec> Retry on connect fail
+</literallayout>
+<para>
+The <literal>retry</literal> option specifies a time after which a single retry for
+a failed connect is made. The default is to not retry.
+</para>
+<para>
+If a Unix socket file is specified, only one server is supported.
+</para>
+<para>
+Examples:
+</para>
+<literallayout class="monospaced">
+av_scanner = clamd:/opt/clamd/socket
+av_scanner = clamd:192.0.2.3 1234
+av_scanner = clamd:192.0.2.3 1234:local
+av_scanner = clamd:192.0.2.3 1234 retry=10s
+av_scanner = clamd:192.0.2.3 1234 : 192.0.2.4 1234
+</literallayout>
+<para>
+If the value of av_scanner points to a UNIX socket file or contains the
+<literal>local</literal>
+option, then the ClamAV interface will pass a filename containing the data
+to be scanned, which should normally result in less I/O happening and be
+more efficient. Normally in the TCP case, the data is streamed to ClamAV as
+Exim does not assume that there is a common filesystem with the remote host.
+</para>
+<para>
+The final example shows that multiple TCP targets can be specified. Exim will
+randomly use one for each incoming email (i.e. it load balances them). Note
+that only TCP targets may be used if specifying a list of scanners; a UNIX
+socket cannot be mixed in with TCP targets. If one of the servers becomes
+unavailable, Exim will try the remaining one(s) until it finds one that works.
+When a clamd server becomes unreachable, Exim will log a message. Exim does
+not keep track of scanner state between multiple messages, and the scanner
+selection is random, so the message will get logged in the mainlog for each
+email that the down scanner gets chosen first (message wrapped to be readable):
+</para>
+<literallayout class="monospaced">
+2013-10-09 14:30:39 1VTumd-0000Y8-BQ malware acl condition:
+ clamd: connection to localhost, port 3310 failed
+ (Connection refused)
+</literallayout>
+<para>
+If the option is unset, the default is <filename>/tmp/clamd</filename>. Thanks to David Saez for
+contributing the code for this scanner.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>cmdline</option></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>virus scanners</primary>
+<secondary>command line interface</secondary>
+</indexterm>
+This is the keyword for the generic command line scanner interface. It can be
+used to attach virus scanners that are invoked from the shell. This scanner
+type takes 3 mandatory options:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+The full path and name of the scanner binary, with all command line options,
+and a placeholder (<literal>%s</literal>) for the directory to scan.
+</para>
+</listitem>
+<listitem>
+<para>
+A regular expression to match against the STDOUT and STDERR output of the
+virus scanner. If the expression matches, a virus was found. You must make
+absolutely sure that this expression matches on <quote>virus found</quote>. This is called
+the <quote>trigger</quote> expression.
+</para>
+</listitem>
+<listitem>
+<para>
+Another regular expression, containing exactly one pair of parentheses, to
+match the name of the virus found in the scanners output. This is called the
+<quote>name</quote> expression.
+</para>
+</listitem>
+</orderedlist>
+<para>
+For example, Sophos Sweep reports a virus on a line like this:
+</para>
+<literallayout class="monospaced">
+Virus 'W32/Magistr-B' found in file ./those.bat
+</literallayout>
+<para>
+For the trigger expression, we can match the phrase <quote>found in file</quote>. For the
+name expression, we want to extract the W32/Magistr-B string, so we can match
+for the single quotes left and right of it. Altogether, this makes the
+configuration setting:
+</para>
+<literallayout class="monospaced">
+av_scanner = cmdline:\
+ /path/to/sweep -ss -all -rec -archive %s:\
+ found in file:'(.+)'
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>drweb</option></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>virus scanners</primary>
+<secondary>DrWeb</secondary>
+</indexterm>
+The DrWeb daemon scanner (<emphasis role="bold"><ulink url="https://www.sald.ru/">https://www.sald.ru/</ulink></emphasis>) interface
+takes one option,
+either a full path to a UNIX socket,
+or host and port specifiers separated by white space.
+The host may be a name or an IP address; the port is either a
+single number or a pair of numbers with a dash between.
+For example:
+</para>
+<literallayout class="monospaced">
+av_scanner = drweb:/var/run/drwebd.sock
+av_scanner = drweb:192.168.2.20 31337
+</literallayout>
+<para>
+If you omit the argument, the default path <filename>/usr/local/drweb/run/drwebd.sock</filename>
+is used. Thanks to Alex Miller for contributing the code for this scanner.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>f-protd</option></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>virus scanners</primary>
+<secondary>f-protd</secondary>
+</indexterm>
+The f-protd scanner is accessed via HTTP over TCP.
+One argument is taken, being a space-separated hostname and port number
+(or port-range).
+For example:
+</para>
+<literallayout class="monospaced">
+av_scanner = f-protd:localhost 10200-10204
+</literallayout>
+<para>
+If you omit the argument, the default values shown above are used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>f-prot6d</option></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>virus scanners</primary>
+<secondary>f-prot6d</secondary>
+</indexterm>
+The f-prot6d scanner is accessed using the FPSCAND protocol over TCP.
+One argument is taken, being a space-separated hostname and port number.
+For example:
+</para>
+<literallayout class="monospaced">
+av_scanner = f-prot6d:localhost 10200
+</literallayout>
+<para>
+If you omit the argument, the default values show above are used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>fsecure</option></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>virus scanners</primary>
+<secondary>F-Secure</secondary>
+</indexterm>
+The F-Secure daemon scanner (<emphasis role="bold"><ulink url="https://www.f-secure.com/">https://www.f-secure.com/</ulink></emphasis>) takes one
+argument which is the path to a UNIX socket. For example:
+</para>
+<literallayout class="monospaced">
+av_scanner = fsecure:/path/to/.fsav
+</literallayout>
+<para>
+If no argument is given, the default is <filename>/var/run/.fsav</filename>. Thanks to Johan
+Thelmen for contributing the code for this scanner.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>kavdaemon</option></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>virus scanners</primary>
+<secondary>Kaspersky</secondary>
+</indexterm>
+This is the scanner daemon of Kaspersky Version 4. This version of the
+Kaspersky scanner is outdated. Please upgrade (see <option>aveserver</option> above). This
+scanner type takes one option, which is the path to the daemon’s UNIX socket.
+For example:
+</para>
+<literallayout class="monospaced">
+av_scanner = kavdaemon:/opt/AVP/AvpCtl
+</literallayout>
+<para>
+The default path is <filename>/var/run/AvpCtl</filename>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>mksd</option></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>virus scanners</primary>
+<secondary>mksd</secondary>
+</indexterm>
+This was a daemon type scanner that is aimed mainly at Polish users,
+though some documentation was available in English.
+The history can be shown at <emphasis role="bold"><ulink url="https://en.wikipedia.org/wiki/Mks_vir">https://en.wikipedia.org/wiki/Mks_vir</ulink></emphasis>
+and this appears to be a candidate for removal from Exim, unless
+we are informed of other virus scanners which use the same protocol
+to integrate.
+The only option for this scanner type is
+the maximum number of processes used simultaneously to scan the attachments,
+provided that mksd has
+been run with at least the same number of child processes. For example:
+</para>
+<literallayout class="monospaced">
+av_scanner = mksd:2
+</literallayout>
+<para>
+You can safely omit this option (the default value is 1).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>sock</option></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>virus scanners</primary>
+<secondary>simple socket-connected</secondary>
+</indexterm>
+This is a general-purpose way of talking to simple scanner daemons
+running on the local machine.
+There are four options:
+an address (which may be an IP address and port, or the path of a Unix socket),
+a commandline to send (may include a single %s which will be replaced with
+the path to the mail file to be scanned),
+an RE to trigger on from the returned data,
+and an RE to extract malware_name from the returned data.
+For example:
+</para>
+<literallayout class="monospaced">
+av_scanner = sock:127.0.0.1 6001:%s:(SPAM|VIRUS):(.*)$
+</literallayout>
+<para>
+Note that surrounding whitespace is stripped from each option, meaning
+there is no way to specify a trailing newline.
+The socket specifier and both regular-expressions are required.
+Default for the commandline is <filename>%s\n</filename> (note this does have a trailing newline);
+specify an empty element to get this.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>sophie</option></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>virus scanners</primary>
+<secondary>Sophos and Sophie</secondary>
+</indexterm>
+Sophie is a daemon that uses Sophos’ <option>libsavi</option> library to scan for viruses.
+You can get Sophie at <emphasis role="bold"><ulink url="http://sophie.sourceforge.net/">http://sophie.sourceforge.net/</ulink></emphasis>. The only option
+for this scanner type is the path to the UNIX socket that Sophie uses for
+client communication. For example:
+</para>
+<literallayout class="monospaced">
+av_scanner = sophie:/tmp/sophie
+</literallayout>
+<para>
+The default path is <filename>/var/run/sophie</filename>, so if you are using this, you can omit
+the option.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+When <option>av_scanner</option> is correctly set, you can use the <option>malware</option> condition in
+the DATA ACL. <emphasis role="bold">Note</emphasis>: You cannot use the <option>malware</option> condition in the MIME
+ACL.
+</para>
+<para>
+The <option>av_scanner</option> option is expanded each time <option>malware</option> is called. This
+makes it possible to use different scanners. See further below for an example.
+The <option>malware</option> condition caches its results, so when you use it multiple times
+for the same message, the actual scanning process is only carried out once.
+However, using expandable items in <option>av_scanner</option> disables this caching, in
+which case each use of the <option>malware</option> condition causes a new scan of the
+message.
+</para>
+<para>
+The <option>malware</option> condition takes a right-hand argument that is expanded before
+use and taken as a list, slash-separated by default.
+The first element can then be one of
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<quote>true</quote>, <quote>*</quote>, or <quote>1</quote>, in which case the message is scanned for viruses.
+The condition succeeds if a virus was found, and fail otherwise. This is the
+recommended usage.
+</para>
+</listitem>
+<listitem>
+<para>
+<quote>false</quote> or <quote>0</quote> or an empty string, in which case no scanning is done and
+the condition fails immediately.
+</para>
+</listitem>
+<listitem>
+<para>
+A regular expression, in which case the message is scanned for viruses. The
+condition succeeds if a virus is found and its name matches the regular
+expression. This allows you to take special actions on certain types of virus.
+Note that <quote>/</quote> characters in the RE must be doubled due to the list-processing,
+unless the separator is changed (in the usual way <xref linkend="SECTlistsepchange"/>).
+</para>
+</listitem>
+</itemizedlist>
+<para>
+You can append a <literal>defer_ok</literal> element to the <option>malware</option> argument list to accept
+messages even if there is a problem with the virus scanner.
+Otherwise, such a problem causes the ACL to defer.
+</para>
+<para>
+You can append a <literal>tmo=<val></literal> element to the <option>malware</option> argument list to
+specify a non-default timeout. The default is two minutes.
+For example:
+</para>
+<literallayout class="monospaced">
+malware = * / defer_ok / tmo=10s
+</literallayout>
+<para>
+A timeout causes the ACL to defer.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$callout_address</varname></primary>
+</indexterm>
+When a connection is made to the scanner the expansion variable <varname>$callout_address</varname>
+is set to record the actual address used.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$malware_name</varname></primary>
+</indexterm>
+When a virus is found, the condition sets up an expansion variable called
+<varname>$malware_name</varname> that contains the name of the virus. You can use it in a
+<option>message</option> modifier that specifies the error returned to the sender, and/or in
+logging data.
+</para>
+<para>
+Beware the interaction of Exim’s <option>message_size_limit</option> with any size limits
+imposed by your anti-virus scanner.
+</para>
+<para>
+Here is a very simple scanning example:
+</para>
+<literallayout class="monospaced">
+deny malware = *
+ message = This message contains malware ($malware_name)
+</literallayout>
+<para>
+The next example accepts messages when there is a problem with the scanner:
+</para>
+<literallayout class="monospaced">
+deny malware = */defer_ok
+ message = This message contains malware ($malware_name)
+</literallayout>
+<para>
+The next example shows how to use an ACL variable to scan with both sophie and
+aveserver. It assumes you have set:
+</para>
+<literallayout class="monospaced">
+av_scanner = $acl_m0
+</literallayout>
+<para>
+in the main Exim configuration.
+</para>
+<literallayout class="monospaced">
+deny set acl_m0 = sophie
+ malware = *
+ message = This message contains malware ($malware_name)
+
+deny set acl_m0 = aveserver
+ malware = *
+ message = This message contains malware ($malware_name)
+</literallayout>
+</section>
+<section id="SECTscanspamass">
+<title>Scanning with SpamAssassin and Rspamd</title>
+<para>
+<indexterm role="concept">
+<primary>content scanning</primary>
+<secondary>for spam</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>spam scanning</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SpamAssassin</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Rspamd</primary>
+</indexterm>
+The <option>spam</option> ACL condition calls SpamAssassin’s <option>spamd</option> daemon to get a spam
+score and a report for the message.
+Support is also provided for Rspamd.
+</para>
+<para>
+For more information about installation and configuration of SpamAssassin or
+Rspamd refer to their respective websites at
+<emphasis role="bold"><ulink url="https://spamassassin.apache.org/">https://spamassassin.apache.org/</ulink></emphasis> and <emphasis role="bold"><ulink url="https://www.rspamd.com/">https://www.rspamd.com/</ulink></emphasis>
+</para>
+<para>
+SpamAssassin can be installed with CPAN by running:
+</para>
+<literallayout class="monospaced">
+perl -MCPAN -e 'install Mail::SpamAssassin'
+</literallayout>
+<para>
+SpamAssassin has its own set of configuration files. Please review its
+documentation to see how you can tweak it. The default installation should work
+nicely, however.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>spamd_address</option></primary>
+</indexterm>
+By default, SpamAssassin listens on 127.0.0.1, TCP port 783 and if you
+intend to use an instance running on the local host you do not need to set
+<option>spamd_address</option>. If you intend to use another host or port for SpamAssassin,
+you must set the <option>spamd_address</option> option in the global part of the Exim
+configuration as follows (example):
+</para>
+<literallayout class="monospaced">
+spamd_address = 192.168.99.45 783
+</literallayout>
+<para>
+The SpamAssassin protocol relies on a TCP half-close from the client.
+If your SpamAssassin client side is running a Linux system with an
+iptables firewall, consider setting
+<option>net.netfilter.nf_conntrack_tcp_timeout_close_wait</option> to at least the
+timeout, Exim uses when waiting for a response from the SpamAssassin
+server (currently defaulting to 120s). With a lower value the Linux
+connection tracking may consider your half-closed connection as dead too
+soon.
+</para>
+<para>
+To use Rspamd (which by default listens on all local addresses
+on TCP port 11333)
+you should add <option>variant=rspamd</option> after the address/port pair, for example:
+</para>
+<literallayout class="monospaced">
+spamd_address = 127.0.0.1 11333 variant=rspamd
+</literallayout>
+<para>
+As of version 2.60, <option>SpamAssassin</option> also supports communication over UNIX
+sockets. If you want to us these, supply <option>spamd_address</option> with an absolute
+filename instead of an address/port pair:
+</para>
+<literallayout class="monospaced">
+spamd_address = /var/run/spamd_socket
+</literallayout>
+<para>
+You can have multiple <option>spamd</option> servers to improve scalability. These can
+reside on other hardware reachable over the network. To specify multiple
+<option>spamd</option> servers, put multiple address/port pairs in the <option>spamd_address</option>
+option, separated with colons (the separator can be changed in the usual way <xref linkend="SECTlistsepchange"/>):
+</para>
+<literallayout class="monospaced">
+spamd_address = 192.168.2.10 783 : \
+ 192.168.2.11 783 : \
+ 192.168.2.12 783
+</literallayout>
+<para>
+Up to 32 <option>spamd</option> servers are supported.
+When a server fails to respond to the connection attempt, all other
+servers are tried until one succeeds. If no server responds, the <option>spam</option>
+condition defers.
+</para>
+<para>
+Unix and TCP socket specifications may be mixed in any order.
+Each element of the list is a list itself, space-separated by default
+and changeable in the usual way (<xref linkend="SECTlistsepchange"/>);
+take care to not double the separator.
+</para>
+<para>
+For TCP socket specifications a host name or IP (v4 or v6, but
+subject to list-separator quoting rules) address can be used,
+and the port can be one or a dash-separated pair.
+In the latter case, the range is tried in strict order.
+</para>
+<para>
+Elements after the first for Unix sockets, or second for TCP socket,
+are options.
+The supported options are:
+</para>
+<literallayout class="monospaced">
+pri=<priority> Selection priority
+weight=<value> Selection bias
+time=<start>-<end> Use only between these times of day
+retry=<timespec> Retry on connect fail
+tmo=<timespec> Connection time limit
+variant=rspamd Use Rspamd rather than SpamAssassin protocol
+</literallayout>
+<para>
+The <literal>pri</literal> option specifies a priority for the server within the list,
+higher values being tried first.
+The default priority is 1.
+</para>
+<para>
+The <literal>weight</literal> option specifies a selection bias.
+Within a priority set
+servers are queried in a random fashion, weighted by this value.
+The default value for selection bias is 1.
+</para>
+<para>
+Time specifications for the <literal>time</literal> option are <hour>.<minute>.<second>
+in the local time zone; each element being one or more digits.
+Either the seconds or both minutes and seconds, plus the leading <literal>.</literal>
+characters, may be omitted and will be taken as zero.
+</para>
+<para>
+Timeout specifications for the <literal>retry</literal> and <literal>tmo</literal> options
+are the usual Exim time interval standard, e.g. <literal>20s</literal> or <literal>1m</literal>.
+</para>
+<para>
+The <literal>tmo</literal> option specifies an overall timeout for communication.
+The default value is two minutes.
+</para>
+<para>
+The <literal>retry</literal> option specifies a time after which a single retry for
+a failed connect is made.
+The default is to not retry.
+</para>
+<para>
+The <option>spamd_address</option> variable is expanded before use if it starts with
+a dollar sign. In this case, the expansion may return a string that is
+used as the list so that multiple spamd servers can be the result of an
+expansion.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$callout_address</varname></primary>
+</indexterm>
+When a connection is made to the server the expansion variable <varname>$callout_address</varname>
+is set to record the actual address used.
+</para>
+</section>
+<section id="SECID206">
+<title>Calling SpamAssassin from an Exim ACL</title>
+<para>
+Here is a simple example of the use of the <option>spam</option> condition in a DATA ACL:
+</para>
+<literallayout class="monospaced">
+deny spam = joe
+ message = This message was classified as SPAM
+</literallayout>
+<para>
+The right-hand side of the <option>spam</option> condition specifies a name. This is
+relevant if you have set up multiple SpamAssassin profiles. If you do not want
+to scan using a specific profile, but rather use the SpamAssassin system-wide
+default profile, you can scan for an unknown name, or simply use <quote>nobody</quote>.
+Rspamd does not use this setting. However, you must put something on the
+right-hand side.
+</para>
+<para>
+The name allows you to use per-domain or per-user antispam profiles in
+principle, but this is not straightforward in practice, because a message may
+have multiple recipients, not necessarily all in the same domain. Because the
+<option>spam</option> condition has to be called from a DATA-time ACL in order to be able to
+read the contents of the message, the variables <varname>$local_part</varname> and <varname>$domain</varname>
+are not set.
+Careful enforcement of single-recipient messages
+(e.g. by responding with defer in the recipient ACL for all recipients
+after the first),
+or the use of PRDR,
+<indexterm role="concept">
+<primary>PRDR</primary>
+<secondary>use for per-user SpamAssassin profiles</secondary>
+</indexterm>
+are needed to use this feature.
+</para>
+<para>
+The right-hand side of the <option>spam</option> condition is expanded before being used, so
+you can put lookups or conditions there. When the right-hand side evaluates to
+<quote>0</quote> or <quote>false</quote>, no scanning is done and the condition fails immediately.
+</para>
+<para>
+Scanning with SpamAssassin uses a lot of resources. If you scan every message,
+large ones may cause significant performance degradation. As most spam messages
+are quite small, it is recommended that you do not scan the big ones. For
+example:
+</para>
+<literallayout class="monospaced">
+deny condition = ${if < {$message_size}{10K}}
+ spam = nobody
+ message = This message was classified as SPAM
+</literallayout>
+<para>
+The <option>spam</option> condition returns true if the threshold specified in the user’s
+SpamAssassin profile has been matched or exceeded. If you want to use the
+<option>spam</option> condition for its side effects (see the variables below), you can make
+it always return <quote>true</quote> by appending <literal>:true</literal> to the username.
+</para>
+<para>
+<indexterm role="concept">
+<primary>spam scanning</primary>
+<secondary>returned variables</secondary>
+</indexterm>
+When the <option>spam</option> condition is run, it sets up a number of expansion
+variables.
+Except for <varname>$spam_report</varname>,
+these variables are saved with the received message so are
+available for use at delivery time.
+</para>
+<variablelist>
+<varlistentry>
+<term><varname>$spam_score</varname></term>
+<listitem>
+<para>
+The spam score of the message, for example, <quote>3.4</quote> or <quote>30.5</quote>. This is useful
+for inclusion in log or reject messages.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$spam_score_int</varname></term>
+<listitem>
+<para>
+The spam score of the message, multiplied by ten, as an integer value. For
+example <quote>34</quote> or <quote>305</quote>. It may appear to disagree with <varname>$spam_score</varname>
+because <varname>$spam_score</varname> is rounded and <varname>$spam_score_int</varname> is truncated.
+The integer value is useful for numeric comparisons in conditions.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$spam_bar</varname></term>
+<listitem>
+<para>
+A string consisting of a number of <quote>+</quote> or <quote>-</quote> characters, representing the
+integer part of the spam score value. A spam score of 4.4 would have a
+<varname>$spam_bar</varname> value of <quote>++++</quote>. This is useful for inclusion in warning
+headers, since MUAs can match on such strings. The maximum length of the
+spam bar is 50 characters.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$spam_report</varname></term>
+<listitem>
+<para>
+A multiline text table, containing the full SpamAssassin report for the
+message. Useful for inclusion in headers or reject messages.
+This variable is only usable in a DATA-time ACL.
+Beware that SpamAssassin may return non-ASCII characters, especially
+when running in country-specific locales, which are not legal
+unencoded in headers.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$spam_action</varname></term>
+<listitem>
+<para>
+For SpamAssassin either ’reject’ or ’no action’ depending on the
+spam score versus threshold.
+For Rspamd, the recommended action.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+The <option>spam</option> condition caches its results unless expansion in
+spamd_address was used. If you call it again with the same user name, it
+does not scan again, but rather returns the same values as before.
+</para>
+<para>
+The <option>spam</option> condition returns DEFER if there is any error while running
+the message through SpamAssassin or if the expansion of spamd_address
+failed. If you want to treat DEFER as FAIL (to pass on to the next ACL
+statement block), append <literal>/defer_ok</literal> to the right-hand side of the
+spam condition, like this:
+</para>
+<literallayout class="monospaced">
+deny spam = joe/defer_ok
+ message = This message was classified as SPAM
+</literallayout>
+<para>
+This causes messages to be accepted even if there is a problem with <option>spamd</option>.
+</para>
+<para>
+Here is a longer, commented example of the use of the <option>spam</option>
+condition:
+</para>
+<literallayout class="monospaced">
+# put headers in all messages (no matter if spam or not)
+warn spam = nobody:true
+ add_header = X-Spam-Score: $spam_score ($spam_bar)
+ add_header = X-Spam-Report: $spam_report
+
+# add second subject line with *SPAM* marker when message
+# is over threshold
+warn spam = nobody
+ add_header = Subject: *SPAM* $h_Subject:
+
+# reject spam at high scores (> 12)
+deny spam = nobody:true
+ condition = ${if >{$spam_score_int}{120}{1}{0}}
+ message = This message scored $spam_score spam points.
+</literallayout>
+</section>
+<section id="SECTscanmimepart">
+<title>Scanning MIME parts</title>
+<para>
+<indexterm role="concept">
+<primary>content scanning</primary>
+<secondary>MIME parts</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>MIME content scanning</primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>acl_smtp_mime</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>acl_not_smtp_mime</option></primary>
+</indexterm>
+The <option>acl_smtp_mime</option> global option specifies an ACL that is called once for
+each MIME part of an SMTP message, including multipart types, in the sequence
+of their position in the message. Similarly, the <option>acl_not_smtp_mime</option> option
+specifies an ACL that is used for the MIME parts of non-SMTP messages. These
+options may both refer to the same ACL if you want the same processing in both
+cases.
+</para>
+<para>
+These ACLs are called (possibly many times) just before the <option>acl_smtp_data</option>
+ACL in the case of an SMTP message, or just before the <option>acl_not_smtp</option> ACL in
+the case of a non-SMTP message. However, a MIME ACL is called only if the
+message contains a <emphasis>Content-Type:</emphasis> header line. When a call to a MIME
+ACL does not yield <quote>accept</quote>, ACL processing is aborted and the appropriate
+result code is sent to the client. In the case of an SMTP message, the
+<option>acl_smtp_data</option> ACL is not called when this happens.
+</para>
+<para>
+You cannot use the <option>malware</option> or <option>spam</option> conditions in a MIME ACL; these can
+only be used in the DATA or non-SMTP ACLs. However, you can use the <option>regex</option>
+condition to match against the raw MIME part. You can also use the
+<option>mime_regex</option> condition to match against the decoded MIME part (see section
+<xref linkend="SECTscanregex"/>).
+</para>
+<para>
+At the start of a MIME ACL, a number of variables are set from the header
+information for the relevant MIME part. These are described below. The contents
+of the MIME part are not by default decoded into a disk file except for MIME
+parts whose content-type is <quote>message/rfc822</quote>. If you want to decode a MIME
+part into a disk file, you can use the <option>decode</option> condition. The general
+syntax is:
+</para>
+<literallayout>
+<literal>decode = [/</literal><<emphasis>path</emphasis>><literal>/]</literal><<emphasis>filename</emphasis>>
+</literallayout>
+<para>
+The right hand side is expanded before use. After expansion,
+the value can be:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+<quote>0</quote> or <quote>false</quote>, in which case no decoding is done.
+</para>
+</listitem>
+<listitem>
+<para>
+The string <quote>default</quote>. In that case, the file is put in the temporary
+<quote>default</quote> directory <<emphasis>spool_directory</emphasis>><filename>/scan/</filename><<emphasis>message_id</emphasis>><filename>/</filename> with
+a sequential filename consisting of the message id and a sequence number. The
+full path and name is available in <varname>$mime_decoded_filename</varname> after decoding.
+</para>
+</listitem>
+<listitem>
+<para>
+A full path name starting with a slash. If the full name is an existing
+directory, it is used as a replacement for the default directory. The filename
+is then sequentially assigned. If the path does not exist, it is used as
+the full path and filename.
+</para>
+</listitem>
+<listitem>
+<para>
+If the string does not start with a slash, it is used as the
+filename, and the default path is then used.
+</para>
+</listitem>
+</orderedlist>
+<para>
+The <option>decode</option> condition normally succeeds. It is only false for syntax
+errors or unusual circumstances such as memory shortages. You can easily decode
+a file with its original, proposed filename using
+</para>
+<literallayout class="monospaced">
+decode = $mime_filename
+</literallayout>
+<para>
+However, you should keep in mind that <varname>$mime_filename</varname> might contain
+anything. If you place files outside of the default path, they are not
+automatically unlinked.
+</para>
+<para>
+For RFC822 attachments (these are messages attached to messages, with a
+content-type of <quote>message/rfc822</quote>), the ACL is called again in the same manner
+as for the primary message, only that the <varname>$mime_is_rfc822</varname> expansion
+variable is set (see below). Attached messages are always decoded to disk
+before being checked, and the files are unlinked once the check is done.
+</para>
+<para>
+The MIME ACL supports the <option>regex</option> and <option>mime_regex</option> conditions. These can be
+used to match regular expressions against raw and decoded MIME parts,
+respectively. They are described in section <xref linkend="SECTscanregex"/>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>MIME content scanning</primary>
+<secondary>returned variables</secondary>
+</indexterm>
+The following list describes all expansion variables that are
+available in the MIME ACL:
+</para>
+<variablelist>
+<varlistentry>
+<term><varname>$mime_anomaly_level</varname></term>
+<term><varname>$mime_anomaly_text</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_anomaly_level</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$mime_anomaly_text</varname></primary>
+</indexterm>
+If there are problems decoding, these variables contain information on
+the detected issue.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_boundary</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_boundary</varname></primary>
+</indexterm>
+If the current part is a multipart (see <varname>$mime_is_multipart</varname> below), it should
+have a boundary string, which is stored in this variable. If the current part
+has no boundary parameter in the <emphasis>Content-Type:</emphasis> header, this variable
+contains the empty string.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_charset</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_charset</varname></primary>
+</indexterm>
+This variable contains the character set identifier, if one was found in the
+<emphasis>Content-Type:</emphasis> header. Examples for charset identifiers are:
+</para>
+<literallayout class="monospaced">
+us-ascii
+gb2312 (Chinese)
+iso-8859-1
+</literallayout>
+<para>
+Please note that this value is not normalized, so you should do matches
+case-insensitively.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_content_description</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_content_description</varname></primary>
+</indexterm>
+This variable contains the normalized content of the <emphasis>Content-Description:</emphasis>
+header. It can contain a human-readable description of the parts content. Some
+implementations repeat the filename for attachments here, but they are usually
+only used for display purposes.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_content_disposition</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_content_disposition</varname></primary>
+</indexterm>
+This variable contains the normalized content of the <emphasis>Content-Disposition:</emphasis>
+header. You can expect strings like <quote>attachment</quote> or <quote>inline</quote> here.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_content_id</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_content_id</varname></primary>
+</indexterm>
+This variable contains the normalized content of the <emphasis>Content-ID:</emphasis> header.
+This is a unique ID that can be used to reference a part from another part.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_content_size</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_content_size</varname></primary>
+</indexterm>
+This variable is set only after the <option>decode</option> modifier (see above) has been
+successfully run. It contains the size of the decoded part in kilobytes. The
+size is always rounded up to full kilobytes, so only a completely empty part
+has a <varname>$mime_content_size</varname> of zero.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_content_transfer_encoding</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_content_transfer_encoding</varname></primary>
+</indexterm>
+This variable contains the normalized content of the
+<emphasis>Content-transfer-encoding:</emphasis> header. This is a symbolic name for an encoding
+type. Typical values are <quote>base64</quote> and <quote>quoted-printable</quote>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_content_type</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_content_type</varname></primary>
+</indexterm>
+If the MIME part has a <emphasis>Content-Type:</emphasis> header, this variable contains its
+value, lowercased, and without any options (like <quote>name</quote> or <quote>charset</quote>). Here
+are some examples of popular MIME types, as they may appear in this variable:
+</para>
+<literallayout class="monospaced">
+text/plain
+text/html
+application/octet-stream
+image/jpeg
+audio/midi
+</literallayout>
+<para>
+If the MIME part has no <emphasis>Content-Type:</emphasis> header, this variable contains the
+empty string.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_decoded_filename</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_decoded_filename</varname></primary>
+</indexterm>
+This variable is set only after the <option>decode</option> modifier (see above) has been
+successfully run. It contains the full path and filename of the file
+containing the decoded data.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+<indexterm role="concept">
+<primary>RFC 2047</primary>
+</indexterm>
+</para>
+<variablelist>
+<varlistentry>
+<term><varname>$mime_filename</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_filename</varname></primary>
+</indexterm>
+This is perhaps the most important of the MIME variables. It contains a
+proposed filename for an attachment, if one was found in either the
+<emphasis>Content-Type:</emphasis> or <emphasis>Content-Disposition:</emphasis> headers. The filename will be
+RFC2047
+or RFC2231
+decoded, but no additional sanity checks are done.
+ If no filename was
+found, this variable contains the empty string.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_is_coverletter</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_is_coverletter</varname></primary>
+</indexterm>
+This variable attempts to differentiate the <quote>cover letter</quote> of an e-mail from
+attached data. It can be used to clamp down on flashy or unnecessarily encoded
+content in the cover letter, while not restricting attachments at all.
+</para>
+<para>
+The variable contains 1 (true) for a MIME part believed to be part of the
+cover letter, and 0 (false) for an attachment. At present, the algorithm is as
+follows:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+The outermost MIME part of a message is always a cover letter.
+</para>
+</listitem>
+<listitem>
+<para>
+If a multipart/alternative or multipart/related MIME part is a cover letter,
+so are all MIME subparts within that multipart.
+</para>
+</listitem>
+<listitem>
+<para>
+If any other multipart is a cover letter, the first subpart is a cover letter,
+and the rest are attachments.
+</para>
+</listitem>
+<listitem>
+<para>
+All parts contained within an attachment multipart are attachments.
+</para>
+</listitem>
+</orderedlist>
+<para>
+As an example, the following will ban <quote>HTML mail</quote> (including that sent with
+alternative plain text), while allowing HTML files to be attached. HTML
+coverletter mail attached to non-HTML coverletter mail will also be allowed:
+</para>
+<literallayout class="monospaced">
+deny !condition = $mime_is_rfc822
+ condition = $mime_is_coverletter
+ condition = ${if eq{$mime_content_type}{text/html}{1}{0}}
+ message = HTML mail is not accepted here
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_is_multipart</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_is_multipart</varname></primary>
+</indexterm>
+This variable has the value 1 (true) when the current part has the main type
+<quote>multipart</quote>, for example, <quote>multipart/alternative</quote> or <quote>multipart/mixed</quote>.
+Since multipart entities only serve as containers for other parts, you may not
+want to carry out specific actions on them.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_is_rfc822</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_is_rfc822</varname></primary>
+</indexterm>
+This variable has the value 1 (true) if the current part is not a part of the
+checked message itself, but part of an attached message. Attached message
+decoding is fully recursive.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$mime_part_count</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$mime_part_count</varname></primary>
+</indexterm>
+This variable is a counter that is raised for each processed MIME part. It
+starts at zero for the very first part (which is usually a multipart). The
+counter is per-message, so it is reset when processing RFC822 attachments (see
+<varname>$mime_is_rfc822</varname>). The counter stays set after <option>acl_smtp_mime</option> is
+complete, so you can use it in the DATA ACL to determine the number of MIME
+parts of a message. For non-MIME messages, this variable contains the value -1.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</section>
+<section id="SECTscanregex">
+<title>Scanning with regular expressions</title>
+<para>
+<indexterm role="concept">
+<primary>content scanning</primary>
+<secondary>with regular expressions</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>regular expressions</primary>
+<secondary>content scanning with</secondary>
+</indexterm>
+You can specify your own custom regular expression matches on the full body of
+the message, or on individual MIME parts.
+</para>
+<para>
+The <option>regex</option> condition takes one or more regular expressions as arguments and
+matches them against the full message (when called in the DATA ACL) or a raw
+MIME part (when called in the MIME ACL). The <option>regex</option> condition matches
+linewise, with a maximum line length of 32K characters. That means you cannot
+have multiline matches with the <option>regex</option> condition.
+</para>
+<para>
+The <option>mime_regex</option> condition can be called only in the MIME ACL. It matches up
+to 32K of decoded content (the whole content at once, not linewise). If the
+part has not been decoded with the <option>decode</option> modifier earlier in the ACL, it
+is decoded automatically when <option>mime_regex</option> is executed (using default path
+and filename values). If the decoded data is larger than 32K, only the first
+32K characters are checked.
+</para>
+<para>
+The regular expressions are passed as a colon-separated list. To include a
+literal colon, you must double it. Since the whole right-hand side string is
+expanded before being used, you must also escape dollar signs and backslashes
+with more backslashes, or use the <literal>\N</literal> facility to disable expansion.
+Here is a simple example that contains two regular expressions:
+</para>
+<literallayout class="monospaced">
+deny regex = [Mm]ortgage : URGENT BUSINESS PROPOSAL
+ message = contains blacklisted regex ($regex_match_string)
+</literallayout>
+<para>
+The conditions returns true if any one of the regular expressions matches. The
+<varname>$regex_match_string</varname> expansion variable is then set up and contains the
+matching regular expression.
+The expansion variables <varname>$regex1</varname> <varname>$regex2</varname> etc
+are set to any substrings captured by the regular expression.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: With large messages, these conditions can be fairly
+CPU-intensive.
+</para>
+<para>
+<indexterm role="concept" startref="IIDcosca" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPlocalscan">
+<title>Adding a local scan function to Exim</title>
+<titleabbrev>Local scan function</titleabbrev>
+<para>
+<indexterm role="concept" id="IIDlosca" class="startofrange">
+<primary><function>local_scan()</function> function</primary>
+<secondary>description of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>customizing</primary>
+<secondary>input scan using C function</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>policy control</primary>
+<secondary>by local scan function</secondary>
+</indexterm>
+In these days of email worms, viruses, and ever-increasing spam, some sites
+want to apply a lot of checking to messages before accepting them.
+</para>
+<para>
+The content scanning extension (chapter <xref linkend="CHAPexiscan"/>) has facilities for
+passing messages to external virus and spam scanning software. You can also do
+a certain amount in Exim itself through string expansions and the <option>condition</option>
+condition in the ACL that runs after the SMTP DATA command or the ACL for
+non-SMTP messages (see chapter <xref linkend="CHAPACL"/>), but this has its limitations.
+</para>
+<para>
+To allow for further customization to a site’s own requirements, there is the
+possibility of linking Exim with a private message scanning function, written
+in C. If you want to run code that is written in something other than C, you
+can of course use a little C stub to call it.
+</para>
+<para>
+The local scan function is run once for every incoming message, at the point
+when Exim is just about to accept the message.
+It can therefore be used to control non-SMTP messages from local processes as
+well as messages arriving via SMTP.
+</para>
+<para>
+Exim applies a timeout to calls of the local scan function, and there is an
+option called <option>local_scan_timeout</option> for setting it. The default is 5 minutes.
+Zero means <quote>no timeout</quote>.
+Exim also sets up signal handlers for SIGSEGV, SIGILL, SIGFPE, and SIGBUS
+before calling the local scan function, so that the most common types of crash
+are caught. If the timeout is exceeded or one of those signals is caught, the
+incoming message is rejected with a temporary error if it is an SMTP message.
+For a non-SMTP message, the message is dropped and Exim ends with a non-zero
+code. The incident is logged on the main and reject logs.
+</para>
+<section id="SECID207">
+<title>Building Exim to use a local scan function</title>
+<para>
+<indexterm role="concept">
+<primary><function>local_scan()</function> function</primary>
+<secondary>building Exim to use</secondary>
+</indexterm>
+To make use of the local scan function feature, you must tell Exim where your
+function is before building Exim, by setting
+both HAVE_LOCAL_SCAN and
+LOCAL_SCAN_SOURCE in your
+<filename>Local/Makefile</filename>. A recommended place to put it is in the <filename>Local</filename>
+directory, so you might set
+</para>
+<literallayout class="monospaced">
+HAVE_LOCAL_SCAN=yes
+LOCAL_SCAN_SOURCE=Local/local_scan.c
+</literallayout>
+<para>
+for example. The function must be called <function>local_scan()</function>;
+</para>
+<para revisionflag="changed">
+the source file(s) for it should first #define LOCAL_SCAN
+and then #include "local_scan.h".
+</para>
+<para>
+It is called by
+Exim after it has received a message, when the success return code is about to
+be sent. This is after all the ACLs have been run. The return code from your
+function controls whether the message is actually accepted or not. There is a
+commented template function (that just accepts the message) in the file
+_src/local_scan.c_.
+</para>
+<para>
+If you want to make use of Exim’s runtime configuration file to set options
+for your <function>local_scan()</function> function, you must also set
+</para>
+<literallayout class="monospaced">
+LOCAL_SCAN_HAS_OPTIONS=yes
+</literallayout>
+<para>
+in <filename>Local/Makefile</filename> (see section <xref linkend="SECTconoptloc"/> below).
+</para>
+</section>
+<section id="SECTapiforloc">
+<title>API for local_scan()</title>
+<para>
+<indexterm role="concept">
+<primary><function>local_scan()</function> function</primary>
+<secondary>API description</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>dlfunc</option></primary>
+<secondary>API description</secondary>
+</indexterm>
+You must include this line near the start of your code:
+</para>
+<literallayout class="monospaced">
+#define LOCAL_SCAN
+#include "local_scan.h"
+</literallayout>
+<para>
+This header file defines a number of variables and other values, and the
+prototype for the function itself. Exim is coded to use unsigned char values
+almost exclusively, and one of the things this header defines is a shorthand
+for <literal>unsigned char</literal> called <literal>uschar</literal>.
+It also makes available the following macro definitions, to simplify casting character
+strings and pointers to character strings:
+</para>
+<literallayout class="monospaced">
+#define CS (char *)
+#define CCS (const char *)
+#define CSS (char **)
+#define US (unsigned char *)
+#define CUS (const unsigned char *)
+#define USS (unsigned char **)
+</literallayout>
+<para>
+The function prototype for <function>local_scan()</function> is:
+</para>
+<literallayout class="monospaced">
+extern int local_scan(int fd, uschar **return_text);
+</literallayout>
+<para>
+The arguments are as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<option>fd</option> is a file descriptor for the file that contains the body of the message
+(the -D file). The file is open for reading and writing, but updating it is not
+recommended. <emphasis role="bold">Warning</emphasis>: You must <emphasis>not</emphasis> close this file descriptor.
+</para>
+<para>
+The descriptor is positioned at character 19 of the file, which is the first
+character of the body itself, because the first 19 characters are the message
+id followed by <literal>-D</literal> and a newline. If you rewind the file, you should use the
+macro SPOOL_DATA_START_OFFSET to reset to the start of the data, just in
+case this changes in some future version.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>return_text</option> is an address which you can use to return a pointer to a text
+string at the end of the function. The value it points to on entry is NULL.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The function must return an <option>int</option> value which is one of the following macros:
+</para>
+<variablelist>
+<varlistentry>
+<term><literal>LOCAL_SCAN_ACCEPT</literal></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_scan_data</varname></primary>
+</indexterm>
+The message is accepted. If you pass back a string of text, it is saved with
+the message, and made available in the variable <varname>$local_scan_data</varname>. No
+newlines are permitted (if there are any, they are turned into spaces) and the
+maximum length of text is 1000 characters.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><literal>LOCAL_SCAN_ACCEPT_FREEZE</literal></term>
+<listitem>
+<para>
+This behaves as LOCAL_SCAN_ACCEPT, except that the accepted message is
+queued without immediate delivery, and is frozen.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><literal>LOCAL_SCAN_ACCEPT_QUEUE</literal></term>
+<listitem>
+<para>
+This behaves as LOCAL_SCAN_ACCEPT, except that the accepted message is
+queued without immediate delivery.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><literal>LOCAL_SCAN_REJECT</literal></term>
+<listitem>
+<para>
+The message is rejected; the returned text is used as an error message which is
+passed back to the sender and which is also logged. Newlines are permitted –
+they cause a multiline response for SMTP rejections, but are converted to
+<literal>\n</literal> in log lines. If no message is given, <quote>Administrative prohibition</quote> is
+used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><literal>LOCAL_SCAN_TEMPREJECT</literal></term>
+<listitem>
+<para>
+The message is temporarily rejected; the returned text is used as an error
+message as for LOCAL_SCAN_REJECT. If no message is given, <quote>Temporary local
+problem</quote> is used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><literal>LOCAL_SCAN_REJECT_NOLOGHDR</literal></term>
+<listitem>
+<para>
+This behaves as LOCAL_SCAN_REJECT, except that the header of the rejected
+message is not written to the reject log. It has the effect of unsetting the
+<option>rejected_header</option> log selector for just this rejection. If
+<option>rejected_header</option> is already unset (see the discussion of the
+<option>log_selection</option> option in section <xref linkend="SECTlogselector"/>), this code is the
+same as LOCAL_SCAN_REJECT.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><literal>LOCAL_SCAN_TEMPREJECT_NOLOGHDR</literal></term>
+<listitem>
+<para>
+This code is a variation of LOCAL_SCAN_TEMPREJECT in the same way that
+LOCAL_SCAN_REJECT_NOLOGHDR is a variation of LOCAL_SCAN_REJECT.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+If the message is not being received by interactive SMTP, rejections are
+reported by writing to <option>stderr</option> or by sending an email, as configured by the
+<option>-oe</option> command line options.
+</para>
+</section>
+<section id="SECTconoptloc">
+<title>Configuration options for local_scan()</title>
+<para>
+<indexterm role="concept">
+<primary><function>local_scan()</function> function</primary>
+<secondary>configuration options</secondary>
+</indexterm>
+It is possible to have option settings in the main configuration file
+that set values in static variables in the <function>local_scan()</function> module. If you
+want to do this, you must have the line
+</para>
+<literallayout class="monospaced">
+LOCAL_SCAN_HAS_OPTIONS=yes
+</literallayout>
+<para>
+in your <filename>Local/Makefile</filename> when you build Exim. (This line is in
+<filename>OS/Makefile-Default</filename>, commented out). Then, in the <function>local_scan()</function> source
+file, you must define static variables to hold the option values, and a table
+to define them.
+</para>
+<para>
+The table must be a vector called <option>local_scan_options</option>, of type
+<literal>optionlist</literal>. Each entry is a triplet, consisting of a name, an option type,
+and a pointer to the variable that holds the value. The entries must appear in
+alphabetical order. Following <option>local_scan_options</option> you must also define a
+variable called <option>local_scan_options_count</option> that contains the number of
+entries in the table. Here is a short example, showing two kinds of option:
+</para>
+<literallayout class="monospaced">
+static int my_integer_option = 42;
+static uschar *my_string_option = US"a default string";
+
+optionlist local_scan_options[] = {
+ { "my_integer", opt_int, &my_integer_option },
+ { "my_string", opt_stringptr, &my_string_option }
+};
+
+int local_scan_options_count =
+ sizeof(local_scan_options)/sizeof(optionlist);
+</literallayout>
+<para>
+The values of the variables can now be changed from Exim’s runtime
+configuration file by including a local scan section as in this example:
+</para>
+<literallayout class="monospaced">
+begin local_scan
+my_integer = 99
+my_string = some string of text...
+</literallayout>
+<para>
+The available types of option data are as follows:
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">opt_bool</emphasis></term>
+<listitem>
+<para>
+This specifies a boolean (true/false) option. The address should point to a
+variable of type <literal>BOOL</literal>, which will be set to TRUE or FALSE, which are macros
+that are defined as <quote>1</quote> and <quote>0</quote>, respectively. If you want to detect
+whether such a variable has been set at all, you can initialize it to
+TRUE_UNSET. (BOOL variables are integers underneath, so can hold more than two
+values.)
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">opt_fixed</emphasis></term>
+<listitem>
+<para>
+This specifies a fixed point number, such as is used for load averages.
+The address should point to a variable of type <literal>int</literal>. The value is stored
+multiplied by 1000, so, for example, 1.4142 is truncated and stored as 1414.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">opt_int</emphasis></term>
+<listitem>
+<para>
+This specifies an integer; the address should point to a variable of type
+<literal>int</literal>. The value may be specified in any of the integer formats accepted by
+Exim.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">opt_mkint</emphasis></term>
+<listitem>
+<para>
+This is the same as <option>opt_int</option>, except that when such a value is output in a
+<option>-bP</option> listing, if it is an exact number of kilobytes or megabytes, it is
+printed with the suffix K or M.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">opt_octint</emphasis></term>
+<listitem>
+<para>
+This also specifies an integer, but the value is always interpreted as an
+octal integer, whether or not it starts with the digit zero, and it is
+always output in octal.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">opt_stringptr</emphasis></term>
+<listitem>
+<para>
+This specifies a string value; the address must be a pointer to a
+variable that points to a string (for example, of type <literal>uschar *</literal>).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">opt_time</emphasis></term>
+<listitem>
+<para>
+This specifies a time interval value. The address must point to a variable of
+type <literal>int</literal>. The value that is placed there is a number of seconds.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+If the <option>-bP</option> command line option is followed by <literal>local_scan</literal>, Exim prints
+out the values of all the <function>local_scan()</function> options.
+</para>
+</section>
+<section id="SECID208">
+<title>Available Exim variables</title>
+<para>
+<indexterm role="concept">
+<primary><function>local_scan()</function> function</primary>
+<secondary>available Exim variables</secondary>
+</indexterm>
+The header <filename>local_scan.h</filename> gives you access to a number of C variables. These
+are the only ones that are guaranteed to be maintained from release to release.
+Note, however, that you can obtain the value of any Exim expansion variable,
+including <varname>$recipients</varname>, by calling <emphasis>expand_string()</emphasis>. The exported
+C variables are as follows:
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">int body_linecount</emphasis></term>
+<listitem>
+<para>
+This variable contains the number of lines in the message’s body.
+It is not valid if the <option>spool_files_wireformat</option> option is used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int body_zerocount</emphasis></term>
+<listitem>
+<para>
+This variable contains the number of binary zero bytes in the message’s body.
+It is not valid if the <option>spool_files_wireformat</option> option is used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">unsigned int debug_selector</emphasis></term>
+<listitem>
+<para>
+This variable is set to zero when no debugging is taking place. Otherwise, it
+is a bitmap of debugging selectors. Two bits are identified for use in
+<function>local_scan()</function>; they are defined as macros:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The <literal>D_v</literal> bit is set when <option>-v</option> was present on the command line. This is a
+testing option that is not privileged – any caller may set it. All the
+other selector bits can be set only by admin users.
+</para>
+</listitem>
+<listitem>
+<para>
+The <literal>D_local_scan</literal> bit is provided for use by <function>local_scan()</function>; it is set
+by the <literal>+local_scan</literal> debug selector. It is not included in the default set
+of debugging bits.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Thus, to write to the debugging output only when <literal>+local_scan</literal> has been
+selected, you should use code like this:
+</para>
+<literallayout class="monospaced">
+if ((debug_selector & D_local_scan) != 0)
+ debug_printf("xxx", ...);
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *expand_string_message</emphasis></term>
+<listitem>
+<para>
+After a failing call to <emphasis>expand_string()</emphasis> (returned value NULL), the
+variable <option>expand_string_message</option> contains the error message, zero-terminated.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">header_line *header_list</emphasis></term>
+<listitem>
+<para>
+A pointer to a chain of header lines. The <option>header_line</option> structure is
+discussed below.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">header_line *header_last</emphasis></term>
+<listitem>
+<para>
+A pointer to the last of the header lines.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *headers_charset</emphasis></term>
+<listitem>
+<para>
+The value of the <option>headers_charset</option> configuration option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">BOOL host_checking</emphasis></term>
+<listitem>
+<para>
+This variable is TRUE during a host checking session that is initiated by the
+<option>-bh</option> command line option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *interface_address</emphasis></term>
+<listitem>
+<para>
+The IP address of the interface that received the message, as a string. This
+is NULL for locally submitted messages.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int interface_port</emphasis></term>
+<listitem>
+<para>
+The port on which this message was received. When testing with the <option>-bh</option>
+command line option, the value of this variable is -1 unless a port has been
+specified via the <option>-oMi</option> option.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *message_id</emphasis></term>
+<listitem>
+<para>
+This variable contains Exim’s message id for the incoming message (the value of
+<varname>$message_exim_id</varname>) as a zero-terminated string.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *received_protocol</emphasis></term>
+<listitem>
+<para>
+The name of the protocol by which the message was received.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int recipients_count</emphasis></term>
+<listitem>
+<para>
+The number of accepted recipients.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">recipient_item *recipients_list</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>recipient</primary>
+<secondary>adding in local scan</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>recipient</primary>
+<secondary>removing in local scan</secondary>
+</indexterm>
+The list of accepted recipients, held in a vector of length
+<option>recipients_count</option>. The <option>recipient_item</option> structure is discussed below. You
+can add additional recipients by calling <emphasis>receive_add_recipient()</emphasis> (see
+below). You can delete recipients by removing them from the vector and
+adjusting the value in <option>recipients_count</option>. In particular, by setting
+<option>recipients_count</option> to zero you remove all recipients. If you then return the
+value <literal>LOCAL_SCAN_ACCEPT</literal>, the message is accepted, but immediately
+blackholed. To replace the recipients, you can set <option>recipients_count</option> to zero
+and then call <emphasis>receive_add_recipient()</emphasis> as often as needed.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *sender_address</emphasis></term>
+<listitem>
+<para>
+The envelope sender address. For bounce messages this is the empty string.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *sender_host_address</emphasis></term>
+<listitem>
+<para>
+The IP address of the sending host, as a string. This is NULL for
+locally-submitted messages.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *sender_host_authenticated</emphasis></term>
+<listitem>
+<para>
+The name of the authentication mechanism that was used, or NULL if the message
+was not received over an authenticated SMTP connection.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *sender_host_name</emphasis></term>
+<listitem>
+<para>
+The name of the sending host, if known.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int sender_host_port</emphasis></term>
+<listitem>
+<para>
+The port on the sending host.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">BOOL smtp_input</emphasis></term>
+<listitem>
+<para>
+This variable is TRUE for all SMTP input, including BSMTP.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">BOOL smtp_batched_input</emphasis></term>
+<listitem>
+<para>
+This variable is TRUE for BSMTP input.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int store_pool</emphasis></term>
+<listitem>
+<para>
+The contents of this variable control which pool of memory is used for new
+requests. See section <xref linkend="SECTmemhanloc"/> for details.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</section>
+<section id="SECID209">
+<title>Structure of header lines</title>
+<para>
+The <option>header_line</option> structure contains the members listed below.
+You can add additional header lines by calling the <emphasis>header_add()</emphasis> function
+(see below). You can cause header lines to be ignored (deleted) by setting
+their type to *.
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">struct header_line *next</emphasis></term>
+<listitem>
+<para>
+A pointer to the next header line, or NULL for the last line.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int type</emphasis></term>
+<listitem>
+<para>
+A code identifying certain headers that Exim recognizes. The codes are printing
+characters, and are documented in chapter <xref linkend="CHAPspool"/> of this manual.
+Notice in particular that any header line whose type is * is not transmitted
+with the message. This flagging is used for header lines that have been
+rewritten, or are to be removed (for example, <emphasis>Envelope-sender:</emphasis> header
+lines.) Effectively, * means <quote>deleted</quote>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int slen</emphasis></term>
+<listitem>
+<para>
+The number of characters in the header line, including the terminating and any
+internal newlines.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *text</emphasis></term>
+<listitem>
+<para>
+A pointer to the text of the header. It always ends with a newline, followed by
+a zero byte. Internal newlines are preserved.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</section>
+<section id="SECID210">
+<title>Structure of recipient items</title>
+<para>
+The <option>recipient_item</option> structure contains these members:
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">uschar *address</emphasis></term>
+<listitem>
+<para>
+This is a pointer to the recipient address as it was received.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int pno</emphasis></term>
+<listitem>
+<para>
+This is used in later Exim processing when top level addresses are created by
+the <option>one_time</option> option. It is not relevant at the time <function>local_scan()</function> is run
+and must always contain -1 at this stage.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *errors_to</emphasis></term>
+<listitem>
+<para>
+If this value is not NULL, bounce messages caused by failing to deliver to the
+recipient are sent to the address it contains. In other words, it overrides the
+envelope sender for this one recipient. (Compare the <option>errors_to</option> generic
+router option.) If a <function>local_scan()</function> function sets an <option>errors_to</option> field to
+an unqualified address, Exim qualifies it using the domain from
+<option>qualify_recipient</option>. When <function>local_scan()</function> is called, the <option>errors_to</option> field
+is NULL for all recipients.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</section>
+<section id="SECID211">
+<title>Available Exim functions</title>
+<para>
+<indexterm role="concept">
+<primary><function>local_scan()</function> function</primary>
+<secondary>available Exim functions</secondary>
+</indexterm>
+The header <filename>local_scan.h</filename> gives you access to a number of Exim functions.
+These are the only ones that are guaranteed to be maintained from release to
+release:
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">pid_t child_open(uschar **argv, uschar **envp, int newumask, int *infdptr, int *outfdptr, BOOL make_leader)</emphasis></term>
+<listitem>
+<para>
+This function creates a child process that runs the command specified by
+<option>argv</option>. The environment for the process is specified by <option>envp</option>, which can
+be NULL if no environment variables are to be passed. A new umask is supplied
+for the process in <option>newumask</option>.
+</para>
+<para>
+Pipes to the standard input and output of the new process are set up
+and returned to the caller via the <option>infdptr</option> and <option>outfdptr</option> arguments. The
+standard error is cloned to the standard output. If there are any file
+descriptors <quote>in the way</quote> in the new process, they are closed. If the final
+argument is TRUE, the new process is made into a process group leader.
+</para>
+<para>
+The function returns the pid of the new process, or -1 if things go wrong.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int child_close(pid_t pid, int timeout)</emphasis></term>
+<listitem>
+<para>
+This function waits for a child process to terminate, or for a timeout (in
+seconds) to expire. A timeout value of zero means wait as long as it takes. The
+return value is as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+>= 0
+</para>
+<para>
+The process terminated by a normal exit and the value is the process
+ending status.
+</para>
+</listitem>
+<listitem>
+<para>
+< 0 and > –256
+</para>
+<para>
+The process was terminated by a signal and the value is the negation of the
+signal number.
+</para>
+</listitem>
+<listitem>
+<para>
+–256
+</para>
+<para>
+The process timed out.
+</para>
+</listitem>
+<listitem>
+<para>
+–257
+</para>
+<para>
+The was some other error in wait(); <option>errno</option> is still set.
+</para>
+</listitem>
+</itemizedlist>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">pid_t child_open_exim(int *fd)</emphasis></term>
+<listitem>
+<para>
+This function provide you with a means of submitting a new message to
+Exim. (Of course, you can also call <filename>/usr/sbin/sendmail</filename> yourself if you
+want, but this packages it all up for you.) The function creates a pipe,
+forks a subprocess that is running
+</para>
+<literallayout class="monospaced">
+exim -t -oem -oi -f <>
+</literallayout>
+<para>
+and returns to you (via the <literal>int *</literal> argument) a file descriptor for the pipe
+that is connected to the standard input. The yield of the function is the PID
+of the subprocess. You can then write a message to the file descriptor, with
+recipients in <emphasis>To:</emphasis>, <emphasis>Cc:</emphasis>, and/or <emphasis>Bcc:</emphasis> header lines.
+</para>
+<para>
+When you have finished, call <emphasis>child_close()</emphasis> to wait for the process to
+finish and to collect its ending status. A timeout value of zero is usually
+fine in this circumstance. Unless you have made a mistake with the recipient
+addresses, you should get a return code of zero.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">pid_t child_open_exim2(int *fd, uschar *sender, uschar *sender_authentication)</emphasis></term>
+<listitem>
+<para>
+This function is a more sophisticated version of <emphasis>child_open()</emphasis>. The command
+that it runs is:
+</para>
+<literallayout>
+<literal>exim -t -oem -oi -f </literal><emphasis>sender</emphasis><literal> -oMas </literal><emphasis>sender_authentication</emphasis>
+</literallayout>
+<para>
+The third argument may be NULL, in which case the <option>-oMas</option> option is omitted.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">void debug_printf(char *, ...)</emphasis></term>
+<listitem>
+<para>
+This is Exim’s debugging function, with arguments as for <emphasis>(printf()</emphasis>. The
+output is written to the standard error stream. If no debugging is selected,
+calls to <emphasis>debug_printf()</emphasis> have no effect. Normally, you should make calls
+conditional on the <literal>local_scan</literal> debug selector by coding like this:
+</para>
+<literallayout class="monospaced">
+if ((debug_selector & D_local_scan) != 0)
+ debug_printf("xxx", ...);
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *expand_string(uschar *string)</emphasis></term>
+<listitem>
+<para>
+This is an interface to Exim’s string expansion code. The return value is the
+expanded string, or NULL if there was an expansion failure.
+The C variable <option>expand_string_message</option> contains an error message after an
+expansion failure. If expansion does not change the string, the return value is
+the pointer to the input string. Otherwise, the return value points to a new
+block of memory that was obtained by a call to <emphasis>store_get()</emphasis>. See section
+<xref linkend="SECTmemhanloc"/> below for a discussion of memory handling.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">void header_add(int type, char *format, ...)</emphasis></term>
+<listitem>
+<para>
+This function allows you to an add additional header line at the end of the
+existing ones. The first argument is the type, and should normally be a space
+character. The second argument is a format string and any number of
+substitution arguments as for <function>sprintf()</function>. You may include internal newlines
+if you want, and you must ensure that the string ends with a newline.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">void header_add_at_position(BOOL after, uschar *name, BOOL topnot, int type, char *format, ...)</emphasis></term>
+<listitem>
+<para>
+This function adds a new header line at a specified point in the header
+chain. The header itself is specified as for <emphasis>header_add()</emphasis>.
+</para>
+<para>
+If <option>name</option> is NULL, the new header is added at the end of the chain if
+<option>after</option> is true, or at the start if <option>after</option> is false. If <option>name</option> is not
+NULL, the header lines are searched for the first non-deleted header that
+matches the name. If one is found, the new header is added before it if
+<option>after</option> is false. If <option>after</option> is true, the new header is added after the
+found header and any adjacent subsequent ones with the same name (even if
+marked <quote>deleted</quote>). If no matching non-deleted header is found, the <option>topnot</option>
+option controls where the header is added. If it is true, addition is at the
+top; otherwise at the bottom. Thus, to add a header after all the <emphasis>Received:</emphasis>
+headers, or at the top if there are no <emphasis>Received:</emphasis> headers, you could use
+</para>
+<literallayout class="monospaced">
+header_add_at_position(TRUE, US"Received", TRUE,
+ ' ', "X-xxx: ...");
+</literallayout>
+<para>
+Normally, there is always at least one non-deleted <emphasis>Received:</emphasis> header, but
+there may not be if <option>received_header_text</option> expands to an empty string.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">void header_remove(int occurrence, uschar *name)</emphasis></term>
+<listitem>
+<para>
+This function removes header lines. If <option>occurrence</option> is zero or negative, all
+occurrences of the header are removed. If occurrence is greater than zero, that
+particular instance of the header is removed. If no header(s) can be found that
+match the specification, the function does nothing.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">BOOL header_testname(header_line *hdr, uschar *name, int length, BOOL notdel)</emphasis></term>
+<listitem>
+<para>
+This function tests whether the given header has the given name. It is not just
+a string comparison, because white space is permitted between the name and the
+colon. If the <option>notdel</option> argument is true, a false return is forced for all
+<quote>deleted</quote> headers; otherwise they are not treated specially. For example:
+</para>
+<literallayout class="monospaced">
+if (header_testname(h, US"X-Spam", 6, TRUE)) ...
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *lss_b64encode(uschar *cleartext, int length)</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>base64 encoding</primary>
+<secondary>functions for <function>local_scan()</function> use</secondary>
+</indexterm>
+This function base64-encodes a string, which is passed by address and length.
+The text may contain bytes of any value, including zero. The result is passed
+back in dynamic memory that is obtained by calling <emphasis>store_get()</emphasis>. It is
+zero-terminated.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int lss_b64decode(uschar *codetext, uschar **cleartext)</emphasis></term>
+<listitem>
+<para>
+This function decodes a base64-encoded string. Its arguments are a
+zero-terminated base64-encoded string and the address of a variable that is set
+to point to the result, which is in dynamic memory. The length of the decoded
+string is the yield of the function. If the input is invalid base64 data, the
+yield is -1. A zero byte is added to the end of the output string to make it
+easy to interpret as a C string (assuming it contains no zeros of its own). The
+added zero byte is not included in the returned count.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int lss_match_domain(uschar *domain, uschar *list)</emphasis></term>
+<listitem>
+<para>
+This function checks for a match in a domain list. Domains are always
+matched caselessly. The return value is one of the following:
+</para>
+<literallayout>
+<literal>OK </literal> match succeeded
+<literal>FAIL </literal> match failed
+<literal>DEFER </literal> match deferred
+</literallayout>
+<para>
+DEFER is usually caused by some kind of lookup defer, such as the
+inability to contact a database.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int lss_match_local_part(uschar *localpart, uschar *list, BOOL caseless)</emphasis></term>
+<listitem>
+<para>
+This function checks for a match in a local part list. The third argument
+controls case-sensitivity. The return values are as for
+<emphasis>lss_match_domain()</emphasis>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int lss_match_address(uschar *address, uschar *list, BOOL caseless)</emphasis></term>
+<listitem>
+<para>
+This function checks for a match in an address list. The third argument
+controls the case-sensitivity of the local part match. The domain is always
+matched caselessly. The return values are as for <emphasis>lss_match_domain()</emphasis>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int lss_match_host(uschar *host_name, uschar *host_address, uschar *list)</emphasis></term>
+<listitem>
+<para>
+This function checks for a match in a host list. The most common usage is
+expected to be
+</para>
+<literallayout class="monospaced">
+lss_match_host(sender_host_name, sender_host_address, ...)
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$sender_host_address</varname></primary>
+</indexterm>
+An empty address field matches an empty item in the host list. If the host name
+is NULL, the name corresponding to <varname>$sender_host_address</varname> is automatically
+looked up if a host name is required to match an item in the list. The return
+values are as for <emphasis>lss_match_domain()</emphasis>, but in addition, <emphasis>lss_match_host()</emphasis>
+returns ERROR in the case when it had to look up a host name, but the lookup
+failed.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">void log_write(unsigned int selector, int which, char *format, ...)</emphasis></term>
+<listitem>
+<para>
+This function writes to Exim’s log files. The first argument should be zero (it
+is concerned with <option>log_selector</option>). The second argument can be <literal>LOG_MAIN</literal> or
+<literal>LOG_REJECT</literal> or <literal>LOG_PANIC</literal> or the inclusive <quote>or</quote> of any combination of
+them. It specifies to which log or logs the message is written. The remaining
+arguments are a format and relevant insertion arguments. The string should not
+contain any newlines, not even at the end.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">void receive_add_recipient(uschar *address, int pno)</emphasis></term>
+<listitem>
+<para>
+This function adds an additional recipient to the message. The first argument
+is the recipient address. If it is unqualified (has no domain), it is qualified
+with the <option>qualify_recipient</option> domain. The second argument must always be -1.
+</para>
+<para>
+This function does not allow you to specify a private <option>errors_to</option> address (as
+described with the structure of <option>recipient_item</option> above), because it pre-dates
+the addition of that field to the structure. However, it is easy to add such a
+value afterwards. For example:
+</para>
+<literallayout class="monospaced">
+ receive_add_recipient(US"monitor@mydom.example", -1);
+ recipients_list[recipients_count-1].errors_to =
+ US"postmaster@mydom.example";
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">BOOL receive_remove_recipient(uschar *recipient)</emphasis></term>
+<listitem>
+<para>
+This is a convenience function to remove a named recipient from the list of
+recipients. It returns true if a recipient was removed, and false if no
+matching recipient could be found. The argument must be a complete email
+address.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+<indexterm role="concept">
+<primary>RFC 2047</primary>
+</indexterm>
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">uschar rfc2047_decode(uschar *string, BOOL lencheck, uschar *target, int zeroval, int *lenptr, uschar **error)</emphasis></term>
+<listitem>
+<para>
+This function decodes strings that are encoded according to RFC 2047. Typically
+these are the contents of header lines. First, each <quote>encoded word</quote> is decoded
+from the Q or B encoding into a byte-string. Then, if provided with the name of
+a charset encoding, and if the <function>iconv()</function> function is available, an attempt is
+made to translate the result to the named character set. If this fails, the
+binary string is returned with an error message.
+</para>
+<para>
+The first argument is the string to be decoded. If <option>lencheck</option> is TRUE, the
+maximum MIME word length is enforced. The third argument is the target
+encoding, or NULL if no translation is wanted.
+</para>
+<para>
+<indexterm role="concept">
+<primary>binary zero</primary>
+<secondary>in RFC 2047 decoding</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>RFC 2047</primary>
+<secondary>binary zero in</secondary>
+</indexterm>
+If a binary zero is encountered in the decoded string, it is replaced by the
+contents of the <option>zeroval</option> argument. For use with Exim headers, the value must
+not be 0 because header lines are handled as zero-terminated strings.
+</para>
+<para>
+The function returns the result of processing the string, zero-terminated; if
+<option>lenptr</option> is not NULL, the length of the result is set in the variable to
+which it points. When <option>zeroval</option> is 0, <option>lenptr</option> should not be NULL.
+</para>
+<para>
+If an error is encountered, the function returns NULL and uses the <option>error</option>
+argument to return an error message. The variable pointed to by <option>error</option> is
+set to NULL if there is no error; it may be set non-NULL even when the function
+returns a non-NULL value if decoding was successful, but there was a problem
+with translation.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">int smtp_fflush(void)</emphasis></term>
+<listitem>
+<para>
+This function is used in conjunction with <emphasis>smtp_printf()</emphasis>, as described
+below.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">void smtp_printf(char *,BOOL, ...)</emphasis></term>
+<listitem>
+<para>
+The arguments of this function are almost like <function>printf()</function>; it writes to the SMTP
+output stream. You should use this function only when there is an SMTP output
+stream, that is, when the incoming message is being received via interactive
+SMTP. This is the case when <option>smtp_input</option> is TRUE and <option>smtp_batched_input</option>
+is FALSE. If you want to test for an incoming message from another host (as
+opposed to a local process that used the <option>-bs</option> command line option), you can
+test the value of <option>sender_host_address</option>, which is non-NULL when a remote host
+is involved.
+</para>
+<para>
+If an SMTP TLS connection is established, <emphasis>smtp_printf()</emphasis> uses the TLS
+output function, so it can be used for all forms of SMTP connection.
+</para>
+<para>
+The second argument is used to request that the data be buffered
+(when TRUE) or flushed (along with any previously buffered, when FALSE).
+This is advisory only, but likely to save on system-calls and packets
+sent when a sequence of calls to the function are made.
+</para>
+<para>
+The argument was added in Exim version 4.90 - changing the API/ABI.
+Nobody noticed until 4.93 was imminent, at which point the
+ABI version number was incremented.
+</para>
+<para>
+Strings that are written by <emphasis>smtp_printf()</emphasis> from within <function>local_scan()</function>
+must start with an appropriate response code: 550 if you are going to return
+LOCAL_SCAN_REJECT, 451 if you are going to return
+LOCAL_SCAN_TEMPREJECT, and 250 otherwise. Because you are writing the
+initial lines of a multi-line response, the code must be followed by a hyphen
+to indicate that the line is not the final response line. You must also ensure
+that the lines you write terminate with CRLF. For example:
+</para>
+<literallayout class="monospaced">
+smtp_printf("550-this is some extra info\r\n");
+return LOCAL_SCAN_REJECT;
+</literallayout>
+<para>
+Note that you can also create multi-line responses by including newlines in
+the data returned via the <option>return_text</option> argument. The added value of using
+<emphasis>smtp_printf()</emphasis> is that, for instance, you could introduce delays between
+multiple output lines.
+</para>
+<para>
+The <emphasis>smtp_printf()</emphasis> function does not return any error indication, because it
+does not
+guarantee a flush of
+pending output, and therefore does not test
+the state of the stream. (In the main code of Exim, flushing and error
+detection is done when Exim is ready for the next SMTP input command.) If
+you want to flush the output and check for an error (for example, the
+dropping of a TCP/IP connection), you can call <emphasis>smtp_fflush()</emphasis>, which has no
+arguments. It flushes the output stream, and returns a non-zero value if there
+is an error.
+</para>
+</listitem></varlistentry>
+<varlistentry revisionflag="changed">
+<term><emphasis role="bold">void *store_get(int,BOOL)</emphasis></term>
+<listitem>
+<para revisionflag="changed">
+This function accesses Exim’s internal store (memory) manager. It gets a new
+chunk of memory whose size is given by the first argument.
+The second argument should be given as TRUE if the memory will be used for
+data possibly coming from an attacker (eg. the message content),
+FALSE if it is locally-sourced.
+Exim bombs out if it ever
+runs out of memory. See the next section for a discussion of memory handling.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">void *store_get_perm(int,BOOL)</emphasis></term>
+<listitem>
+<para>
+This function is like <emphasis>store_get()</emphasis>, but it always gets memory from the
+permanent pool. See the next section for a discussion of memory handling.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *string_copy(uschar *string)</emphasis></term>
+<listitem>
+<para>
+See below.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *string_copyn(uschar *string, int length)</emphasis></term>
+<listitem>
+<para>
+See below.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">uschar *string_sprintf(char *format, ...)</emphasis></term>
+<listitem>
+<para>
+These three functions create strings using Exim’s dynamic memory facilities.
+The first makes a copy of an entire string. The second copies up to a maximum
+number of characters, indicated by the second argument. The third uses a format
+and insertion arguments to create a new string. In each case, the result is a
+pointer to a new string in the current memory pool. See the next section for
+more discussion.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</section>
+<section id="SECTmemhanloc">
+<title>More about Exim’s memory handling</title>
+<para>
+<indexterm role="concept">
+<primary><function>local_scan()</function> function</primary>
+<secondary>memory handling</secondary>
+</indexterm>
+No function is provided for freeing memory, because that is never needed.
+The dynamic memory that Exim uses when receiving a message is automatically
+recycled if another message is received by the same process (this applies only
+to incoming SMTP connections – other input methods can supply only one
+message at a time). After receiving the last message, a reception process
+terminates.
+</para>
+<para>
+Because it is recycled, the normal dynamic memory cannot be used for holding
+data that must be preserved over a number of incoming messages on the same SMTP
+connection. However, Exim in fact uses two pools of dynamic memory; the second
+one is not recycled, and can be used for this purpose.
+</para>
+<para>
+If you want to allocate memory that remains available for subsequent messages
+in the same SMTP connection, you should set
+</para>
+<literallayout class="monospaced">
+store_pool = POOL_PERM
+</literallayout>
+<para>
+before calling the function that does the allocation. There is no need to
+restore the value if you do not need to; however, if you do want to revert to
+the normal pool, you can either restore the previous value of <option>store_pool</option> or
+set it explicitly to POOL_MAIN.
+</para>
+<para>
+The pool setting applies to all functions that get dynamic memory, including
+<emphasis>expand_string()</emphasis>, <emphasis>store_get()</emphasis>, and the <emphasis>string_xxx()</emphasis> functions.
+There is also a convenience function called <emphasis>store_get_perm()</emphasis> that gets a
+block of memory from the permanent pool while preserving the value of
+<option>store_pool</option>.
+<indexterm role="concept" startref="IIDlosca" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPsystemfilter">
+<title>System-wide message filtering</title>
+<para>
+<indexterm role="concept" id="IIDsysfil1" class="startofrange">
+<primary>filter</primary>
+<secondary>system filter</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDsysfil2" class="startofrange">
+<primary>filtering all mail</primary>
+</indexterm>
+<indexterm role="concept" id="IIDsysfil3" class="startofrange">
+<primary>system filter</primary>
+</indexterm>
+The previous chapters (on ACLs and the local scan function) describe checks
+that can be applied to messages before they are accepted by a host. There is
+also a mechanism for checking messages once they have been received, but before
+they are delivered. This is called the <emphasis>system filter</emphasis>.
+</para>
+<para>
+The system filter operates in a similar manner to users’ filter files, but it
+is run just once per message (however many recipients the message has).
+It should not normally be used as a substitute for routing, because <option>deliver</option>
+commands in a system router provide new envelope recipient addresses.
+The system filter must be an Exim filter. It cannot be a Sieve filter.
+</para>
+<para>
+The system filter is run at the start of a delivery attempt, before any routing
+is done. If a message fails to be completely delivered at the first attempt,
+the system filter is run again at the start of every retry.
+If you want your filter to do something only once per message, you can make use
+of the <option>first_delivery</option> condition in an <option>if</option> command in the filter to
+prevent it happening on retries.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+<emphasis role="bold">Warning</emphasis>: Because the system filter runs just once, variables that are
+specific to individual recipient addresses, such as <varname>$local_part</varname> and
+<varname>$domain</varname>, are not set, and the <quote>personal</quote> condition is not meaningful. If
+you want to run a centrally-specified filter for each recipient address
+independently, you can do so by setting up a suitable <command>redirect</command> router, as
+described in section <xref linkend="SECTperaddfil"/> below.
+</para>
+<section id="SECID212">
+<title>Specifying a system filter</title>
+<para>
+<indexterm role="concept">
+<primary>uid (user id)</primary>
+<secondary>system filter</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>gid (group id)</primary>
+<secondary>system filter</secondary>
+</indexterm>
+The name of the file that contains the system filter must be specified by
+setting <option>system_filter</option>. If you want the filter to run under a uid and gid
+other than root, you must also set <option>system_filter_user</option> and
+<option>system_filter_group</option> as appropriate. For example:
+</para>
+<literallayout class="monospaced">
+system_filter = /etc/mail/exim.filter
+system_filter_user = exim
+</literallayout>
+<para>
+If a system filter generates any deliveries directly to files or pipes (via the
+<option>save</option> or <option>pipe</option> commands), transports to handle these deliveries must be
+specified by setting <option>system_filter_file_transport</option> and
+<option>system_filter_pipe_transport</option>, respectively. Similarly,
+<option>system_filter_reply_transport</option> must be set to handle any messages generated
+by the <option>reply</option> command.
+</para>
+</section>
+<section id="SECID213">
+<title>Testing a system filter</title>
+<para>
+You can run simple tests of a system filter in the same way as for a user
+filter, but you should use <option>-bF</option> rather than <option>-bf</option>, so that features that
+are permitted only in system filters are recognized.
+</para>
+<para>
+If you want to test the combined effect of a system filter and a user filter,
+you can use both <option>-bF</option> and <option>-bf</option> on the same command line.
+</para>
+</section>
+<section id="SECID214">
+<title>Contents of a system filter</title>
+<para>
+The language used to specify system filters is the same as for users’ filter
+files. It is described in the separate end-user document <emphasis>Exim’s interface to
+mail filtering</emphasis>. However, there are some additional features that are
+available only in system filters; these are described in subsequent sections.
+If they are encountered in a user’s filter file or when testing with <option>-bf</option>,
+they cause errors.
+</para>
+<para>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>manual thaw; testing in filter</secondary>
+</indexterm>
+There are two special conditions which, though available in users’ filter
+files, are designed for use in system filters. The condition <option>first_delivery</option>
+is true only for the first attempt at delivering a message, and
+<option>manually_thawed</option> is true only if the message has been frozen, and
+subsequently thawed by an admin user. An explicit forced delivery counts as a
+manual thaw, but thawing as a result of the <option>auto_thaw</option> setting does not.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: If a system filter uses the <option>first_delivery</option> condition to
+specify an <quote>unseen</quote> (non-significant) delivery, and that delivery does not
+succeed, it will not be tried again.
+If you want Exim to retry an unseen delivery until it succeeds, you should
+arrange to set it up every time the filter runs.
+</para>
+<para>
+When a system filter finishes running, the values of the variables <varname>$n0</varname> –
+<varname>$n9</varname> are copied into <varname>$sn0</varname> – <varname>$sn9</varname> and are thereby made available to
+users’ filter files. Thus a system filter can, for example, set up <quote>scores</quote>
+to which users’ filter files can refer.
+</para>
+</section>
+<section id="SECID215">
+<title>Additional variable for system filters</title>
+<para>
+<indexterm role="variable">
+<primary><varname>$recipients</varname></primary>
+</indexterm>
+The expansion variable <varname>$recipients</varname>, containing a list of all the recipients
+of the message (separated by commas and white space), is available in system
+filters. It is not available in users’ filters for privacy reasons.
+</para>
+</section>
+<section id="SECID216">
+<title>Defer, freeze, and fail commands for system filters</title>
+<para>
+<indexterm role="concept">
+<primary>freezing messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>freezing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>forced failure</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>fail</option></primary>
+<secondary>in system filter</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>freeze</option> in system filter</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>defer</option> in system filter</primary>
+</indexterm>
+There are three extra commands (<option>defer</option>, <option>freeze</option> and <option>fail</option>) which are
+always available in system filters, but are not normally enabled in users’
+filters. (See the <option>allow_defer</option>, <option>allow_freeze</option> and <option>allow_fail</option> options
+for the <command>redirect</command> router.) These commands can optionally be followed by the
+word <option>text</option> and a string containing an error message, for example:
+</para>
+<literallayout class="monospaced">
+fail text "this message looks like spam to me"
+</literallayout>
+<para>
+The keyword <option>text</option> is optional if the next character is a double quote.
+</para>
+<para>
+The <option>defer</option> command defers delivery of the original recipients of the
+message. The <option>fail</option> command causes all the original recipients to be failed,
+and a bounce message to be created. The <option>freeze</option> command suspends all
+delivery attempts for the original recipients. In all cases, any new deliveries
+that are specified by the filter are attempted as normal after the filter has
+run.
+</para>
+<para>
+The <option>freeze</option> command is ignored if the message has been manually unfrozen and
+not manually frozen since. This means that automatic freezing by a system
+filter can be used as a way of checking out suspicious messages. If a message
+is found to be all right, manually unfreezing it allows it to be delivered.
+</para>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary><option>fail</option> command log line</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><option>fail</option></primary>
+<secondary>log line; reducing</secondary>
+</indexterm>
+The text given with a fail command is used as part of the bounce message as
+well as being written to the log. If the message is quite long, this can fill
+up a lot of log space when such failures are common. To reduce the size of the
+log message, Exim interprets the text in a special way if it starts with the
+two characters <literal><<</literal> and contains <literal>>></literal> later. The text between these two
+strings is written to the log, and the rest of the text is used in the bounce
+message. For example:
+</para>
+<literallayout class="monospaced">
+fail "<<filter test 1>>Your message is rejected \
+ because it contains attachments that we are \
+ not prepared to receive."
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>loop</primary>
+<secondary>caused by <option>fail</option></secondary>
+</indexterm>
+Take great care with the <option>fail</option> command when basing the decision to fail on
+the contents of the message, because the bounce message will of course include
+the contents of the original message and will therefore trigger the <option>fail</option>
+command again (causing a mail loop) unless steps are taken to prevent this.
+Testing the <option>error_message</option> condition is one way to prevent this. You could
+use, for example
+</para>
+<literallayout class="monospaced">
+if $message_body contains "this is spam" and not error_message
+then fail text "spam is not wanted here" endif
+</literallayout>
+<para>
+though of course that might let through unwanted bounce messages. The
+alternative is clever checking of the body and/or headers to detect bounces
+generated by the filter.
+</para>
+<para>
+The interpretation of a system filter file ceases after a
+<option>defer</option>,
+<option>freeze</option>, or <option>fail</option> command is obeyed. However, any deliveries that were
+set up earlier in the filter file are honoured, so you can use a sequence such
+as
+</para>
+<literallayout class="monospaced">
+mail ...
+freeze
+</literallayout>
+<para>
+to send a specified message when the system filter is freezing (or deferring or
+failing) a message. The normal deliveries for the message do not, of course,
+take place.
+</para>
+</section>
+<section id="SECTaddremheasys">
+<title>Adding and removing headers in a system filter</title>
+<para>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>adding; in system filter</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>removing; in system filter</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>header lines; adding/removing</secondary>
+</indexterm>
+Two filter commands that are available only in system filters are:
+</para>
+<literallayout class="monospaced">
+headers add <string>
+headers remove <string>
+</literallayout>
+<para>
+The argument for the <option>headers add</option> is a string that is expanded and then
+added to the end of the message’s headers. It is the responsibility of the
+filter maintainer to make sure it conforms to RFC 2822 syntax. Leading white
+space is ignored, and if the string is otherwise empty, or if the expansion is
+forced to fail, the command has no effect.
+</para>
+<para>
+You can use <quote>\n</quote> within the string, followed by white space, to specify
+continued header lines. More than one header may be added in one command by
+including <quote>\n</quote> within the string without any following white space. For
+example:
+</para>
+<literallayout class="monospaced">
+headers add "X-header-1: ....\n \
+ continuation of X-header-1 ...\n\
+ X-header-2: ...."
+</literallayout>
+<para>
+Note that the header line continuation white space after the first newline must
+be placed before the backslash that continues the input string, because white
+space after input continuations is ignored.
+</para>
+<para>
+The argument for <option>headers remove</option> is a colon-separated list of header names.
+This command applies only to those headers that are stored with the message;
+those that are added at delivery time (such as <emphasis>Envelope-To:</emphasis> and
+<emphasis>Return-Path:</emphasis>) cannot be removed by this means. If there is more than one
+header with the same name, they are all removed.
+</para>
+<para>
+The <option>headers</option> command in a system filter makes an immediate change to the set
+of header lines that was received with the message (with possible additions
+from ACL processing). Subsequent commands in the system filter operate on the
+modified set, which also forms the basis for subsequent message delivery.
+Unless further modified during routing or transporting, this set of headers is
+used for all recipients of the message.
+</para>
+<para>
+During routing and transporting, the variables that refer to the contents of
+header lines refer only to those lines that are in this set. Thus, header lines
+that are added by a system filter are visible to users’ filter files and to all
+routers and transports. This contrasts with the manipulation of header lines by
+routers and transports, which is not immediate, but which instead is saved up
+until the message is actually being written (see section
+<xref linkend="SECTheadersaddrem"/>).
+</para>
+<para>
+If the message is not delivered at the first attempt, header lines that were
+added by the system filter are stored with the message, and so are still
+present at the next delivery attempt. Header lines that were removed are still
+present, but marked <quote>deleted</quote> so that they are not transported with the
+message. For this reason, it is usual to make the <option>headers</option> command
+conditional on <option>first_delivery</option> so that the set of header lines is not
+modified more than once.
+</para>
+<para>
+Because header modification in a system filter acts immediately, you have to
+use an indirect approach if you want to modify the contents of a header line.
+For example:
+</para>
+<literallayout class="monospaced">
+headers add "Old-Subject: $h_subject:"
+headers remove "Subject"
+headers add "Subject: new subject (was: $h_old-subject:)"
+headers remove "Old-Subject"
+</literallayout>
+</section>
+<section id="SECID217">
+<title>Setting an errors address in a system filter</title>
+<para>
+<indexterm role="concept">
+<primary>envelope from</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope sender</primary>
+</indexterm>
+In a system filter, if a <option>deliver</option> command is followed by
+</para>
+<literallayout class="monospaced">
+errors_to <some address>
+</literallayout>
+<para>
+in order to change the envelope sender (and hence the error reporting) for that
+delivery, any address may be specified. (In a user filter, only the current
+user’s address can be set.) For example, if some mail is being monitored, you
+might use
+</para>
+<literallayout class="monospaced">
+unseen deliver monitor@spying.example errors_to root@local.example
+</literallayout>
+<para>
+to take a copy which would not be sent back to the normal error reporting
+address if its delivery failed.
+</para>
+</section>
+<section id="SECTperaddfil">
+<title>Per-address filtering</title>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+In contrast to the system filter, which is run just once per message for each
+delivery attempt, it is also possible to set up a system-wide filtering
+operation that runs once for each recipient address. In this case, variables
+such as <varname>$local_part</varname> and <varname>$domain</varname> can be used, and indeed, the choice of
+filter file could be made dependent on them. This is an example of a router
+which implements such a filter:
+</para>
+<literallayout class="monospaced">
+central_filter:
+ check_local_user
+ driver = redirect
+ domains = +local_domains
+ file = /central/filters/$local_part_data
+ no_verify
+ allow_filter
+ allow_freeze
+</literallayout>
+<para>
+The filter is run in a separate process under its own uid. Therefore, either
+<option>check_local_user</option> must be set (as above), in which case the filter is run as
+the local user, or the <option>user</option> option must be used to specify which user to
+use. If both are set, <option>user</option> overrides.
+</para>
+<para>
+Care should be taken to ensure that none of the commands in the filter file
+specify a significant delivery if the message is to go on to be delivered to
+its intended recipient. The router will not then claim to have dealt with the
+address, so it will be passed on to subsequent routers to be delivered in the
+normal way.
+<indexterm role="concept" startref="IIDsysfil1" class="endofrange"/>
+<indexterm role="concept" startref="IIDsysfil2" class="endofrange"/>
+<indexterm role="concept" startref="IIDsysfil3" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPmsgproc">
+<title>Message processing</title>
+<para>
+<indexterm role="concept" id="IIDmesproc" class="startofrange">
+<primary>message</primary>
+<secondary>general processing</secondary>
+</indexterm>
+Exim performs various transformations on the sender and recipient addresses of
+all messages that it handles, and also on the messages’ header lines. Some of
+these are optional and configurable, while others always take place. All of
+this processing, except rewriting as a result of routing, and the addition or
+removal of header lines while delivering, happens when a message is received,
+before it is placed on Exim’s queue.
+</para>
+<para>
+Some of the automatic processing takes place by default only for
+<quote>locally-originated</quote> messages. This adjective is used to describe messages
+that are not received over TCP/IP, but instead are passed to an Exim process on
+its standard input. This includes the interactive <quote>local SMTP</quote> case that is
+set up by the <option>-bs</option> command line option.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: Messages received over TCP/IP on the loopback interface (127.0.0.1
+or ::1) are not considered to be locally-originated. Exim does not treat the
+loopback interface specially in any way.
+</para>
+<para>
+If you want the loopback interface to be treated specially, you must ensure
+that there are appropriate entries in your ACLs.
+</para>
+<section id="SECTsubmodnon">
+<title>Submission mode for non-local messages</title>
+<para>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>submission</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>submission mode</primary>
+</indexterm>
+Processing that happens automatically for locally-originated messages (unless
+<option>suppress_local_fixups</option> is set) can also be requested for messages that are
+received over TCP/IP. The term <quote>submission mode</quote> is used to describe this
+state. Submission mode is set by the modifier
+</para>
+<literallayout class="monospaced">
+control = submission
+</literallayout>
+<para>
+in a MAIL, RCPT, or pre-data ACL for an incoming message (see sections
+<xref linkend="SECTACLmodi"/> and <xref linkend="SECTcontrols"/>). This makes Exim treat the message as
+a local submission, and is normally used when the source of the message is
+known to be an MUA running on a client host (as opposed to an MTA). For
+example, to set submission mode for messages originating on the IPv4 loopback
+interface, you could include the following in the MAIL ACL:
+</para>
+<literallayout class="monospaced">
+warn hosts = 127.0.0.1
+ control = submission
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary><option>sender_retain</option> submission option</primary>
+</indexterm>
+There are some options that can be used when setting submission mode. A slash
+is used to separate options. For example:
+</para>
+<literallayout class="monospaced">
+control = submission/sender_retain
+</literallayout>
+<para>
+Specifying <option>sender_retain</option> has the effect of setting <option>local_sender_retain</option>
+true and <option>local_from_check</option> false for the current incoming message. The first
+of these allows an existing <emphasis>Sender:</emphasis> header in the message to remain, and
+the second suppresses the check to ensure that <emphasis>From:</emphasis> matches the
+authenticated sender. With this setting, Exim still fixes up messages by adding
+<emphasis>Date:</emphasis> and <emphasis>Message-ID:</emphasis> header lines if they are missing, but makes no
+attempt to check sender authenticity in header lines.
+</para>
+<para>
+When <option>sender_retain</option> is not set, a submission mode setting may specify a
+domain to be used when generating a <emphasis>From:</emphasis> or <emphasis>Sender:</emphasis> header line. For
+example:
+</para>
+<literallayout class="monospaced">
+control = submission/domain=some.domain
+</literallayout>
+<para>
+The domain may be empty. How this value is used is described in sections
+<xref linkend="SECTthefrohea"/> and <xref linkend="SECTthesenhea"/>. There is also a <option>name</option> option
+that allows you to specify the user’s full name for inclusion in a created
+<emphasis>Sender:</emphasis> or <emphasis>From:</emphasis> header line. For example:
+</para>
+<literallayout class="monospaced">
+accept authenticated = *
+ control = submission/domain=wonderland.example/\
+ name=${lookup {$authenticated_id} \
+ lsearch {/etc/exim/namelist}}
+</literallayout>
+<para>
+Because the name may contain any characters, including slashes, the <option>name</option>
+option must be given last. The remainder of the string is used as the name. For
+the example above, if <filename>/etc/exim/namelist</filename> contains:
+</para>
+<literallayout class="monospaced">
+bigegg: Humpty Dumpty
+</literallayout>
+<para>
+then when the sender has authenticated as <emphasis>bigegg</emphasis>, the generated <emphasis>Sender:</emphasis>
+line would be:
+</para>
+<literallayout class="monospaced">
+Sender: Humpty Dumpty <bigegg@wonderland.example>
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>return path</primary>
+<secondary>in submission mode</secondary>
+</indexterm>
+By default, submission mode forces the return path to the same address as is
+used to create the <emphasis>Sender:</emphasis> header. However, if <option>sender_retain</option> is
+specified, the return path is also left unchanged.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: The changes caused by submission mode take effect after the predata
+ACL. This means that any sender checks performed before the fix-ups use the
+untrusted sender address specified by the user, not the trusted sender address
+specified by submission mode. Although this might be slightly unexpected, it
+does mean that you can configure ACL checks to spot that a user is trying to
+spoof another’s address.
+</para>
+</section>
+<section id="SECTlineendings">
+<title>Line endings</title>
+<para>
+<indexterm role="concept">
+<primary>line endings</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>carriage return</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>linefeed</primary>
+</indexterm>
+RFC 2821 specifies that CRLF (two characters: carriage-return, followed by
+linefeed) is the line ending for messages transmitted over the Internet using
+SMTP over TCP/IP. However, within individual operating systems, different
+conventions are used. For example, Unix-like systems use just LF, but others
+use CRLF or just CR.
+</para>
+<para>
+Exim was designed for Unix-like systems, and internally, it stores messages
+using the system’s convention of a single LF as a line terminator. When
+receiving a message, all line endings are translated to this standard format.
+Originally, it was thought that programs that passed messages directly to an
+MTA within an operating system would use that system’s convention. Experience
+has shown that this is not the case; for example, there are Unix applications
+that use CRLF in this circumstance. For this reason, and for compatibility with
+other MTAs, the way Exim handles line endings for all messages is now as
+follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+LF not preceded by CR is treated as a line ending.
+</para>
+</listitem>
+<listitem>
+<para>
+CR is treated as a line ending; if it is immediately followed by LF, the LF
+is ignored.
+</para>
+</listitem>
+<listitem>
+<para>
+The sequence <quote>CR, dot, CR</quote> does not terminate an incoming SMTP message,
+nor a local message in the state where a line containing only a dot is a
+terminator.
+</para>
+</listitem>
+<listitem>
+<para>
+If a bare CR is encountered within a header line, an extra space is added after
+the line terminator so as not to end the header line. The reasoning behind this
+is that bare CRs in header lines are most likely either to be mistakes, or
+people trying to play silly games.
+</para>
+</listitem>
+<listitem>
+<para>
+If the first header line received in a message ends with CRLF, a subsequent
+bare LF in a header line is treated in the same way as a bare CR in a header
+line.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID218">
+<title>Unqualified addresses</title>
+<para>
+<indexterm role="concept">
+<primary>unqualified addresses</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>address</primary>
+<secondary>qualification</secondary>
+</indexterm>
+By default, Exim expects every envelope address it receives from an external
+host to be fully qualified. Unqualified addresses cause negative responses to
+SMTP commands. However, because SMTP is used as a means of transporting
+messages from MUAs running on personal workstations, there is sometimes a
+requirement to accept unqualified addresses from specific hosts or IP networks.
+</para>
+<para>
+Exim has two options that separately control which hosts may send unqualified
+sender or recipient addresses in SMTP commands, namely
+<option>sender_unqualified_hosts</option> and <option>recipient_unqualified_hosts</option>. In both
+cases, if an unqualified address is accepted, it is qualified by adding the
+value of <option>qualify_domain</option> or <option>qualify_recipient</option>, as appropriate.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>qualify_domain</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>qualify_recipient</option></primary>
+</indexterm>
+Unqualified addresses in header lines are automatically qualified for messages
+that are locally originated, unless the <option>-bnq</option> option is given on the command
+line. For messages received over SMTP, unqualified addresses in header lines
+are qualified only if unqualified addresses are permitted in SMTP commands. In
+other words, such qualification is also controlled by
+<option>sender_unqualified_hosts</option> and <option>recipient_unqualified_hosts</option>,
+</para>
+</section>
+<section id="SECID219">
+<title>The UUCP From line</title>
+<para>
+<indexterm role="concept">
+<primary><quote>From</quote> line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>UUCP</primary>
+<secondary><quote>From</quote> line</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>sender</primary>
+<secondary>address</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>uucp_from_pattern</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>uucp_from_sender</option></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope from</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope sender</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary><quote>From</quote> line</secondary>
+</indexterm>
+Messages that have come from UUCP (and some other applications) often begin
+with a line containing the envelope sender and a timestamp, following the word
+<quote>From</quote>. Examples of two common formats are:
+</para>
+<literallayout class="monospaced">
+From a.oakley@berlin.mus Fri Jan 5 12:35 GMT 1996
+From f.butler@berlin.mus Fri, 7 Jan 97 14:00:00 GMT
+</literallayout>
+<para>
+This line precedes the RFC 2822 header lines. For compatibility with Sendmail,
+Exim recognizes such lines at the start of messages that are submitted to it
+via the command line (that is, on the standard input). It does not recognize
+such lines in incoming SMTP messages, unless the sending host matches
+<option>ignore_fromline_hosts</option> or the <option>-bs</option> option was used for a local message
+and <option>ignore_fromline_local</option> is set. The recognition is controlled by a
+regular expression that is defined by the <option>uucp_from_pattern</option> option, whose
+default value matches the two common cases shown above and puts the address
+that follows <quote>From</quote> into <varname>$1</varname>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>numerical variables (<varname>$1</varname> <varname>$2</varname> etc)</primary>
+<secondary>in <quote>From </quote> line handling</secondary>
+</indexterm>
+When the caller of Exim for a non-SMTP message that contains a <quote>From</quote> line is
+a trusted user, the message’s sender address is constructed by expanding the
+contents of <option>uucp_sender_address</option>, whose default value is <quote>$1</quote>. This is
+then parsed as an RFC 2822 address. If there is no domain, the local part is
+qualified with <option>qualify_domain</option> unless it is the empty string. However, if
+the command line <option>-f</option> option is used, it overrides the <quote>From</quote> line.
+</para>
+<para>
+If the caller of Exim is not trusted, the <quote>From</quote> line is recognized, but the
+sender address is not changed. This is also the case for incoming SMTP messages
+that are permitted to contain <quote>From</quote> lines.
+</para>
+<para>
+Only one <quote>From</quote> line is recognized. If there is more than one, the second is
+treated as a data line that starts the body of the message, as it is not valid
+as a header line. This also happens if a <quote>From</quote> line is present in an
+incoming SMTP message from a source that is not permitted to send them.
+</para>
+</section>
+<section id="SECID220">
+<title>Resent- header lines</title>
+<para>
+<indexterm role="concept">
+<primary><option>Resent-</option> header lines</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>Resent-</secondary>
+</indexterm>
+RFC 2822 makes provision for sets of header lines starting with the string
+<literal>Resent-</literal> to be added to a message when it is resent by the original
+recipient to somebody else. These headers are <emphasis>Resent-Date:</emphasis>,
+<emphasis>Resent-From:</emphasis>, <emphasis>Resent-Sender:</emphasis>, <emphasis>Resent-To:</emphasis>, <emphasis>Resent-Cc:</emphasis>,
+<emphasis>Resent-Bcc:</emphasis> and <emphasis>Resent-Message-ID:</emphasis>. The RFC says:
+</para>
+<blockquote>
+<para>
+<emphasis>Resent fields are strictly informational. They MUST NOT be used in the normal
+processing of replies or other such automatic actions on messages.</emphasis>
+</para>
+</blockquote>
+<para>
+This leaves things a bit vague as far as other processing actions such as
+address rewriting are concerned. Exim treats <option>Resent-</option> header lines as
+follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+A <emphasis>Resent-From:</emphasis> line that just contains the login id of the submitting user
+is automatically rewritten in the same way as <emphasis>From:</emphasis> (see below).
+</para>
+</listitem>
+<listitem>
+<para>
+If there’s a rewriting rule for a particular header line, it is also applied to
+<option>Resent-</option> header lines of the same type. For example, a rule that rewrites
+<emphasis>From:</emphasis> also rewrites <emphasis>Resent-From:</emphasis>.
+</para>
+</listitem>
+<listitem>
+<para>
+For local messages, if <emphasis>Sender:</emphasis> is removed on input, <emphasis>Resent-Sender:</emphasis> is
+also removed.
+</para>
+</listitem>
+<listitem>
+<para>
+For a locally-submitted message,
+if there are any <option>Resent-</option> header lines but no <emphasis>Resent-Date:</emphasis>,
+<emphasis>Resent-From:</emphasis>, or <emphasis>Resent-Message-Id:</emphasis>, they are added as necessary. It is
+the contents of <emphasis>Resent-Message-Id:</emphasis> (rather than <emphasis>Message-Id:</emphasis>) which are
+included in log lines in this case.
+</para>
+</listitem>
+<listitem>
+<para>
+The logic for adding <emphasis>Sender:</emphasis> is duplicated for <emphasis>Resent-Sender:</emphasis> when any
+<option>Resent-</option> header lines are present.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID221">
+<title>The Auto-Submitted: header line</title>
+<para>
+Whenever Exim generates an autoreply, a bounce, or a delay warning message, it
+includes the header line:
+</para>
+<literallayout class="monospaced">
+Auto-Submitted: auto-replied
+</literallayout>
+</section>
+<section id="SECID222">
+<title>The Bcc: header line</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Bcc:</emphasis> header line</primary>
+</indexterm>
+If Exim is called with the <option>-t</option> option, to take recipient addresses from a
+message’s header, it removes any <emphasis>Bcc:</emphasis> header line that may exist (after
+extracting its addresses). If <option>-t</option> is not present on the command line, any
+existing <emphasis>Bcc:</emphasis> is not removed.
+</para>
+</section>
+<section id="SECID223">
+<title>The Date: header line</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Date:</emphasis> header line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>Date:</secondary>
+</indexterm>
+If a locally-generated or submission-mode message has no <emphasis>Date:</emphasis> header line,
+Exim adds one, using the current date and time, unless the
+<option>suppress_local_fixups</option> control has been specified.
+</para>
+</section>
+<section id="SECID224">
+<title>The Delivery-date: header line</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Delivery-date:</emphasis> header line</primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>delivery_date_remove</option></primary>
+</indexterm>
+<emphasis>Delivery-date:</emphasis> header lines are not part of the standard RFC 2822 header
+set. Exim can be configured to add them to the final delivery of messages. (See
+the generic <option>delivery_date_add</option> transport option.) They should not be present
+in messages in transit. If the <option>delivery_date_remove</option> configuration option is
+set (the default), Exim removes <emphasis>Delivery-date:</emphasis> header lines from incoming
+messages.
+</para>
+</section>
+<section id="SECID225">
+<title>The Envelope-to: header line</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Envelope-to:</emphasis> header line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>Envelope-to:</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>envelope_to_remove</option></primary>
+</indexterm>
+<emphasis>Envelope-to:</emphasis> header lines are not part of the standard RFC 2822 header set.
+Exim can be configured to add them to the final delivery of messages. (See the
+generic <option>envelope_to_add</option> transport option.) They should not be present in
+messages in transit. If the <option>envelope_to_remove</option> configuration option is set
+(the default), Exim removes <emphasis>Envelope-to:</emphasis> header lines from incoming
+messages.
+</para>
+</section>
+<section id="SECTthefrohea">
+<title>The From: header line</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>From:</emphasis> header line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>From:</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Sendmail compatibility</primary>
+<secondary><quote>From</quote> line</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>submission</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>submission mode</primary>
+</indexterm>
+If a submission-mode message does not contain a <emphasis>From:</emphasis> header line, Exim
+adds one if either of the following conditions is true:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The envelope sender address is not empty (that is, this is not a bounce
+message). The added header line copies the envelope sender address.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$authenticated_id</varname></primary>
+</indexterm>
+The SMTP session is authenticated and <varname>$authenticated_id</varname> is not empty.
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$qualify_domain</varname></primary>
+</indexterm>
+If no domain is specified by the submission control, the local part is
+<varname>$authenticated_id</varname> and the domain is <varname>$qualify_domain</varname>.
+</para>
+</listitem>
+<listitem>
+<para>
+If a non-empty domain is specified by the submission control, the local
+part is <varname>$authenticated_id</varname>, and the domain is the specified domain.
+</para>
+</listitem>
+<listitem>
+<para>
+If an empty domain is specified by the submission control,
+<varname>$authenticated_id</varname> is assumed to be the complete address.
+</para>
+</listitem>
+</orderedlist>
+</listitem>
+</itemizedlist>
+<para>
+A non-empty envelope sender takes precedence.
+</para>
+<para>
+If a locally-generated incoming message does not contain a <emphasis>From:</emphasis> header
+line, and the <option>suppress_local_fixups</option> control is not set, Exim adds one
+containing the sender’s address. The calling user’s login name and full name
+are used to construct the address, as described in section <xref linkend="SECTconstr"/>.
+They are obtained from the password data by calling <function>getpwuid()</function> (but see the
+<option>unknown_login</option> configuration option). The address is qualified with
+<option>qualify_domain</option>.
+</para>
+<para>
+For compatibility with Sendmail, if an incoming, non-SMTP message has a
+<emphasis>From:</emphasis> header line containing just the unqualified login name of the calling
+user, this is replaced by an address containing the user’s login name and full
+name as described in section <xref linkend="SECTconstr"/>.
+</para>
+</section>
+<section id="SECID226">
+<title>The Message-ID: header line</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Message-ID:</emphasis> header line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>Message-ID:</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>submission</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>message_id_header_text</option></primary>
+</indexterm>
+If a locally-generated or submission-mode incoming message does not contain a
+<emphasis>Message-ID:</emphasis> or <emphasis>Resent-Message-ID:</emphasis> header line, and the
+<option>suppress_local_fixups</option> control is not set, Exim adds a suitable header line
+to the message. If there are any <emphasis>Resent-:</emphasis> headers in the message, it
+creates <emphasis>Resent-Message-ID:</emphasis>. The id is constructed from Exim’s internal
+message id, preceded by the letter E to ensure it starts with a letter, and
+followed by @ and the primary host name. Additional information can be included
+in this header line by setting the <option>message_id_header_text</option> and/or
+<option>message_id_header_domain</option> options.
+</para>
+</section>
+<section id="SECID227">
+<title>The Received: header line</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Received:</emphasis> header line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>Received:</secondary>
+</indexterm>
+A <emphasis>Received:</emphasis> header line is added at the start of every message. The
+contents are defined by the <option>received_header_text</option> configuration option, and
+Exim automatically adds a semicolon and a timestamp to the configured string.
+</para>
+<para>
+The <emphasis>Received:</emphasis> header is generated as soon as the message’s header lines
+have been received. At this stage, the timestamp in the <emphasis>Received:</emphasis> header
+line is the time that the message started to be received. This is the value
+that is seen by the DATA ACL and by the <function>local_scan()</function> function.
+</para>
+<para>
+Once a message is accepted, the timestamp in the <emphasis>Received:</emphasis> header line is
+changed to the time of acceptance, which is (apart from a small delay while the
+-H spool file is written) the earliest time at which delivery could start.
+</para>
+</section>
+<section id="SECID228">
+<title>The References: header line</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>References:</emphasis> header line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>References:</secondary>
+</indexterm>
+Messages created by the <command>autoreply</command> transport include a <emphasis>References:</emphasis>
+header line. This is constructed according to the rules that are described in
+section 3.64 of RFC 2822 (which states that replies should contain such a
+header line), and section 3.14 of RFC 3834 (which states that automatic
+responses are not different in this respect). However, because some mail
+processing software does not cope well with very long header lines, no more
+than 12 message IDs are copied from the <emphasis>References:</emphasis> header line in the
+incoming message. If there are more than 12, the first one and then the final
+11 are copied, before adding the message ID of the incoming message.
+</para>
+</section>
+<section id="SECID229">
+<title>The Return-path: header line</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Return-path:</emphasis> header line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>Return-path:</secondary>
+</indexterm>
+<indexterm role="option">
+<primary><option>return_path_remove</option></primary>
+</indexterm>
+<emphasis>Return-path:</emphasis> header lines are defined as something an MTA may insert when
+it does the final delivery of messages. (See the generic <option>return_path_add</option>
+transport option.) Therefore, they should not be present in messages in
+transit. If the <option>return_path_remove</option> configuration option is set (the
+default), Exim removes <emphasis>Return-path:</emphasis> header lines from incoming messages.
+</para>
+</section>
+<section id="SECTthesenhea">
+<title>The Sender: header line</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>Sender:</emphasis> header line</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>submission</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>Sender:</secondary>
+</indexterm>
+For a locally-originated message from an untrusted user, Exim may remove an
+existing <emphasis>Sender:</emphasis> header line, and it may add a new one. You can modify
+these actions by setting the <option>local_sender_retain</option> option true, the
+<option>local_from_check</option> option false, or by using the <option>suppress_local_fixups</option>
+control setting.
+</para>
+<para>
+When a local message is received from an untrusted user and
+<option>local_from_check</option> is true (the default), and the <option>suppress_local_fixups</option>
+control has not been set, a check is made to see if the address given in the
+<emphasis>From:</emphasis> header line is the correct (local) sender of the message. The address
+that is expected has the login name as the local part and the value of
+<option>qualify_domain</option> as the domain. Prefixes and suffixes for the local part can
+be permitted by setting <option>local_from_prefix</option> and <option>local_from_suffix</option>
+appropriately. If <emphasis>From:</emphasis> does not contain the correct sender, a <emphasis>Sender:</emphasis>
+line is added to the message.
+</para>
+<para>
+If you set <option>local_from_check</option> false, this checking does not occur. However,
+the removal of an existing <emphasis>Sender:</emphasis> line still happens, unless you also set
+<option>local_sender_retain</option> to be true. It is not possible to set both of these
+options true at the same time.
+</para>
+<para>
+<indexterm role="concept">
+<primary>submission mode</primary>
+</indexterm>
+By default, no processing of <emphasis>Sender:</emphasis> header lines is done for messages
+received over TCP/IP or for messages submitted by trusted users. However, when
+a message is received over TCP/IP in submission mode, and <option>sender_retain</option> is
+not specified on the submission control, the following processing takes place:
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$authenticated_id</varname></primary>
+</indexterm>
+First, any existing <emphasis>Sender:</emphasis> lines are removed. Then, if the SMTP session is
+authenticated, and <varname>$authenticated_id</varname> is not empty, a sender address is
+created as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$qualify_domain</varname></primary>
+</indexterm>
+If no domain is specified by the submission control, the local part is
+<varname>$authenticated_id</varname> and the domain is <varname>$qualify_domain</varname>.
+</para>
+</listitem>
+<listitem>
+<para>
+If a non-empty domain is specified by the submission control, the local part
+is <varname>$authenticated_id</varname>, and the domain is the specified domain.
+</para>
+</listitem>
+<listitem>
+<para>
+If an empty domain is specified by the submission control,
+<varname>$authenticated_id</varname> is assumed to be the complete address.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+This address is compared with the address in the <emphasis>From:</emphasis> header line. If they
+are different, a <emphasis>Sender:</emphasis> header line containing the created address is
+added. Prefixes and suffixes for the local part in <emphasis>From:</emphasis> can be permitted
+by setting <option>local_from_prefix</option> and <option>local_from_suffix</option> appropriately.
+</para>
+<para>
+<indexterm role="concept">
+<primary>return path</primary>
+<secondary>created from <emphasis>Sender:</emphasis></secondary>
+</indexterm>
+<emphasis role="bold">Note</emphasis>: Whenever a <emphasis>Sender:</emphasis> header line is created, the return path for
+the message (the envelope sender address) is changed to be the same address,
+except in the case of submission mode when <option>sender_retain</option> is specified.
+</para>
+</section>
+<section id="SECTheadersaddrem">
+<title>Adding and removing header lines in routers and transports</title>
+<para>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>adding; in router or transport</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>header lines</primary>
+<secondary>removing; in router or transport</secondary>
+</indexterm>
+When a message is delivered, the addition and removal of header lines can be
+specified in a system filter, or on any of the routers and transports that
+process the message. Section <xref linkend="SECTaddremheasys"/> contains details about
+modifying headers in a system filter. Header lines can also be added in an ACL
+as a message is received (see section <xref linkend="SECTaddheadacl"/>).
+</para>
+<para>
+In contrast to what happens in a system filter, header modifications that are
+specified on routers and transports apply only to the particular recipient
+addresses that are being processed by those routers and transports. These
+changes do not actually take place until a copy of the message is being
+transported. Therefore, they do not affect the basic set of header lines, and
+they do not affect the values of the variables that refer to header lines.
+</para>
+<para>
+<emphasis role="bold">Note</emphasis>: In particular, this means that any expansions in the configuration of
+the transport cannot refer to the modified header lines, because such
+expansions all occur before the message is actually transported.
+</para>
+<para>
+For both routers and transports, the argument of a <option>headers_add</option>
+option must be in the form of one or more RFC 2822 header lines, separated by
+newlines (coded as <quote>\n</quote>). For example:
+</para>
+<literallayout class="monospaced">
+headers_add = X-added-header: added by $primary_hostname\n\
+ X-added-second: another added header line
+</literallayout>
+<para>
+Exim does not check the syntax of these added header lines.
+</para>
+<para>
+Multiple <option>headers_add</option> options for a single router or transport can be
+specified; the values will append to a single list of header lines.
+Each header-line is separately expanded.
+</para>
+<para>
+The argument of a <option>headers_remove</option> option must consist of a colon-separated
+list of header names. This is confusing, because header names themselves are
+often terminated by colons. In this case, the colons are the list separators,
+not part of the names. For example:
+</para>
+<literallayout class="monospaced">
+headers_remove = return-receipt-to:acknowledge-to
+</literallayout>
+<para>
+Multiple <option>headers_remove</option> options for a single router or transport can be
+specified; the arguments will append to a single header-names list.
+Each item is separately expanded.
+Note that colons in complex expansions which are used to
+form all or part of a <option>headers_remove</option> list
+will act as list separators.
+</para>
+<para>
+When <option>headers_add</option> or <option>headers_remove</option> is specified on a router,
+items are expanded at routing time,
+and then associated with all addresses that are
+accepted by that router, and also with any new addresses that it generates. If
+an address passes through several routers as a result of aliasing or
+forwarding, the changes are cumulative.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>unseen</option></primary>
+</indexterm>
+However, this does not apply to multiple routers that result from the use of
+the <option>unseen</option> option. Any header modifications that were specified by the
+<quote>unseen</quote> router or its predecessors apply only to the <quote>unseen</quote> delivery.
+</para>
+<para>
+Addresses that end up with different <option>headers_add</option> or <option>headers_remove</option>
+settings cannot be delivered together in a batch, so a transport is always
+dealing with a set of addresses that have the same header-processing
+requirements.
+</para>
+<para>
+The transport starts by writing the original set of header lines that arrived
+with the message, possibly modified by the system filter. As it writes out
+these lines, it consults the list of header names that were attached to the
+recipient address(es) by <option>headers_remove</option> options in routers, and it also
+consults the transport’s own <option>headers_remove</option> option. Header lines whose
+names are on either of these lists are not written out. If there are multiple
+instances of any listed header, they are all skipped.
+</para>
+<para>
+After the remaining original header lines have been written, new header
+lines that were specified by routers’ <option>headers_add</option> options are written, in
+the order in which they were attached to the address. These are followed by any
+header lines specified by the transport’s <option>headers_add</option> option.
+</para>
+<para>
+This way of handling header line modifications in routers and transports has
+the following consequences:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The original set of header lines, possibly modified by the system filter,
+remains <quote>visible</quote>, in the sense that the <varname>$header_</varname><emphasis>xxx</emphasis> variables refer
+to it, at all times.
+</para>
+</listitem>
+<listitem>
+<para>
+Header lines that are added by a router’s
+<option>headers_add</option> option are not accessible by means of the <varname>$header_</varname><emphasis>xxx</emphasis>
+expansion syntax in subsequent routers or the transport.
+</para>
+</listitem>
+<listitem>
+<para>
+Conversely, header lines that are specified for removal by <option>headers_remove</option>
+in a router remain visible to subsequent routers and the transport.
+</para>
+</listitem>
+<listitem>
+<para>
+Headers added to an address by <option>headers_add</option> in a router cannot be removed by
+a later router or by a transport.
+</para>
+</listitem>
+<listitem>
+<para>
+An added header can refer to the contents of an original header that is to be
+removed, even it has the same name as the added header. For example:
+</para>
+<literallayout class="monospaced">
+headers_remove = subject
+headers_add = Subject: new subject (was: $h_subject:)
+</literallayout>
+</listitem>
+</itemizedlist>
+<para>
+<emphasis role="bold">Warning</emphasis>: The <option>headers_add</option> and <option>headers_remove</option> options cannot be used
+for a <command>redirect</command> router that has the <option>one_time</option> option set.
+</para>
+</section>
+<section id="SECTconstr">
+<title>Constructed addresses</title>
+<para>
+<indexterm role="concept">
+<primary>address</primary>
+<secondary>constructed</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>constructed address</primary>
+</indexterm>
+When Exim constructs a sender address for a locally-generated message, it uses
+the form
+</para>
+<literallayout>
+<<emphasis>user name</emphasis>> <<emphasis>login</emphasis><literal>@</literal><emphasis>qualify_domain</emphasis>>
+</literallayout>
+<para>
+For example:
+</para>
+<literallayout class="monospaced">
+Zaphod Beeblebrox <zaphod@end.univ.example>
+</literallayout>
+<para>
+The user name is obtained from the <option>-F</option> command line option if set, or
+otherwise by looking up the calling user by <function>getpwuid()</function> and extracting the
+<quote>gecos</quote> field from the password entry. If the <quote>gecos</quote> field contains an
+ampersand character, this is replaced by the login name with the first letter
+upper cased, as is conventional in a number of operating systems. See the
+<option>gecos_name</option> option for a way to tailor the handling of the <quote>gecos</quote> field.
+The <option>unknown_username</option> option can be used to specify user names in cases when
+there is no password file entry.
+</para>
+<para>
+<indexterm role="concept">
+<primary>RFC 2047</primary>
+</indexterm>
+In all cases, the user name is made to conform to RFC 2822 by quoting all or
+parts of it if necessary. In addition, if it contains any non-printing
+characters, it is encoded as described in RFC 2047, which defines a way of
+including non-ASCII characters in header lines. The value of the
+<option>headers_charset</option> option specifies the name of the encoding that is used (the
+characters are assumed to be in this encoding). The setting of
+<option>print_topbitchars</option> controls whether characters with the top bit set (that
+is, with codes greater than 127) count as printing characters or not.
+</para>
+</section>
+<section id="SECID230">
+<title>Case of local parts</title>
+<para>
+<indexterm role="concept">
+<primary>case of local parts</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>case of</secondary>
+</indexterm>
+RFC 2822 states that the case of letters in the local parts of addresses cannot
+be assumed to be non-significant. Exim preserves the case of local parts of
+addresses, but by default it uses a lower-cased form when it is routing,
+because on most Unix systems, usernames are in lower case and case-insensitive
+routing is required. However, any particular router can be made to use the
+original case for local parts by setting the <option>caseful_local_part</option> generic
+router option.
+</para>
+<para>
+<indexterm role="concept">
+<primary>mixed-case login names</primary>
+</indexterm>
+If you must have mixed-case user names on your system, the best way to proceed,
+assuming you want case-independent handling of incoming email, is to set up
+your first router to convert incoming local parts in your domains to the
+correct case by means of a file lookup. For example:
+</para>
+<literallayout class="monospaced">
+correct_case:
+ driver = redirect
+ domains = +local_domains
+ data = ${lookup{$local_part}cdb\
+ {/etc/usercased.cdb}{$value}fail}\
+ @$domain
+</literallayout>
+<para>
+For this router, the local part is forced to lower case by the default action
+(<option>caseful_local_part</option> is not set). The lower-cased local part is used to look
+up a new local part in the correct case. If you then set <option>caseful_local_part</option>
+on any subsequent routers which process your domains, they will operate on
+local parts with the correct case in a case-sensitive manner.
+</para>
+</section>
+<section id="SECID231">
+<title>Dots in local parts</title>
+<para>
+<indexterm role="concept">
+<primary>dot</primary>
+<secondary>in local part</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>dots in</secondary>
+</indexterm>
+RFC 2822 forbids empty components in local parts. That is, an unquoted local
+part may not begin or end with a dot, nor have two consecutive dots in the
+middle. However, it seems that many MTAs do not enforce this, so Exim permits
+empty components for compatibility.
+</para>
+</section>
+<section id="SECID232">
+<title>Rewriting addresses</title>
+<para>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>addresses</secondary>
+</indexterm>
+Rewriting of sender and recipient addresses, and addresses in headers, can
+happen automatically, or as the result of configuration options, as described
+in chapter <xref linkend="CHAPrewrite"/>. The headers that may be affected by this are
+<emphasis>Bcc:</emphasis>, <emphasis>Cc:</emphasis>, <emphasis>From:</emphasis>, <emphasis>Reply-To:</emphasis>, <emphasis>Sender:</emphasis>, and <emphasis>To:</emphasis>.
+</para>
+<para>
+Automatic rewriting includes qualification, as mentioned above. The other case
+in which it can happen is when an incomplete non-local domain is given. The
+routing process may cause this to be expanded into the full domain name. For
+example, a header such as
+</para>
+<literallayout class="monospaced">
+To: hare@teaparty
+</literallayout>
+<para>
+might get rewritten as
+</para>
+<literallayout class="monospaced">
+To: hare@teaparty.wonderland.fict.example
+</literallayout>
+<para>
+Rewriting as a result of routing is the one kind of message processing that
+does not happen at input time, as it cannot be done until the address has
+been routed.
+</para>
+<para>
+Strictly, one should not do <emphasis>any</emphasis> deliveries of a message until all its
+addresses have been routed, in case any of the headers get changed as a
+result of routing. However, doing this in practice would hold up many
+deliveries for unreasonable amounts of time, just because one address could not
+immediately be routed. Exim therefore does not delay other deliveries when
+routing of one or more addresses is deferred.
+<indexterm role="concept" startref="IIDmesproc" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPSMTP">
+<title>SMTP processing</title>
+<para>
+<indexterm role="concept" id="IIDsmtpproc1" class="startofrange">
+<primary>SMTP</primary>
+<secondary>processing details</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDsmtpproc2" class="startofrange">
+<primary>LMTP</primary>
+<secondary>processing details</secondary>
+</indexterm>
+Exim supports a number of different ways of using the SMTP protocol, and its
+LMTP variant, which is an interactive protocol for transferring messages into a
+closed mail store application. This chapter contains details of how SMTP is
+processed. For incoming mail, the following are available:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+SMTP over TCP/IP (Exim daemon or <emphasis>inetd</emphasis>);
+</para>
+</listitem>
+<listitem>
+<para>
+SMTP over the standard input and output (the <option>-bs</option> option);
+</para>
+</listitem>
+<listitem>
+<para>
+Batched SMTP on the standard input (the <option>-bS</option> option).
+</para>
+</listitem>
+</itemizedlist>
+<para>
+For mail delivery, the following are available:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+SMTP over TCP/IP (the <command>smtp</command> transport);
+</para>
+</listitem>
+<listitem>
+<para>
+LMTP over TCP/IP (the <command>smtp</command> transport with the <option>protocol</option> option set to
+<quote>lmtp</quote>);
+</para>
+</listitem>
+<listitem>
+<para>
+LMTP over a pipe to a process running in the local host (the <command>lmtp</command>
+transport);
+</para>
+</listitem>
+<listitem>
+<para>
+Batched SMTP to a file or pipe (the <command>appendfile</command> and <command>pipe</command> transports with
+the <option>use_bsmtp</option> option set).
+</para>
+</listitem>
+</itemizedlist>
+<para>
+<emphasis>Batched SMTP</emphasis> is the name for a process in which batches of messages are
+stored in or read from files (or pipes), in a format in which SMTP commands are
+used to contain the envelope information.
+</para>
+<section id="SECToutSMTPTCP">
+<title>Outgoing SMTP and LMTP over TCP/IP</title>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>outgoing over TCP/IP</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>outgoing SMTP over TCP/IP</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>LMTP</primary>
+<secondary>over TCP/IP</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>outgoing LMTP over TCP/IP</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>EHLO</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>HELO</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SIZE</primary>
+<secondary>option on MAIL command</secondary>
+</indexterm>
+Outgoing SMTP and LMTP over TCP/IP is implemented by the <command>smtp</command> transport.
+The <option>protocol</option> option selects which protocol is to be used, but the actual
+processing is the same in both cases.
+</para>
+<para>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>SIZE</secondary>
+</indexterm>
+If, in response to its EHLO command, Exim is told that the SIZE
+extension is supported, it adds SIZE=<<emphasis>n</emphasis>> to each subsequent MAIL
+command. The value of <<emphasis>n</emphasis>> is the message size plus the value of the
+<option>size_addition</option> option (default 1024) to allow for additions to the message
+such as per-transport header lines, or changes made in a
+<indexterm role="concept">
+<primary>transport</primary>
+<secondary>filter</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>filter</primary>
+<secondary>transport filter</secondary>
+</indexterm>
+transport filter. If <option>size_addition</option> is set negative, the use of SIZE is
+suppressed.
+</para>
+<para>
+If the remote server advertises support for PIPELINING, Exim uses the
+pipelining extension to SMTP (RFC 2197) to reduce the number of TCP/IP packets
+required for the transaction.
+</para>
+<para>
+If the remote server advertises support for the STARTTLS command, and Exim
+was built to support TLS encryption, it tries to start a TLS session unless the
+server matches <option>hosts_avoid_tls</option>. See chapter <xref linkend="CHAPTLS"/> for more details.
+Either a match in that or <option>hosts_verify_avoid_tls</option> apply when the transport
+is called for verification.
+</para>
+<para>
+If the remote server advertises support for the AUTH command, Exim scans
+the authenticators configuration for any suitable client settings, as described
+in chapter <xref linkend="CHAPSMTPAUTH"/>.
+</para>
+<para>
+<indexterm role="concept">
+<primary>carriage return</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>linefeed</primary>
+</indexterm>
+Responses from the remote host are supposed to be terminated by CR followed by
+LF. However, there are known to be hosts that do not send CR characters, so in
+order to be able to interwork with such hosts, Exim treats LF on its own as a
+line terminator.
+</para>
+<para>
+If a message contains a number of different addresses, all those with the same
+characteristics (for example, the same envelope sender) that resolve to the
+same set of hosts, in the same order, are sent in a single SMTP transaction,
+even if they are for different domains, unless there are more than the setting
+of the <option>max_rcpt</option>s option in the <command>smtp</command> transport allows, in which case
+they are split into groups containing no more than <option>max_rcpt</option>s addresses
+each. If <option>remote_max_parallel</option> is greater than one, such groups may be sent
+in parallel sessions. The order of hosts with identical MX values is not
+significant when checking whether addresses can be batched in this way.
+</para>
+<para>
+When the <command>smtp</command> transport suffers a temporary failure that is not
+message-related, Exim updates its transport-specific database, which contains
+records indexed by host name that remember which messages are waiting for each
+particular host. It also updates the retry database with new retry times.
+</para>
+<para>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>retry keys</secondary>
+</indexterm>
+Exim’s retry hints are based on host name plus IP address, so if one address of
+a multi-homed host is broken, it will soon be skipped most of the time.
+See the next section for more detail about error handling.
+</para>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>passed connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>batching over TCP/IP</secondary>
+</indexterm>
+When a message is successfully delivered over a TCP/IP SMTP connection, Exim
+looks in the hints database for the transport to see if there are any queued
+messages waiting for the host to which it is connected. If it finds one, it
+creates a new Exim process using the <option>-MC</option> option (which can only be used by
+a process running as root or the Exim user) and passes the TCP/IP socket to it
+so that it can deliver another message using the same socket. The new process
+does only those deliveries that are routed to the connected host, and may in
+turn pass the socket on to a third process, and so on.
+</para>
+<para>
+The <option>connection_max_messages</option> option of the <command>smtp</command> transport can be used to
+limit the number of messages sent down a single TCP/IP connection.
+</para>
+<para>
+<indexterm role="concept">
+<primary>asterisk</primary>
+<secondary>after IP address</secondary>
+</indexterm>
+The second and subsequent messages delivered down an existing connection are
+identified in the main log by the addition of an asterisk after the closing
+square bracket of the IP address.
+</para>
+</section>
+<section id="SECToutSMTPerr">
+<title>Errors in outgoing SMTP</title>
+<para>
+<indexterm role="concept">
+<primary>error</primary>
+<secondary>in outgoing SMTP</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>errors in outgoing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>host</primary>
+<secondary>error</secondary>
+</indexterm>
+Three different kinds of error are recognized for outgoing SMTP: host errors,
+message errors, and recipient errors.
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">Host errors</emphasis></term>
+<listitem>
+<para>
+A host error is not associated with a particular message or with a
+particular recipient of a message. The host errors are:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Connection refused or timed out,
+</para>
+</listitem>
+<listitem>
+<para>
+Any error response code on connection,
+</para>
+</listitem>
+<listitem>
+<para>
+Any error response code to EHLO or HELO,
+</para>
+</listitem>
+<listitem>
+<para>
+Loss of connection at any time, except after <quote>.</quote>,
+</para>
+</listitem>
+<listitem>
+<para>
+I/O errors at any time,
+</para>
+</listitem>
+<listitem>
+<para>
+Timeouts during the session, other than in response to MAIL, RCPT or
+the <quote>.</quote> at the end of the data.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+For a host error, a permanent error response on connection, or in response to
+EHLO, causes all addresses routed to the host to be failed. Any other host
+error causes all addresses to be deferred, and retry data to be created for the
+host. It is not tried again, for any message, until its retry time arrives. If
+the current set of addresses are not all delivered in this run (to some
+alternative host), the message is added to the list of those waiting for this
+host, so if it is still undelivered when a subsequent successful delivery is
+made to the host, it will be sent down the same SMTP connection.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">Message errors</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>error</secondary>
+</indexterm>
+A message error is associated with a particular message when sent to a
+particular host, but not with a particular recipient of the message. The
+message errors are:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Any error response code to MAIL, DATA, or the <quote>.</quote> that terminates
+the data,
+</para>
+</listitem>
+<listitem>
+<para>
+Timeout after MAIL,
+</para>
+</listitem>
+<listitem>
+<para>
+Timeout or loss of connection after the <quote>.</quote> that terminates the data. A
+timeout after the DATA command itself is treated as a host error, as is loss of
+connection at any other time.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+For a message error, a permanent error response (5<emphasis>xx</emphasis>) causes all addresses
+to be failed, and a delivery error report to be returned to the sender. A
+temporary error response (4<emphasis>xx</emphasis>), or one of the timeouts, causes all
+addresses to be deferred. Retry data is not created for the host, but instead,
+a retry record for the combination of host plus message id is created. The
+message is not added to the list of those waiting for this host. This ensures
+that the failing message will not be sent to this host again until the retry
+time arrives. However, other messages that are routed to the host are not
+affected, so if it is some property of the message that is causing the error,
+it will not stop the delivery of other mail.
+</para>
+<para>
+If the remote host specified support for the SIZE parameter in its response
+to EHLO, Exim adds SIZE=<emphasis>nnn</emphasis> to the MAIL command, so an
+over-large message will cause a message error because the error arrives as a
+response to MAIL.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">Recipient errors</emphasis></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>recipient</primary>
+<secondary>error</secondary>
+</indexterm>
+A recipient error is associated with a particular recipient of a message. The
+recipient errors are:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Any error response to RCPT,
+</para>
+</listitem>
+<listitem>
+<para>
+Timeout after RCPT.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+For a recipient error, a permanent error response (5<emphasis>xx</emphasis>) causes the
+recipient address to be failed, and a bounce message to be returned to the
+sender. A temporary error response (4<emphasis>xx</emphasis>) or a timeout causes the failing
+address to be deferred, and routing retry data to be created for it. This is
+used to delay processing of the address in subsequent queue runs, until its
+routing retry time arrives. This applies to all messages, but because it
+operates only in queue runs, one attempt will be made to deliver a new message
+to the failing address before the delay starts to operate. This ensures that,
+if the failure is really related to the message rather than the recipient
+(<quote>message too big for this recipient</quote> is a possible example), other messages
+have a chance of getting delivered. If a delivery to the address does succeed,
+the retry information gets cleared, so all stuck messages get tried again, and
+the retry clock is reset.
+</para>
+<para>
+The message is not added to the list of those waiting for this host. Use of the
+host for other messages is unaffected, and except in the case of a timeout,
+other recipients are processed independently, and may be successfully delivered
+in the current SMTP session. After a timeout it is of course impossible to
+proceed with the session, so all addresses get deferred. However, those other
+than the one that failed do not suffer any subsequent retry delays. Therefore,
+if one recipient is causing trouble, the others have a chance of getting
+through when a subsequent delivery attempt occurs before the failing
+recipient’s retry time.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+In all cases, if there are other hosts (or IP addresses) available for the
+current set of addresses (for example, from multiple MX records), they are
+tried in this run for any undelivered addresses, subject of course to their
+own retry data. In other words, recipient error retry data does not take effect
+until the next delivery attempt.
+</para>
+<para>
+Some hosts have been observed to give temporary error responses to every
+MAIL command at certain times (<quote>insufficient space</quote> has been seen). It
+would be nice if such circumstances could be recognized, and defer data for the
+host itself created, but this is not possible within the current Exim design.
+What actually happens is that retry data for every (host, message) combination
+is created.
+</para>
+<para>
+The reason that timeouts after MAIL and RCPT are treated specially is that
+these can sometimes arise as a result of the remote host’s verification
+procedures. Exim makes this assumption, and treats them as if a temporary error
+response had been received. A timeout after <quote>.</quote> is treated specially because
+it is known that some broken implementations fail to recognize the end of the
+message if the last character of the last line is a binary zero. Thus, it is
+helpful to treat this case as a message error.
+</para>
+<para>
+Timeouts at other times are treated as host errors, assuming a problem with the
+host, or the connection to it. If a timeout after MAIL, RCPT,
+or <quote>.</quote> is really a connection problem, the assumption is that at the next try
+the timeout is likely to occur at some other point in the dialogue, causing it
+then to be treated as a host error.
+</para>
+<para>
+There is experimental evidence that some MTAs drop the connection after the
+terminating <quote>.</quote> if they do not like the contents of the message for some
+reason, in contravention of the RFC, which indicates that a 5<emphasis>xx</emphasis> response
+should be given. That is why Exim treats this case as a message rather than a
+host error, in order not to delay other messages to the same host.
+</para>
+</section>
+<section id="SECID233">
+<title>Incoming SMTP messages over TCP/IP</title>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>incoming over TCP/IP</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>incoming SMTP over TCP/IP</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>inetd</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>daemon</primary>
+</indexterm>
+Incoming SMTP messages can be accepted in one of two ways: by running a
+listening daemon, or by using <emphasis>inetd</emphasis>. In the latter case, the entry in
+<filename>/etc/inetd.conf</filename> should be like this:
+</para>
+<literallayout class="monospaced">
+smtp stream tcp nowait exim /opt/exim/bin/exim in.exim -bs
+</literallayout>
+<para>
+Exim distinguishes between this case and the case of a locally running user
+agent using the <option>-bs</option> option by checking whether or not the standard input is
+a socket. When it is, either the port must be privileged (less than 1024), or
+the caller must be root or the Exim user. If any other user passes a socket
+with an unprivileged port number, Exim prints a message on the standard error
+stream and exits with an error code.
+</para>
+<para>
+By default, Exim does not make a log entry when a remote host connects or
+disconnects (either via the daemon or <emphasis>inetd</emphasis>), unless the disconnection is
+unexpected. It can be made to write such log entries by setting the
+<option>smtp_connection</option> log selector.
+</para>
+<para>
+<indexterm role="concept">
+<primary>carriage return</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>linefeed</primary>
+</indexterm>
+Commands from the remote host are supposed to be terminated by CR followed by
+LF. However, there are known to be hosts that do not send CR characters. In
+order to be able to interwork with such hosts, Exim treats LF on its own as a
+line terminator.
+Furthermore, because common code is used for receiving messages from all
+sources, a CR on its own is also interpreted as a line terminator. However, the
+sequence <quote>CR, dot, CR</quote> does not terminate incoming SMTP data.
+</para>
+<para>
+<indexterm role="concept">
+<primary>EHLO</primary>
+<secondary>invalid data</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>HELO</primary>
+<secondary>invalid data</secondary>
+</indexterm>
+One area that sometimes gives rise to problems concerns the EHLO or
+HELO commands. Some clients send syntactically invalid versions of these
+commands, which Exim rejects by default. (This is nothing to do with verifying
+the data that is sent, so <option>helo_verify_hosts</option> is not relevant.) You can tell
+Exim not to apply a syntax check by setting <option>helo_accept_junk_hosts</option> to
+match the broken hosts that send invalid commands.
+</para>
+<para>
+<indexterm role="concept">
+<primary>SIZE option on MAIL command</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>MAIL</primary>
+<secondary>SIZE option</secondary>
+</indexterm>
+The amount of disk space available is checked whenever SIZE is received on
+a MAIL command, independently of whether <option>message_size_limit</option> or
+<option>check_spool_space</option> is configured, unless <option>smtp_check_spool_space</option> is set
+false. A temporary error is given if there is not enough space. If
+<option>check_spool_space</option> is set, the check is for that amount of space plus the
+value given with SIZE, that is, it checks that the addition of the incoming
+message will not reduce the space below the threshold.
+</para>
+<para>
+When a message is successfully received, Exim includes the local message id in
+its response to the final <quote>.</quote> that terminates the data. If the remote host
+logs this text it can help with tracing what has happened to a message.
+</para>
+<para>
+The Exim daemon can limit the number of simultaneous incoming connections it is
+prepared to handle (see the <option>smtp_accept_max</option> option). It can also limit the
+number of simultaneous incoming connections from a single remote host (see the
+<option>smtp_accept_max_per_host</option> option). Additional connection attempts are
+rejected using the SMTP temporary error code 421.
+</para>
+<para>
+The Exim daemon does not rely on the SIGCHLD signal to detect when a
+subprocess has finished, as this can get lost at busy times. Instead, it looks
+for completed subprocesses every time it wakes up. Provided there are other
+things happening (new incoming calls, starts of queue runs), completed
+processes will be noticed and tidied away. On very quiet systems you may
+sometimes see a <quote>defunct</quote> Exim process hanging about. This is not a problem;
+it will be noticed when the daemon next wakes up.
+</para>
+<para>
+When running as a daemon, Exim can reserve some SMTP slots for specific hosts,
+and can also be set up to reject SMTP calls from non-reserved hosts at times of
+high system load – for details see the <option>smtp_accept_reserve</option>,
+<option>smtp_load_reserve</option>, and <option>smtp_reserve_hosts</option> options. The load check
+applies in both the daemon and <emphasis>inetd</emphasis> cases.
+</para>
+<para>
+Exim normally starts a delivery process for each message received, though this
+can be varied by means of the <option>-odq</option> command line option and the
+<option>queue_only</option>, <option>queue_only_file</option>, and <option>queue_only_load</option> options. The
+number of simultaneously running delivery processes started in this way from
+SMTP input can be limited by the <option>smtp_accept_queue</option> and
+<option>smtp_accept_queue_per_connection</option> options. When either limit is reached,
+subsequently received messages are just put on the input queue without starting
+a delivery process.
+</para>
+<para>
+The controls that involve counts of incoming SMTP calls (<option>smtp_accept_max</option>,
+<option>smtp_accept_queue</option>, <option>smtp_accept_reserve</option>) are not available when Exim is
+started up from the <emphasis>inetd</emphasis> daemon, because in that case each connection is
+handled by an entirely independent Exim process. Control by load average is,
+however, available with <emphasis>inetd</emphasis>.
+</para>
+<para>
+Exim can be configured to verify addresses in incoming SMTP commands as they
+are received. See chapter <xref linkend="CHAPACL"/> for details. It can also be configured
+to rewrite addresses at this time – before any syntax checking is done. See
+section <xref linkend="SECTrewriteS"/>.
+</para>
+<para>
+Exim can also be configured to limit the rate at which a client host submits
+MAIL and RCPT commands in a single SMTP session. See the
+<option>smtp_ratelimit_hosts</option> option.
+</para>
+</section>
+<section id="SECID234">
+<title>Unrecognized SMTP commands</title>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>unrecognized commands</secondary>
+</indexterm>
+If Exim receives more than <option>smtp_max_unknown_commands</option> unrecognized SMTP
+commands during a single SMTP connection, it drops the connection after sending
+the error response to the last command. The default value for
+<option>smtp_max_unknown_commands</option> is 3. This is a defence against some kinds of
+abuse that subvert web servers into making connections to SMTP ports; in these
+circumstances, a number of non-SMTP lines are sent first.
+</para>
+</section>
+<section id="SECID235">
+<title>Syntax and protocol errors in SMTP commands</title>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>syntax errors</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>protocol errors</secondary>
+</indexterm>
+A syntax error is detected if an SMTP command is recognized, but there is
+something syntactically wrong with its data, for example, a malformed email
+address in a RCPT command. Protocol errors include invalid command
+sequencing such as RCPT before MAIL. If Exim receives more than
+<option>smtp_max_synprot_errors</option> such commands during a single SMTP connection, it
+drops the connection after sending the error response to the last command. The
+default value for <option>smtp_max_synprot_errors</option> is 3. This is a defence against
+broken clients that loop sending bad commands (yes, it has been seen).
+</para>
+</section>
+<section id="SECID236">
+<title>Use of non-mail SMTP commands</title>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>non-mail commands</secondary>
+</indexterm>
+The <quote>non-mail</quote> SMTP commands are those other than MAIL, RCPT, and
+DATA. Exim counts such commands, and drops the connection if there are too
+many of them in a single SMTP session. This action catches some
+denial-of-service attempts and things like repeated failing AUTHs, or a mad
+client looping sending EHLO. The global option <option>smtp_accept_max_nonmail</option>
+defines what <quote>too many</quote> means. Its default value is 10.
+</para>
+<para>
+When a new message is expected, one occurrence of RSET is not counted. This
+allows a client to send one RSET between messages (this is not necessary,
+but some clients do it). Exim also allows one uncounted occurrence of HELO
+or EHLO, and one occurrence of STARTTLS between messages. After
+starting up a TLS session, another EHLO is expected, and so it too is not
+counted.
+</para>
+<para>
+The first occurrence of AUTH in a connection, or immediately following
+STARTTLS is also not counted. Otherwise, all commands other than MAIL,
+RCPT, DATA, and QUIT are counted.
+</para>
+<para>
+You can control which hosts are subject to the limit set by
+<option>smtp_accept_max_nonmail</option> by setting
+<option>smtp_accept_max_nonmail_hosts</option>. The default value is <literal>*</literal>, which makes
+the limit apply to all hosts. This option means that you can exclude any
+specific badly-behaved hosts that you have to live with.
+</para>
+</section>
+<section id="SECID237">
+<title>The VRFY and EXPN commands</title>
+<para>
+When Exim receives a VRFY or EXPN command on a TCP/IP connection, it
+runs the ACL specified by <option>acl_smtp_vrfy</option> or <option>acl_smtp_expn</option> (as
+appropriate) in order to decide whether the command should be accepted or not.
+</para>
+<para>
+<indexterm role="concept">
+<primary>VRFY</primary>
+<secondary>processing</secondary>
+</indexterm>
+When no ACL is defined for VRFY, or if it rejects without
+setting an explicit response code, the command is accepted
+(with a 252 SMTP response code)
+in order to support awkward clients that do a VRFY before every RCPT.
+When VRFY is accepted, it runs exactly the same code as when Exim is
+called with the <option>-bv</option> option, and returns 250/451/550
+SMTP response codes.
+</para>
+<para>
+<indexterm role="concept">
+<primary>EXPN</primary>
+<secondary>processing</secondary>
+</indexterm>
+If no ACL for EXPN is defined, the command is rejected.
+When EXPN is accepted, a single-level expansion of the address is done.
+EXPN is treated as an <quote>address test</quote> (similar to the <option>-bt</option> option) rather
+than a verification (the <option>-bv</option> option). If an unqualified local part is given
+as the argument to EXPN, it is qualified with <option>qualify_domain</option>. Rejections
+of VRFY and EXPN commands are logged on the main and reject logs, and
+VRFY verification failures are logged on the main log for consistency with
+RCPT failures.
+</para>
+</section>
+<section id="SECTETRN">
+<title>The ETRN command</title>
+<para>
+<indexterm role="concept">
+<primary>ETRN</primary>
+<secondary>processing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>ETRN</secondary>
+</indexterm>
+RFC 1985 describes an ESMTP command called ETRN that is designed to
+overcome the security problems of the TURN command (which has fallen into
+disuse). When Exim receives an ETRN command on a TCP/IP connection, it runs
+the ACL specified by <option>acl_smtp_etrn</option> in order to decide whether the command
+should be accepted or not. If no ACL is defined, the command is rejected.
+</para>
+<para>
+The ETRN command is concerned with <quote>releasing</quote> messages that are awaiting
+delivery to certain hosts. As Exim does not organize its message queue by host,
+the only form of ETRN that is supported by default is the one where the
+text starts with the <quote>#</quote> prefix, in which case the remainder of the text is
+specific to the SMTP server. A valid ETRN command causes a run of Exim with
+the <option>-R</option> option to happen, with the remainder of the ETRN text as its
+argument. For example,
+</para>
+<literallayout class="monospaced">
+ETRN #brigadoon
+</literallayout>
+<para>
+runs the command
+</para>
+<literallayout class="monospaced">
+exim -R brigadoon
+</literallayout>
+<para>
+which causes a delivery attempt on all messages with undelivered addresses
+containing the text <quote>brigadoon</quote>. When <option>smtp_etrn_serialize</option> is set (the
+default), Exim prevents the simultaneous execution of more than one queue run
+for the same argument string as a result of an ETRN command. This stops
+a misbehaving client from starting more than one queue runner at once.
+</para>
+<para>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>ETRN serialization</secondary>
+</indexterm>
+Exim implements the serialization by means of a hints database in which a
+record is written whenever a process is started by ETRN, and deleted when
+the process completes. However, Exim does not keep the SMTP session waiting for
+the ETRN process to complete. Once ETRN is accepted, the client is sent
+a <quote>success</quote> return code. Obviously there is scope for hints records to get
+left lying around if there is a system or program crash. To guard against this,
+Exim ignores any records that are more than six hours old.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>smtp_etrn_command</option></primary>
+</indexterm>
+For more control over what ETRN does, the <option>smtp_etrn_command</option> option can
+used. This specifies a command that is run whenever ETRN is received,
+whatever the form of its argument. For
+example:
+</para>
+<literallayout class="monospaced">
+smtp_etrn_command = /etc/etrn_command $domain \
+ $sender_host_address
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$domain</varname></primary>
+</indexterm>
+The string is split up into arguments which are independently expanded. The
+expansion variable <varname>$domain</varname> is set to the argument of the ETRN command,
+and no syntax checking is done on the contents of this argument. Exim does not
+wait for the command to complete, so its status code is not checked. Exim runs
+under its own uid and gid when receiving incoming SMTP, so it is not possible
+for it to change them before running the command.
+</para>
+</section>
+<section id="SECID238">
+<title>Incoming local SMTP</title>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>local incoming</secondary>
+</indexterm>
+Some user agents use SMTP to pass messages to their local MTA using the
+standard input and output, as opposed to passing the envelope on the command
+line and writing the message to the standard input. This is supported by the
+<option>-bs</option> option. This form of SMTP is handled in the same way as incoming
+messages over TCP/IP (including the use of ACLs), except that the envelope
+sender given in a MAIL command is ignored unless the caller is trusted. In
+an ACL you can detect this form of SMTP input by testing for an empty host
+identification. It is common to have this as the first line in the ACL that
+runs for RCPT commands:
+</para>
+<literallayout class="monospaced">
+accept hosts = :
+</literallayout>
+<para>
+This accepts SMTP messages from local processes without doing any other tests.
+</para>
+</section>
+<section id="SECTbatchSMTP">
+<title>Outgoing batched SMTP</title>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>batched outgoing</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>batched SMTP output</primary>
+</indexterm>
+Both the <command>appendfile</command> and <command>pipe</command> transports can be used for handling
+batched SMTP. Each has an option called <option>use_bsmtp</option> which causes messages to
+be output in BSMTP format. No SMTP responses are possible for this form of
+delivery. All it is doing is using SMTP commands as a way of transmitting the
+envelope along with the message.
+</para>
+<para>
+The message is written to the file or pipe preceded by the SMTP commands
+MAIL and RCPT, and followed by a line containing a single dot. Lines in
+the message that start with a dot have an extra dot added. The SMTP command
+HELO is not normally used. If it is required, the <option>message_prefix</option> option
+can be used to specify it.
+</para>
+<para>
+Because <command>appendfile</command> and <command>pipe</command> are both local transports, they accept only
+one recipient address at a time by default. However, you can arrange for them
+to handle several addresses at once by setting the <option>batch_max</option> option. When
+this is done for BSMTP, messages may contain multiple RCPT commands. See
+chapter <xref linkend="CHAPbatching"/> for more details.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$host</varname></primary>
+</indexterm>
+When one or more addresses are routed to a BSMTP transport by a router that
+sets up a host list, the name of the first host on the list is available to the
+transport in the variable <varname>$host</varname>. Here is an example of such a transport and
+router:
+</para>
+<literallayout class="monospaced">
+begin routers
+route_append:
+ driver = manualroute
+ transport = smtp_appendfile
+ route_list = domain.example batch.host.example
+
+begin transports
+smtp_appendfile:
+ driver = appendfile
+ directory = /var/bsmtp/$host
+ batch_max = 1000
+ use_bsmtp
+ user = exim
+</literallayout>
+<para>
+This causes messages addressed to <emphasis>domain.example</emphasis> to be written in BSMTP
+format to <filename>/var/bsmtp/batch.host.example</filename>, with only a single copy of each
+message (unless there are more than 1000 recipients).
+</para>
+</section>
+<section id="SECTincomingbatchedSMTP">
+<title>Incoming batched SMTP</title>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>batched incoming</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>batched SMTP input</primary>
+</indexterm>
+The <option>-bS</option> command line option causes Exim to accept one or more messages by
+reading SMTP on the standard input, but to generate no responses. If the caller
+is trusted, the senders in the MAIL commands are believed; otherwise the
+sender is always the caller of Exim. Unqualified senders and receivers are not
+rejected (there seems little point) but instead just get qualified. HELO
+and EHLO act as RSET; VRFY, EXPN, ETRN and HELP, act
+as NOOP; QUIT quits.
+</para>
+<para>
+Minimal policy checking is done for BSMTP input. Only the non-SMTP
+ACL is run in the same way as for non-SMTP local input.
+</para>
+<para>
+If an error is detected while reading a message, including a missing <quote>.</quote> at
+the end, Exim gives up immediately. It writes details of the error to the
+standard output in a stylized way that the calling program should be able to
+make some use of automatically, for example:
+</para>
+<literallayout class="monospaced">
+554 Unexpected end of file
+Transaction started in line 10
+Error detected in line 14
+</literallayout>
+<para>
+It writes a more verbose version, for human consumption, to the standard error
+file, for example:
+</para>
+<literallayout class="monospaced">
+An error was detected while processing a file of BSMTP input.
+The error message was:
+
+501 '>' missing at end of address
+
+The SMTP transaction started in line 10.
+The error was detected in line 12.
+The SMTP command at fault was:
+
+rcpt to:<malformed@in.com.plete
+
+1 previous message was successfully processed.
+The rest of the batch was abandoned.
+</literallayout>
+<para>
+The return code from Exim is zero only if there were no errors. It is 1 if some
+messages were accepted before an error was detected, and 2 if no messages were
+accepted.
+<indexterm role="concept" startref="IIDsmtpproc1" class="endofrange"/>
+<indexterm role="concept" startref="IIDsmtpproc2" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPemsgcust">
+<title>Customizing bounce and warning messages</title>
+<titleabbrev>Customizing messages</titleabbrev>
+<para>
+When a message fails to be delivered, or remains in the queue for more than a
+configured amount of time, Exim sends a message to the original sender, or
+to an alternative configured address. The text of these messages is built into
+the code of Exim, but it is possible to change it, either by adding a single
+string, or by replacing each of the paragraphs by text supplied in a file.
+</para>
+<para>
+The <emphasis>From:</emphasis> and <emphasis>To:</emphasis> header lines are automatically generated; you can
+cause a <emphasis>Reply-To:</emphasis> line to be added by setting the <option>errors_reply_to</option>
+option. Exim also adds the line
+</para>
+<literallayout class="monospaced">
+Auto-Submitted: auto-generated
+</literallayout>
+<para>
+to all warning and bounce messages,
+</para>
+<section id="SECID239">
+<title>Customizing bounce messages</title>
+<para>
+<indexterm role="concept">
+<primary>customizing</primary>
+<secondary>bounce message</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>bounce message</primary>
+<secondary>customizing</secondary>
+</indexterm>
+If <option>bounce_message_text</option> is set, its contents are included in the default
+message immediately after <quote>This message was created automatically by mail
+delivery software.</quote> The string is not expanded. It is not used if
+<option>bounce_message_file</option> is set.
+</para>
+<para>
+When <option>bounce_message_file</option> is set, it must point to a template file for
+constructing error messages. The file consists of a series of text items,
+separated by lines consisting of exactly four asterisks. If the file cannot be
+opened, default text is used and a message is written to the main and panic
+logs. If any text item in the file is empty, default text is used for that
+item.
+</para>
+<para>
+<indexterm role="variable">
+<primary><varname>$bounce_recipient</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$bounce_return_size_limit</varname></primary>
+</indexterm>
+Each item of text that is read from the file is expanded, and there are two
+expansion variables which can be of use here: <varname>$bounce_recipient</varname> is set to
+the recipient of an error message while it is being created, and
+<varname>$bounce_return_size_limit</varname> contains the value of the <option>return_size_limit</option>
+option, rounded to a whole number.
+</para>
+<para>
+The items must appear in the file in the following order:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The first item is included in the headers, and should include at least a
+<emphasis>Subject:</emphasis> header. Exim does not check the syntax of these headers.
+</para>
+</listitem>
+<listitem>
+<para>
+The second item forms the start of the error message. After it, Exim lists the
+failing addresses with their error messages.
+</para>
+</listitem>
+<listitem>
+<para>
+The third item is used to introduce any text from pipe transports that is to be
+returned to the sender. It is omitted if there is no such text.
+</para>
+</listitem>
+<listitem>
+<para>
+The fourth, fifth and sixth items will be ignored and may be empty.
+The fields exist for back-compatibility
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The default state (<option>bounce_message_file</option> unset) is equivalent to the
+following file, in which the sixth item is empty. The <emphasis>Subject:</emphasis> and some
+other lines have been split in order to fit them on the page:
+</para>
+<literallayout class="monospaced">
+Subject: Mail delivery failed
+ ${if eq{$sender_address}{$bounce_recipient}
+ {: returning message to sender}}
+****
+This message was created automatically by mail delivery software.
+
+A message ${if eq{$sender_address}{$bounce_recipient}
+ {that you sent }{sent by
+
+<$sender_address>
+
+}}could not be delivered to all of its recipients.
+This is a permanent error. The following address(es) failed:
+****
+The following text was generated during the delivery attempt(s):
+****
+------ This is a copy of the message, including all the headers.
+ ------
+****
+------ The body of the message is $message_size characters long;
+ only the first
+------ $bounce_return_size_limit or so are included here.
+****
+</literallayout>
+</section>
+<section id="SECTcustwarn">
+<title>Customizing warning messages</title>
+<para>
+<indexterm role="concept">
+<primary>customizing</primary>
+<secondary>warning message</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>warning of delay</primary>
+<secondary>customizing the message</secondary>
+</indexterm>
+The option <option>warn_message_file</option> can be pointed at a template file for use when
+warnings about message delays are created. In this case there are only three
+text sections:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+The first item is included in the headers, and should include at least a
+<emphasis>Subject:</emphasis> header. Exim does not check the syntax of these headers.
+</para>
+</listitem>
+<listitem>
+<para>
+The second item forms the start of the warning message. After it, Exim lists
+the delayed addresses.
+</para>
+</listitem>
+<listitem>
+<para>
+The third item then ends the message.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The default state is equivalent to the following file, except that some lines
+have been split here, in order to fit them on the page:
+</para>
+<literallayout class="monospaced">
+Subject: Warning: message $message_exim_id delayed
+ $warn_message_delay
+****
+This message was created automatically by mail delivery software.
+
+A message ${if eq{$sender_address}{$warn_message_recipients}
+{that you sent }{sent by
+
+<$sender_address>
+
+}}has not been delivered to all of its recipients after
+more than $warn_message_delay in the queue on $primary_hostname.
+
+The message identifier is: $message_exim_id
+The subject of the message is: $h_subject
+The date of the message is: $h_date
+
+The following address(es) have not yet been delivered:
+****
+No action is required on your part. Delivery attempts will
+continue for some time, and this warning may be repeated at
+intervals if the message remains undelivered. Eventually the
+mail delivery software will give up, and when that happens,
+the message will be returned to you.
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$warn_message_delay</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$warn_message_recipients</varname></primary>
+</indexterm>
+However, in the default state the subject and date lines are omitted if no
+appropriate headers exist. During the expansion of this file,
+<varname>$warn_message_delay</varname> is set to the delay time in one of the forms <quote><<emphasis>n</emphasis>>
+minutes</quote> or <quote><<emphasis>n</emphasis>> hours</quote>, and <varname>$warn_message_recipients</varname> contains a list
+of recipients for the warning message. There may be more than one if there are
+multiple addresses with different <option>errors_to</option> settings on the routers that
+handled them.
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPcomconreq">
+<title>Some common configuration settings</title>
+<para>
+This chapter discusses some configuration settings that seem to be fairly
+common. More examples and discussion can be found in the Exim book.
+</para>
+<section id="SECID240">
+<title>Sending mail to a smart host</title>
+<para>
+<indexterm role="concept">
+<primary>smart host</primary>
+<secondary>example router</secondary>
+</indexterm>
+If you want to send all mail for non-local domains to a <quote>smart host</quote>, you
+should replace the default <command>dnslookup</command> router with a router which does the
+routing explicitly:
+</para>
+<literallayout class="monospaced">
+send_to_smart_host:
+ driver = manualroute
+ route_list = !+local_domains smart.host.name
+ transport = remote_smtp
+</literallayout>
+<para>
+You can use the smart host’s IP address instead of the name if you wish.
+If you are using Exim only to submit messages to a smart host, and not for
+receiving incoming messages, you can arrange for it to do the submission
+synchronously by setting the <option>mua_wrapper</option> option (see chapter
+<xref linkend="CHAPnonqueueing"/>).
+</para>
+</section>
+<section id="SECTmailinglists">
+<title>Using Exim to handle mailing lists</title>
+<para>
+<indexterm role="concept">
+<primary>mailing lists</primary>
+</indexterm>
+Exim can be used to run simple mailing lists, but for large and/or complicated
+requirements, the use of additional specialized mailing list software such as
+Majordomo or Mailman is recommended.
+</para>
+<para>
+The <command>redirect</command> router can be used to handle mailing lists where each list
+is maintained in a separate file, which can therefore be managed by an
+independent manager. The <option>domains</option> router option can be used to run these
+lists in a separate domain from normal mail. For example:
+</para>
+<literallayout class="monospaced">
+lists:
+ driver = redirect
+ domains = lists.example
+ file = ${lookup {$local_part} dsearch,ret=full {/usr/lists}}
+ forbid_pipe
+ forbid_file
+ errors_to = ${quote_local_part:$local_part-request}@lists.example
+ no_more
+</literallayout>
+<para>
+This router is skipped for domains other than <emphasis>lists.example</emphasis>. For addresses
+in that domain, it looks for a file that matches the local part. If there is no
+such file, the router declines, but because <option>no_more</option> is set, no subsequent
+routers are tried, and so the whole delivery fails.
+</para>
+<para>
+The <option>forbid_pipe</option> and <option>forbid_file</option> options prevent a local part from being
+expanded into a filename or a pipe delivery, which is usually inappropriate in
+a mailing list.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>errors_to</option></primary>
+</indexterm>
+The <option>errors_to</option> option specifies that any delivery errors caused by addresses
+taken from a mailing list are to be sent to the given address rather than the
+original sender of the message. However, before acting on this, Exim verifies
+the error address, and ignores it if verification fails.
+</para>
+<para>
+For example, using the configuration above, mail sent to
+<emphasis>dicts@lists.example</emphasis> is passed on to those addresses contained in
+<filename>/usr/lists/dicts</filename>, with error reports directed to
+<emphasis>dicts-request@lists.example</emphasis>, provided that this address can be verified.
+There could be a file called <filename>/usr/lists/dicts-request</filename> containing
+the address(es) of this particular list’s manager(s), but other approaches,
+such as setting up an earlier router (possibly using the <option>local_part_prefix</option>
+or <option>local_part_suffix</option> options) to handle addresses of the form
+<option>owner-</option><emphasis>xxx</emphasis> or <option>xxx-</option><emphasis>request</emphasis>, are also possible.
+</para>
+</section>
+<section id="SECID241">
+<title>Syntax errors in mailing lists</title>
+<para>
+<indexterm role="concept">
+<primary>mailing lists</primary>
+<secondary>syntax errors in</secondary>
+</indexterm>
+If an entry in redirection data contains a syntax error, Exim normally defers
+delivery of the original address. That means that a syntax error in a mailing
+list holds up all deliveries to the list. This may not be appropriate when a
+list is being maintained automatically from data supplied by users, and the
+addresses are not rigorously checked.
+</para>
+<para>
+If the <option>skip_syntax_errors</option> option is set, the <command>redirect</command> router just skips
+entries that fail to parse, noting the incident in the log. If in addition
+<option>syntax_errors_to</option> is set to a verifiable address, a message is sent to it
+whenever a broken address is skipped. It is usually appropriate to set
+<option>syntax_errors_to</option> to the same address as <option>errors_to</option>.
+</para>
+</section>
+<section id="SECID242">
+<title>Re-expansion of mailing lists</title>
+<para>
+<indexterm role="concept">
+<primary>mailing lists</primary>
+<secondary>re-expansion of</secondary>
+</indexterm>
+Exim remembers every individual address to which a message has been delivered,
+in order to avoid duplication, but it normally stores only the original
+recipient addresses with a message. If all the deliveries to a mailing list
+cannot be done at the first attempt, the mailing list is re-expanded when the
+delivery is next tried. This means that alterations to the list are taken into
+account at each delivery attempt, so addresses that have been added to
+the list since the message arrived will therefore receive a copy of the
+message, even though it pre-dates their subscription.
+</para>
+<para>
+If this behaviour is felt to be undesirable, the <option>one_time</option> option can be set
+on the <command>redirect</command> router. If this is done, any addresses generated by the
+router that fail to deliver at the first attempt are added to the message as
+<quote>top level</quote> addresses, and the parent address that generated them is marked
+<quote>delivered</quote>. Thus, expansion of the mailing list does not happen again at the
+subsequent delivery attempts. The disadvantage of this is that if any of the
+failing addresses are incorrect, correcting them in the file has no effect on
+pre-existing messages.
+</para>
+<para>
+The original top-level address is remembered with each of the generated
+addresses, and is output in any log messages. However, any intermediate parent
+addresses are not recorded. This makes a difference to the log only if the
+<option>all_parents</option> selector is set, but for mailing lists there is normally only
+one level of expansion anyway.
+</para>
+</section>
+<section id="SECID243">
+<title>Closed mailing lists</title>
+<para>
+<indexterm role="concept">
+<primary>mailing lists</primary>
+<secondary>closed</secondary>
+</indexterm>
+The examples so far have assumed open mailing lists, to which anybody may
+send mail. It is also possible to set up closed lists, where mail is accepted
+from specified senders only. This is done by making use of the generic
+<option>senders</option> option to restrict the router that handles the list.
+</para>
+<para>
+The following example uses the same file as a list of recipients and as a list
+of permitted senders. It requires three routers:
+</para>
+<literallayout class="monospaced">
+lists_request:
+ driver = redirect
+ domains = lists.example
+ local_part_suffix = -request
+ local_parts = ${lookup {$local_part} dsearch,filter=file {/usr/lists}}
+ file = /usr/lists/${local_part_data}-request
+ no_more
+
+lists_post:
+ driver = redirect
+ domains = lists.example
+ senders = ${if exists {/usr/lists/$local_part}\
+ {lsearch;/usr/lists/$local_part}{*}}
+ file = ${lookup {$local_part} dsearch,ret=full {/usr/lists}}
+ forbid_pipe
+ forbid_file
+ errors_to = ${quote_local_part:$local_part-request}@lists.example
+ no_more
+
+lists_closed:
+ driver = redirect
+ domains = lists.example
+ allow_fail
+ data = :fail: $local_part@lists.example is a closed mailing list
+</literallayout>
+<para>
+All three routers have the same <option>domains</option> setting, so for any other domains,
+they are all skipped. The first router runs only if the local part ends in
+<option>-request</option>. It handles messages to the list manager(s) by means of an open
+mailing list.
+</para>
+<para>
+The second router runs only if the <option>senders</option> precondition is satisfied. It
+checks for the existence of a list that corresponds to the local part, and then
+checks that the sender is on the list by means of a linear search. It is
+necessary to check for the existence of the file before trying to search it,
+because otherwise Exim thinks there is a configuration error. If the file does
+not exist, the expansion of <option>senders</option> is *, which matches all senders. This
+means that the router runs, but because there is no list, declines, and
+<option>no_more</option> ensures that no further routers are run. The address fails with an
+<quote>unrouteable address</quote> error.
+</para>
+<para>
+The third router runs only if the second router is skipped, which happens when
+a mailing list exists, but the sender is not on it. This router forcibly fails
+the address, giving a suitable error message.
+</para>
+</section>
+<section id="SECTverp">
+<title>Variable Envelope Return Paths (VERP)</title>
+<para>
+<indexterm role="concept">
+<primary>VERP</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Variable Envelope Return Paths</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope from</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>envelope sender</primary>
+</indexterm>
+Variable Envelope Return Paths – see <emphasis role="bold"><ulink url="https://cr.yp.to/proto/verp.txt">https://cr.yp.to/proto/verp.txt</ulink></emphasis> –
+are a way of helping mailing list administrators discover which subscription
+address is the cause of a particular delivery failure. The idea is to encode
+the original recipient address in the outgoing envelope sender address, so that
+if the message is forwarded by another host and then subsequently bounces, the
+original recipient can be extracted from the recipient address of the bounce.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>errors_to</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>return_path</option></primary>
+</indexterm>
+Envelope sender addresses can be modified by Exim using two different
+facilities: the <option>errors_to</option> option on a router (as shown in previous mailing
+list examples), or the <option>return_path</option> option on a transport. The second of
+these is effective only if the message is successfully delivered to another
+host; it is not used for errors detected on the local host (see the description
+of <option>return_path</option> in chapter <xref linkend="CHAPtransportgeneric"/>). Here is an example
+of the use of <option>return_path</option> to implement VERP on an <command>smtp</command> transport:
+</para>
+<literallayout class="monospaced">
+verp_smtp:
+ driver = smtp
+ max_rcpt = 1
+ return_path = \
+ ${if match {$return_path}{^(.+?)-request@your.dom.example\$}\
+ {${quote_local_part:$1-request+$local_part=$domain}@your.dom.example}fail}
+</literallayout>
+<para>
+This has the effect of rewriting the return path (envelope sender) on outgoing
+SMTP messages, if the local part of the original return path ends in
+<quote>-request</quote>, and the domain is <emphasis>your.dom.example</emphasis>. The rewriting inserts the
+local part and domain of the recipient into the return path. Suppose, for
+example, that a message whose return path has been set to
+<emphasis>somelist-request@your.dom.example</emphasis> is sent to
+<emphasis>subscriber@other.dom.example</emphasis>. In the transport, the return path is
+rewritten as
+</para>
+<literallayout class="monospaced">
+somelist-request+subscriber=other.dom.example@your.dom.example
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part</varname></primary>
+</indexterm>
+For this to work, you must tell Exim to send multiple copies of messages that
+have more than one recipient, so that each copy has just one recipient. This is
+achieved by setting <option>max_rcpt</option> to 1. Without this, a single copy of a message
+might be sent to several different recipients in the same domain, in which case
+<varname>$local_part</varname> is not available in the transport, because it is not unique.
+</para>
+<para>
+Unless your host is doing nothing but mailing list deliveries, you should
+probably use a separate transport for the VERP deliveries, so as not to use
+extra resources in making one-per-recipient copies for other deliveries. This
+can easily be done by expanding the <option>transport</option> option in the router:
+</para>
+<literallayout class="monospaced">
+dnslookup:
+ driver = dnslookup
+ domains = ! +local_domains
+ transport = \
+ ${if match {$return_path}{^(.+?)-request@your.dom.example\$}\
+ {verp_smtp}{remote_smtp}}
+ no_more
+</literallayout>
+<para>
+If you want to change the return path using <option>errors_to</option> in a router instead
+of using <option>return_path</option> in the transport, you need to set <option>errors_to</option> on all
+routers that handle mailing list addresses. This will ensure that all delivery
+errors, including those detected on the local host, are sent to the VERP
+address.
+</para>
+<para>
+On a host that does no local deliveries and has no manual routing, only the
+<command>dnslookup</command> router needs to be changed. A special transport is not needed for
+SMTP deliveries. Every mailing list recipient has its own return path value,
+and so Exim must hand them to the transport one at a time. Here is an example
+of a <command>dnslookup</command> router that implements VERP:
+</para>
+<literallayout class="monospaced">
+verp_dnslookup:
+ driver = dnslookup
+ domains = ! +local_domains
+ transport = remote_smtp
+ errors_to = \
+ ${if match {$return_path}{^(.+?)-request@your.dom.example\$}}
+ {${quote_local_part:$1-request+$local_part=$domain}@your.dom.example}fail}
+ no_more
+</literallayout>
+<para>
+Before you start sending out messages with VERPed return paths, you must also
+configure Exim to accept the bounce messages that come back to those paths.
+Typically this is done by setting a <option>local_part_suffix</option> option for a
+router, and using this to route the messages to wherever you want to handle
+them.
+</para>
+<para>
+The overhead incurred in using VERP depends very much on the size of the
+message, the number of recipient addresses that resolve to the same remote
+host, and the speed of the connection over which the message is being sent. If
+a lot of addresses resolve to the same host and the connection is slow, sending
+a separate copy of the message for each address may take substantially longer
+than sending a single copy with many recipients (for which VERP cannot be
+used).
+</para>
+</section>
+<section id="SECTvirtualdomains">
+<title>Virtual domains</title>
+<para>
+<indexterm role="concept">
+<primary>virtual domains</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>domain</primary>
+<secondary>virtual</secondary>
+</indexterm>
+The phrase <emphasis>virtual domain</emphasis> is unfortunately used with two rather different
+meanings:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+A domain for which there are no real mailboxes; all valid local parts are
+aliases for other email addresses. Common examples are organizational
+top-level domains and <quote>vanity</quote> domains.
+</para>
+</listitem>
+<listitem>
+<para>
+One of a number of independent domains that are all handled by the same host,
+with mailboxes on that host, but where the mailbox owners do not necessarily
+have login accounts on that host.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The first usage is probably more common, and does seem more <quote>virtual</quote> than
+the second. This kind of domain can be handled in Exim with a straightforward
+aliasing router. One approach is to create a separate alias file for each
+virtual domain. Exim can test for the existence of the alias file to determine
+whether the domain exists. The <command>dsearch</command> lookup type is useful here, leading
+to a router of this form:
+</para>
+<literallayout class="monospaced">
+virtual:
+ driver = redirect
+ domains = dsearch;/etc/mail/virtual
+ data = ${lookup{$local_part}lsearch{/etc/mail/virtual/$domain_data}}
+ no_more
+</literallayout>
+<para revisionflag="changed">
+The <option>domains</option> option specifies that the router is to be skipped, unless there
+is a file in the <filename>/etc/mail/virtual</filename> directory whose name is the same as the
+domain that is being processed.
+The <command>dsearch</command> lookup used results in an untainted version of <varname>$domain</varname>
+being placed into the <varname>$domain_data</varname> variable.
+</para>
+<para>
+When the router runs, it looks up the local
+part in the file to find a new address (or list of addresses). The <option>no_more</option>
+setting ensures that if the lookup fails (leading to <option>data</option> being an empty
+string), Exim gives up on the address without trying any subsequent routers.
+</para>
+<para>
+This one router can handle all the virtual domains because the alias filenames
+follow a fixed pattern. Permissions can be arranged so that appropriate people
+can edit the different alias files. A successful aliasing operation results in
+a new envelope recipient address, which is then routed from scratch.
+</para>
+<para>
+The other kind of <quote>virtual</quote> domain can also be handled in a straightforward
+way. One approach is to create a file for each domain containing a list of
+valid local parts, and use it in a router like this:
+</para>
+<literallayout class="monospaced">
+my_domains:
+ driver = accept
+ domains = dsearch;/etc/mail/domains
+ local_parts = lsearch;/etc/mail/domains/$domain
+ transport = my_mailboxes
+</literallayout>
+<para>
+The address is accepted if there is a file for the domain, and the local part
+can be found in the file. The <option>domains</option> option is used to check for the
+file’s existence because <option>domains</option> is tested before the <option>local_parts</option>
+option (see section <xref linkend="SECTrouprecon"/>). You cannot use <option>require_files</option>,
+because that option is tested after <option>local_parts</option>. The transport is as
+follows:
+</para>
+<literallayout class="monospaced">
+my_mailboxes:
+ driver = appendfile
+ file = /var/mail/$domain/$local_part_data
+ user = mail
+</literallayout>
+<para>
+This uses a directory of mailboxes for each domain. The <option>user</option> setting is
+required, to specify which uid is to be used for writing to the mailboxes.
+</para>
+<para>
+The configuration shown here is just one example of how you might support this
+requirement. There are many other ways this kind of configuration can be set
+up, for example, by using a database instead of separate files to hold all the
+information about the domains.
+</para>
+</section>
+<section id="SECTmulbox">
+<title>Multiple user mailboxes</title>
+<para>
+<indexterm role="concept">
+<primary>multiple mailboxes</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>mailbox</primary>
+<secondary>multiple</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>prefix</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>local part</primary>
+<secondary>suffix</secondary>
+</indexterm>
+Heavy email users often want to operate with multiple mailboxes, into which
+incoming mail is automatically sorted. A popular way of handling this is to
+allow users to use multiple sender addresses, so that replies can easily be
+identified. Users are permitted to add prefixes or suffixes to their local
+parts for this purpose. The wildcard facility of the generic router options
+<option>local_part_prefix</option> and <option>local_part_suffix</option> can be used for this. For
+example, consider this router:
+</para>
+<literallayout class="monospaced">
+userforward:
+ driver = redirect
+ check_local_user
+ file = $home/.forward
+ local_part_suffix = -*
+ local_part_suffix_optional
+ allow_filter
+</literallayout>
+<para>
+<indexterm role="variable">
+<primary><varname>$local_part_suffix</varname></primary>
+</indexterm>
+It runs a user’s <filename>.forward</filename> file for all local parts of the form
+<emphasis>username-*</emphasis>. Within the filter file the user can distinguish different
+cases by testing the variable <varname>$local_part_suffix</varname>. For example:
+</para>
+<literallayout class="monospaced">
+if $local_part_suffix contains -special then
+save /home/$local_part/Mail/special
+endif
+</literallayout>
+<para>
+If the filter file does not exist, or does not deal with such addresses, they
+fall through to subsequent routers, and, assuming no subsequent use of the
+<option>local_part_suffix</option> option is made, they presumably fail. Thus, users have
+control over which suffixes are valid.
+</para>
+<para>
+Alternatively, a suffix can be used to trigger the use of a different
+<filename>.forward</filename> file – which is the way a similar facility is implemented in
+another MTA:
+</para>
+<literallayout class="monospaced">
+userforward:
+ driver = redirect
+ check_local_user
+ local_part_suffix = -*
+ local_part_suffix_optional
+ file = ${lookup {.forward$local_part_suffix} dsearch,ret=full {$home} {$value}fail}
+ allow_filter
+</literallayout>
+<para>
+If there is no suffix, <filename>.forward</filename> is used; if the suffix is <emphasis>-special</emphasis>, for
+example, <filename>.forward-special</filename> is used. Once again, if the appropriate file
+does not exist, or does not deal with the address, it is passed on to
+subsequent routers, which could, if required, look for an unqualified
+<filename>.forward</filename> file to use as a default.
+</para>
+</section>
+<section id="SECID244">
+<title>Simplified vacation processing</title>
+<para>
+<indexterm role="concept">
+<primary>vacation processing</primary>
+</indexterm>
+The traditional way of running the <emphasis>vacation</emphasis> program is for a user to set up
+a pipe command in a <filename>.forward</filename> file
+(see section <xref linkend="SECTspecitredli"/> for syntax details).
+This is prone to error by inexperienced users. There are two features of Exim
+that can be used to make this process simpler for users:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+A local part prefix such as <quote>vacation-</quote> can be specified on a router which
+can cause the message to be delivered directly to the <emphasis>vacation</emphasis> program, or
+alternatively can use Exim’s <command>autoreply</command> transport. The contents of a user’s
+<filename>.forward</filename> file are then much simpler. For example:
+</para>
+<literallayout class="monospaced">
+spqr, vacation-spqr
+</literallayout>
+</listitem>
+<listitem>
+<para>
+The <option>require_files</option> generic router option can be used to trigger a
+vacation delivery by checking for the existence of a certain file in the
+user’s home directory. The <option>unseen</option> generic option should also be used, to
+ensure that the original delivery also proceeds. In this case, all the user has
+to do is to create a file called, say, <filename>.vacation</filename>, containing a vacation
+message.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Another advantage of both these methods is that they both work even when the
+use of arbitrary pipes by users is locked out.
+</para>
+</section>
+<section id="SECID245">
+<title>Taking copies of mail</title>
+<para>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>copying every</secondary>
+</indexterm>
+Some installations have policies that require archive copies of all messages to
+be made. A single copy of each message can easily be taken by an appropriate
+command in a system filter, which could, for example, use a different file for
+each day’s messages.
+</para>
+<para>
+There is also a shadow transport mechanism that can be used to take copies of
+messages that are successfully delivered by local transports, one copy per
+delivery. This could be used, <emphasis>inter alia</emphasis>, to implement automatic
+notification of delivery by sites that insist on doing such things.
+</para>
+</section>
+<section id="SECID246">
+<title>Intermittently connected hosts</title>
+<para>
+<indexterm role="concept">
+<primary>intermittently connected hosts</primary>
+</indexterm>
+It has become quite common (because it is cheaper) for hosts to connect to the
+Internet periodically rather than remain connected all the time. The normal
+arrangement is that mail for such hosts accumulates on a system that is
+permanently connected.
+</para>
+<para>
+Exim was designed for use on permanently connected hosts, and so it is not
+particularly well-suited to use in an intermittently connected environment.
+Nevertheless there are some features that can be used.
+</para>
+</section>
+<section id="SECID247">
+<title>Exim on the upstream server host</title>
+<para>
+It is tempting to arrange for incoming mail for the intermittently connected
+host to remain in Exim’s queue until the client connects. However, this
+approach does not scale very well. Two different kinds of waiting message are
+being mixed up in the same queue – those that cannot be delivered because of
+some temporary problem, and those that are waiting for their destination host
+to connect. This makes it hard to manage the queue, as well as wasting
+resources, because each queue runner scans the entire queue.
+</para>
+<para>
+A better approach is to separate off those messages that are waiting for an
+intermittently connected host. This can be done by delivering these messages
+into local files in batch SMTP, <quote>mailstore</quote>, or other envelope-preserving
+format, from where they are transmitted by other software when their
+destination connects. This makes it easy to collect all the mail for one host
+in a single directory, and to apply local timeout rules on a per-message basis
+if required.
+</para>
+<para>
+On a very small scale, leaving the mail on Exim’s queue can be made to work. If
+you are doing this, you should configure Exim with a long retry period for the
+intermittent host. For example:
+</para>
+<literallayout class="monospaced">
+cheshire.wonderland.fict.example * F,5d,24h
+</literallayout>
+<para>
+This stops a lot of failed delivery attempts from occurring, but Exim remembers
+which messages it has queued up for that host. Once the intermittent host comes
+online, forcing delivery of one message (either by using the <option>-M</option> or <option>-R</option>
+options, or by using the ETRN SMTP command (see section <xref linkend="SECTETRN"/>)
+causes all the queued up messages to be delivered, often down a single SMTP
+connection. While the host remains connected, any new messages get delivered
+immediately.
+</para>
+<para>
+If the connecting hosts do not have fixed IP addresses, that is, if a host is
+issued with a different IP address each time it connects, Exim’s retry
+mechanisms on the holding host get confused, because the IP address is normally
+used as part of the key string for holding retry information. This can be
+avoided by unsetting <option>retry_include_ip_address</option> on the <command>smtp</command> transport.
+Since this has disadvantages for permanently connected hosts, it is best to
+arrange a separate transport for the intermittently connected ones.
+</para>
+</section>
+<section id="SECID248">
+<title>Exim on the intermittently connected client host</title>
+<para>
+The value of <option>smtp_accept_queue_per_connection</option> should probably be
+increased, or even set to zero (that is, disabled) on the intermittently
+connected host, so that all incoming messages down a single connection get
+delivered immediately.
+</para>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>passed connection</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>multiple deliveries</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>multiple SMTP deliveries</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>first pass routing</primary>
+</indexterm>
+Mail waiting to be sent from an intermittently connected host will probably
+not have been routed, because without a connection DNS lookups are not
+possible. This means that if a normal queue run is done at connection time,
+each message is likely to be sent in a separate SMTP session. This can be
+avoided by starting the queue run with a command line option beginning with
+<option>-qq</option> instead of <option>-q</option>. In this case, the queue is scanned twice. In the
+first pass, routing is done but no deliveries take place. The second pass is a
+normal queue run; since all the messages have been previously routed, those
+destined for the same host are likely to get sent as multiple deliveries in a
+single SMTP connection.
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPnonqueueing">
+<title>Using Exim as a non-queueing client</title>
+<titleabbrev>Exim as a non-queueing client</titleabbrev>
+<para>
+<indexterm role="concept">
+<primary>client, non-queueing</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>smart host</primary>
+<secondary>suppressing queueing</secondary>
+</indexterm>
+On a personal computer, it is a common requirement for all
+email to be sent to a <quote>smart host</quote>. There are plenty of MUAs that can be
+configured to operate that way, for all the popular operating systems.
+However, there are some MUAs for Unix-like systems that cannot be so
+configured: they submit messages using the command line interface of
+<filename>/usr/sbin/sendmail</filename>. Furthermore, utility programs such as <emphasis>cron</emphasis> submit
+messages this way.
+</para>
+<para>
+If the personal computer runs continuously, there is no problem, because it can
+run a conventional MTA that handles delivery to the smart host, and deal with
+any delays via its queueing mechanism. However, if the computer does not run
+continuously or runs different operating systems at different times, queueing
+email is not desirable.
+</para>
+<para>
+There is therefore a requirement for something that can provide the
+<filename>/usr/sbin/sendmail</filename> interface but deliver messages to a smart host without
+any queueing or retrying facilities. Furthermore, the delivery to the smart
+host should be synchronous, so that if it fails, the sending MUA is immediately
+informed. In other words, we want something that extends an MUA that submits
+to a local MTA via the command line so that it behaves like one that submits
+to a remote smart host using TCP/SMTP.
+</para>
+<para>
+There are a number of applications (for example, there is one called <emphasis>ssmtp</emphasis>)
+that do this job. However, people have found them to be lacking in various
+ways. For instance, you might want to allow aliasing and forwarding to be done
+before sending a message to the smart host.
+</para>
+<para>
+Exim already had the necessary infrastructure for doing this job. Just a few
+tweaks were needed to make it behave as required, though it is somewhat of an
+overkill to use a fully-featured MTA for this purpose.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>mua_wrapper</option></primary>
+</indexterm>
+There is a Boolean global option called <option>mua_wrapper</option>, defaulting false.
+Setting <option>mua_wrapper</option> true causes Exim to run in a special mode where it
+assumes that it is being used to <quote>wrap</quote> a command-line MUA in the manner
+just described. As well as setting <option>mua_wrapper</option>, you also need to provide a
+compatible router and transport configuration. Typically there will be just one
+router and one transport, sending everything to a smart host.
+</para>
+<para>
+When run in MUA wrapping mode, the behaviour of Exim changes in the
+following ways:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+A daemon cannot be run, nor will Exim accept incoming messages from <emphasis>inetd</emphasis>.
+In other words, the only way to submit messages is via the command line.
+</para>
+</listitem>
+<listitem>
+<para>
+Each message is synchronously delivered as soon as it is received (<option>-odi</option> is
+assumed). All queueing options (<option>queue_only</option>, <option>queue_smtp_domains</option>,
+<option>control</option> in an ACL, etc.) are quietly ignored. The Exim reception process
+does not finish until the delivery attempt is complete. If the delivery is
+successful, a zero return code is given.
+</para>
+</listitem>
+<listitem>
+<para>
+Address redirection is permitted, but the final routing for all addresses must
+be to the same remote transport, and to the same list of hosts. Furthermore,
+the return address (envelope sender) must be the same for all recipients, as
+must any added or deleted header lines. In other words, it must be possible to
+deliver the message in a single SMTP transaction, however many recipients there
+are.
+</para>
+</listitem>
+<listitem>
+<para>
+If these conditions are not met, or if routing any address results in a
+failure or defer status, or if Exim is unable to deliver all the recipients
+successfully to one of the smart hosts, delivery of the entire message fails.
+</para>
+</listitem>
+<listitem>
+<para>
+Because no queueing is allowed, all failures are treated as permanent; there
+is no distinction between 4<emphasis>xx</emphasis> and 5<emphasis>xx</emphasis> SMTP response codes from the
+smart host. Furthermore, because only a single yes/no response can be given to
+the caller, it is not possible to deliver to some recipients and not others. If
+there is an error (temporary or permanent) for any recipient, all are failed.
+</para>
+</listitem>
+<listitem>
+<para>
+If more than one smart host is listed, Exim will try another host after a
+connection failure or a timeout, in the normal way. However, if this kind of
+failure happens for all the hosts, the delivery fails.
+</para>
+</listitem>
+<listitem>
+<para>
+When delivery fails, an error message is written to the standard error stream
+(as well as to Exim’s log), and Exim exits to the caller with a return code
+value 1. The message is expunged from Exim’s spool files. No bounce messages
+are ever generated.
+</para>
+</listitem>
+<listitem>
+<para>
+No retry data is maintained, and any retry rules are ignored.
+</para>
+</listitem>
+<listitem>
+<para>
+A number of Exim options are overridden: <option>deliver_drop_privilege</option> is forced
+true, <option>max_rcpt</option> in the <command>smtp</command> transport is forced to <quote>unlimited</quote>,
+<option>remote_max_parallel</option> is forced to one, and fallback hosts are ignored.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The overall effect is that Exim makes a single synchronous attempt to deliver
+the message, failing if there is any kind of problem. Because no local
+deliveries are done and no daemon can be run, Exim does not need root
+privilege. It should be possible to run it setuid to <emphasis>exim</emphasis> instead of setuid
+to <emphasis>root</emphasis>. See section <xref linkend="SECTrunexiwitpri"/> for a general discussion about
+the advantages and disadvantages of running without root privilege.
+</para>
+</chapter>
+
+<chapter id="CHAPlog">
+<title>Log files</title>
+<para>
+<indexterm role="concept" id="IIDloggen" class="startofrange">
+<primary>log</primary>
+<secondary>general description</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>types of</secondary>
+</indexterm>
+Exim writes three different logs, referred to as the main log, the reject log,
+and the panic log:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>main log</primary>
+</indexterm>
+The main log records the arrival of each message and each delivery in a single
+line in each case. The format is as compact as possible, in an attempt to keep
+down the size of log files. Two-character flag sequences make it easy to pick
+out these lines. A number of other events are recorded in the main log. Some of
+them are optional, in which case the <option>log_selector</option> option controls whether
+they are included or not. A Perl script called <emphasis>eximstats</emphasis>, which does simple
+analysis of main log files, is provided in the Exim distribution (see section
+<xref linkend="SECTmailstat"/>).
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>reject log</primary>
+</indexterm>
+The reject log records information from messages that are rejected as a result
+of a configuration option (that is, for policy reasons).
+The first line of each rejection is a copy of the line that is also written to
+the main log. Then, if the message’s header has been read at the time the log
+is written, its contents are written to this log. Only the original header
+lines are available; header lines added by ACLs are not logged. You can use the
+reject log to check that your policy controls are working correctly; on a busy
+host this may be easier than scanning the main log for rejection messages. You
+can suppress the writing of the reject log by setting <option>write_rejectlog</option>
+false.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>panic log</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>system log</primary>
+</indexterm>
+When certain serious errors occur, Exim writes entries to its panic log. If the
+error is sufficiently disastrous, Exim bombs out afterwards. Panic log entries
+are usually written to the main log as well, but can get lost amid the mass of
+other entries. The panic log should be empty under normal circumstances. It is
+therefore a good idea to check it (or to have a <emphasis>cron</emphasis> script check it)
+regularly, in order to become aware of any problems. When Exim cannot open its
+panic log, it tries as a last resort to write to the system log (syslog). This
+is opened with LOG_PID+LOG_CONS and the facility code of LOG_MAIL. The
+message itself is written at priority LOG_CRIT.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Every log line starts with a timestamp, in the format shown in the following
+example. Note that many of the examples shown in this chapter are line-wrapped.
+In the log file, this would be all on one line:
+</para>
+<literallayout class="monospaced">
+2001-09-16 16:09:47 SMTP connection from [127.0.0.1] closed
+ by QUIT
+</literallayout>
+<para>
+By default, the timestamps are in the local timezone. There are two
+ways of changing this:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+You can set the <option>timezone</option> option to a different time zone; in particular, if
+you set
+</para>
+<literallayout class="monospaced">
+timezone = UTC
+</literallayout>
+<para>
+the timestamps will be in UTC (aka GMT).
+</para>
+</listitem>
+<listitem>
+<para>
+If you set <option>log_timezone</option> true, the time zone is added to the timestamp, for
+example:
+</para>
+<literallayout class="monospaced">
+2003-04-25 11:17:07 +0100 Start queue run: pid=12762
+</literallayout>
+</listitem>
+</itemizedlist>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>process ids in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>pid (process id)</primary>
+<secondary>in log lines</secondary>
+</indexterm>
+Exim does not include its process id in log lines by default, but you can
+request that it does so by specifying the <literal>pid</literal> log selector (see section
+<xref linkend="SECTlogselector"/>). When this is set, the process id is output, in square
+brackets, immediately after the time and date.
+</para>
+<section id="SECTwhelogwri">
+<title>Where the logs are written</title>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>destination</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>to file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>to syslog</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>syslog</primary>
+</indexterm>
+The logs may be written to local files, or to syslog, or both. However, it
+should be noted that many syslog implementations use UDP as a transport, and
+are therefore unreliable in the sense that messages are not guaranteed to
+arrive at the loghost, nor is the ordering of messages necessarily maintained.
+It has also been reported that on large log files (tens of megabytes) you may
+need to tweak syslog to prevent it syncing the file with each write – on
+Linux this has been seen to make syslog take 90% plus of CPU time.
+</para>
+<para>
+The destination for Exim’s logs is configured by setting LOG_FILE_PATH in
+<filename>Local/Makefile</filename> or by setting <option>log_file_path</option> in the runtime
+configuration. This latter string is expanded, so it can contain, for example,
+references to the host name:
+</para>
+<literallayout class="monospaced">
+log_file_path = /var/log/$primary_hostname/exim_%slog
+</literallayout>
+<para>
+It is generally advisable, however, to set the string in <filename>Local/Makefile</filename>
+rather than at runtime, because then the setting is available right from the
+start of Exim’s execution. Otherwise, if there’s something it wants to log
+before it has read the configuration file (for example, an error in the
+configuration file) it will not use the path you want, and may not be able to
+log at all.
+</para>
+<para>
+The value of LOG_FILE_PATH or <option>log_file_path</option> is a colon-separated
+list, currently limited to at most two items. This is one option where the
+facility for changing a list separator may not be used. The list must always be
+colon-separated. If an item in the list is <quote>syslog</quote> then syslog is used;
+otherwise the item must either be an absolute path, containing <literal>%s</literal> at the
+point where <quote>main</quote>, <quote>reject</quote>, or <quote>panic</quote> is to be inserted, or be empty,
+implying the use of a default path.
+</para>
+<para>
+When Exim encounters an empty item in the list, it searches the list defined by
+LOG_FILE_PATH, and uses the first item it finds that is neither empty nor
+<quote>syslog</quote>. This means that an empty item in <option>log_file_path</option> can be used to
+mean <quote>use the path specified at build time</quote>. It no such item exists, log
+files are written in the <filename>log</filename> subdirectory of the spool directory. This is
+equivalent to the setting:
+</para>
+<literallayout class="monospaced">
+log_file_path = $spool_directory/log/%slog
+</literallayout>
+<para>
+If you do not specify anything at build time or runtime,
+or if you unset the option at runtime (i.e. <literal>log_file_path = </literal>),
+that is where the logs are written.
+</para>
+<para>
+A log file path may also contain <literal>%D</literal> or <literal>%M</literal> if datestamped log filenames
+are in use – see section <xref linkend="SECTdatlogfil"/> below.
+</para>
+<para>
+Here are some examples of possible settings:
+</para>
+<literallayout>
+<literal>LOG_FILE_PATH=syslog </literal> syslog only
+<literal>LOG_FILE_PATH=:syslog </literal> syslog and default path
+<literal>LOG_FILE_PATH=syslog : /usr/log/exim_%s </literal> syslog and specified path
+<literal>LOG_FILE_PATH=/usr/log/exim_%s </literal> specified path only
+</literallayout>
+<para>
+If there are more than two paths in the list, the first is used and a panic
+error is logged.
+</para>
+</section>
+<section id="SECID285">
+<title>Logging to local files that are periodically <quote>cycled</quote></title>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>cycling local files</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>cycling logs</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>exicyclog</emphasis></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>local files; writing to</secondary>
+</indexterm>
+Some operating systems provide centralized and standardized methods for cycling
+log files. For those that do not, a utility script called <emphasis>exicyclog</emphasis> is
+provided (see section <xref linkend="SECTcyclogfil"/>). This renames and compresses the
+main and reject logs each time it is called. The maximum number of old logs to
+keep can be set. It is suggested this script is run as a daily <emphasis>cron</emphasis> job.
+</para>
+<para>
+An Exim delivery process opens the main log when it first needs to write to it,
+and it keeps the file open in case subsequent entries are required – for
+example, if a number of different deliveries are being done for the same
+message. However, remote SMTP deliveries can take a long time, and this means
+that the file may be kept open long after it is renamed if <emphasis>exicyclog</emphasis> or
+something similar is being used to rename log files on a regular basis. To
+ensure that a switch of log files is noticed as soon as possible, Exim calls
+<function>stat()</function> on the main log’s name before reusing an open file, and if the file
+does not exist, or its inode has changed, the old file is closed and Exim
+tries to open the main log from scratch. Thus, an old log file may remain open
+for quite some time, but no Exim processes should write to it once it has been
+renamed.
+</para>
+</section>
+<section id="SECTdatlogfil">
+<title>Datestamped log files</title>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>datestamped files</secondary>
+</indexterm>
+Instead of cycling the main and reject log files by renaming them
+periodically, some sites like to use files whose names contain a datestamp,
+for example, <filename>mainlog-20031225</filename>. The datestamp is in the form <filename>yyyymmdd</filename> or
+<filename>yyyymm</filename>. Exim has support for this way of working. It is enabled by setting
+the <option>log_file_path</option> option to a path that includes <literal>%D</literal> or <literal>%M</literal> at the
+point where the datestamp is required. For example:
+</para>
+<literallayout class="monospaced">
+log_file_path = /var/spool/exim/log/%slog-%D
+log_file_path = /var/log/exim-%s-%D.log
+log_file_path = /var/spool/exim/log/%D-%slog
+log_file_path = /var/log/exim/%s.%M
+</literallayout>
+<para>
+As before, <literal>%s</literal> is replaced by <quote>main</quote> or <quote>reject</quote>; the following are
+examples of names generated by the above examples:
+</para>
+<literallayout class="monospaced">
+/var/spool/exim/log/mainlog-20021225
+/var/log/exim-reject-20021225.log
+/var/spool/exim/log/20021225-mainlog
+/var/log/exim/main.200212
+</literallayout>
+<para>
+When this form of log file is specified, Exim automatically switches to new
+files at midnight. It does not make any attempt to compress old logs; you
+will need to write your own script if you require this. You should not
+run <emphasis>exicyclog</emphasis> with this form of logging.
+</para>
+<para>
+The location of the panic log is also determined by <option>log_file_path</option>, but it
+is not datestamped, because rotation of the panic log does not make sense.
+When generating the name of the panic log, <literal>%D</literal> or <literal>%M</literal> are removed from
+the string. In addition, if it immediately follows a slash, a following
+non-alphanumeric character is removed; otherwise a preceding non-alphanumeric
+character is removed. Thus, the four examples above would give these panic
+log names:
+</para>
+<literallayout class="monospaced">
+/var/spool/exim/log/paniclog
+/var/log/exim-panic.log
+/var/spool/exim/log/paniclog
+/var/log/exim/panic
+</literallayout>
+</section>
+<section id="SECID249">
+<title>Logging to syslog</title>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>syslog; writing to</secondary>
+</indexterm>
+The use of syslog does not change what Exim logs or the format of its messages,
+except in one respect. If <option>syslog_timestamp</option> is set false, the timestamps on
+Exim’s log lines are omitted when these lines are sent to syslog. Apart from
+that, the same strings are written to syslog as to log files. The syslog
+<quote>facility</quote> is set to LOG_MAIL, and the program name to <quote>exim</quote>
+by default, but you can change these by setting the <option>syslog_facility</option> and
+<option>syslog_processname</option> options, respectively. If Exim was compiled with
+SYSLOG_LOG_PID set in <filename>Local/Makefile</filename> (this is the default in
+<filename>src/EDITME</filename>), then, on systems that permit it (all except ULTRIX), the
+LOG_PID flag is set so that the <function>syslog()</function> call adds the pid as well as
+the time and host name to each line.
+The three log streams are mapped onto syslog priorities as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<emphasis>mainlog</emphasis> is mapped to LOG_INFO
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>rejectlog</emphasis> is mapped to LOG_NOTICE
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>paniclog</emphasis> is mapped to LOG_ALERT
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Many log lines are written to both <emphasis>mainlog</emphasis> and <emphasis>rejectlog</emphasis>, and some are
+written to both <emphasis>mainlog</emphasis> and <emphasis>paniclog</emphasis>, so there will be duplicates if
+these are routed by syslog to the same place. You can suppress this duplication
+by setting <option>syslog_duplication</option> false.
+</para>
+<para>
+Exim’s log lines can sometimes be very long, and some of its <emphasis>rejectlog</emphasis>
+entries contain multiple lines when headers are included. To cope with both
+these cases, entries written to syslog are split into separate <function>syslog()</function>
+calls at each internal newline, and also after a maximum of
+870 data characters. (This allows for a total syslog line length of 1024, when
+additions such as timestamps are added.) If you are running a syslog
+replacement that can handle lines longer than the 1024 characters allowed by
+RFC 3164, you should set
+</para>
+<literallayout class="monospaced">
+SYSLOG_LONG_LINES=yes
+</literallayout>
+<para>
+in <filename>Local/Makefile</filename> before building Exim. That stops Exim from splitting long
+lines, but it still splits at internal newlines in <emphasis>reject</emphasis> log entries.
+</para>
+<para>
+To make it easy to re-assemble split lines later, each component of a split
+entry starts with a string of the form [<<emphasis>n</emphasis>>/<<emphasis>m</emphasis>>] or [<<emphasis>n</emphasis>>\<<emphasis>m</emphasis>>]
+where <<emphasis>n</emphasis>> is the component number and <<emphasis>m</emphasis>> is the total number of
+components in the entry. The / delimiter is used when the line was split
+because it was too long; if it was split because of an internal newline, the \
+delimiter is used. For example, supposing the length limit to be 50 instead of
+870, the following would be the result of a typical rejection message to
+<emphasis>mainlog</emphasis> (LOG_INFO), each line in addition being preceded by the time, host
+name, and pid as added by syslog:
+</para>
+<literallayout class="monospaced">
+[1/5] 2002-09-16 16:09:43 16RdAL-0006pc-00 rejected from
+[2/5] [127.0.0.1] (ph10): syntax error in 'From' header
+[3/5] when scanning for sender: missing or malformed lo
+[4/5] cal part in "<>" (envelope sender is <ph10@cam.exa
+[5/5] mple>)
+</literallayout>
+<para>
+The same error might cause the following lines to be written to <quote>rejectlog</quote>
+(LOG_NOTICE):
+</para>
+<literallayout class="monospaced">
+[1/18] 2002-09-16 16:09:43 16RdAL-0006pc-00 rejected fro
+[2/18] m [127.0.0.1] (ph10): syntax error in 'From' head
+[3/18] er when scanning for sender: missing or malformed
+[4/18] local part in "<>" (envelope sender is <ph10@cam
+[5\18] .example>)
+[6\18] Recipients: ph10@some.domain.cam.example
+[7\18] P Received: from [127.0.0.1] (ident=ph10)
+[8\18] by xxxxx.cam.example with smtp (Exim 4.00)
+[9\18] id 16RdAL-0006pc-00
+[10/18] for ph10@cam.example; Mon, 16 Sep 2002 16:
+[11\18] 09:43 +0100
+[12\18] F From: <>
+[13\18] Subject: this is a test header
+[18\18] X-something: this is another header
+[15/18] I Message-Id: <E16RdAL-0006pc-00@xxxxx.cam.examp
+[16\18] le>
+[17\18] B Bcc:
+[18/18] Date: Mon, 16 Sep 2002 16:09:43 +0100
+</literallayout>
+<para>
+Log lines that are neither too long nor contain newlines are written to syslog
+without modification.
+</para>
+<para>
+If only syslog is being used, the Exim monitor is unable to provide a log tail
+display, unless syslog is routing <emphasis>mainlog</emphasis> to a file on the local host and
+the environment variable EXIMON_LOG_FILE_PATH is set to tell the monitor
+where it is.
+</para>
+</section>
+<section id="SECID250">
+<title>Log line flags</title>
+<para>
+One line is written to the main log for each message received, and for each
+successful, unsuccessful, and delayed delivery. These lines can readily be
+picked out by the distinctive two-character flags that immediately follow the
+timestamp. The flags are:
+</para>
+<literallayout>
+<literal><=</literal> message arrival
+<literal>(=</literal> message fakereject
+<literal>=></literal> normal message delivery
+<literal>-></literal> additional address in same delivery
+<literal>>></literal> cutthrough message delivery
+<literal>*></literal> delivery suppressed by <option>-N</option>
+<literal>**</literal> delivery failed; address bounced
+<literal>==</literal> delivery deferred; temporary problem
+</literallayout>
+</section>
+<section id="SECID251">
+<title>Logging message reception</title>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>reception line</secondary>
+</indexterm>
+The format of the single-line entry in the main log that is written for every
+message received is shown in the basic example below, which is split over
+several lines in order to fit it on the page:
+</para>
+<literallayout class="monospaced">
+2002-10-31 08:57:53 16ZCW1-0005MB-00 <= kryten@dwarf.fict.example
+ H=mailer.fict.example [192.168.123.123] U=exim
+ P=smtp S=5678 id=<incoming message id>
+</literallayout>
+<para>
+The address immediately following <quote><=</quote> is the envelope sender address. A
+bounce message is shown with the sender address <quote><></quote>, and if it is locally
+generated, this is followed by an item of the form
+</para>
+<literallayout class="monospaced">
+R=<message id>
+</literallayout>
+<para>
+which is a reference to the message that caused the bounce to be sent.
+</para>
+<para>
+<indexterm role="concept">
+<primary>HELO</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>EHLO</primary>
+</indexterm>
+For messages from other hosts, the H and U fields identify the remote host and
+record the RFC 1413 identity of the user that sent the message, if one was
+received. The number given in square brackets is the IP address of the sending
+host. If there is a single, unparenthesized host name in the H field, as
+above, it has been verified to correspond to the IP address (see the
+<option>host_lookup</option> option). If the name is in parentheses, it was the name quoted
+by the remote host in the SMTP HELO or EHLO command, and has not been
+verified. If verification yields a different name to that given for HELO or
+EHLO, the verified name appears first, followed by the HELO or EHLO
+name in parentheses.
+</para>
+<para>
+Misconfigured hosts (and mail forgers) sometimes put an IP address, with or
+without brackets, in the HELO or EHLO command, leading to entries in
+the log containing text like these examples:
+</para>
+<literallayout class="monospaced">
+H=(10.21.32.43) [192.168.8.34]
+H=([10.21.32.43]) [192.168.8.34]
+</literallayout>
+<para>
+This can be confusing. Only the final address in square brackets can be relied
+on.
+</para>
+<para>
+For locally generated messages (that is, messages not received over TCP/IP),
+the H field is omitted, and the U field contains the login name of the caller
+of Exim.
+</para>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>logging</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>AUTH</primary>
+<secondary>logging</secondary>
+</indexterm>
+For all messages, the P field specifies the protocol used to receive the
+message. This is the value that is stored in <varname>$received_protocol</varname>. In the case
+of incoming SMTP messages, the value indicates whether or not any SMTP
+extensions (ESMTP), encryption, or authentication were used. If the SMTP
+session was encrypted, there is an additional X field that records the cipher
+suite that was used.
+</para>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>protocol</secondary>
+</indexterm>
+The protocol is set to <quote>esmtpsa</quote> or <quote>esmtpa</quote> for messages received from
+hosts that have authenticated themselves using the SMTP AUTH command. The first
+value is used when the SMTP connection was encrypted (<quote>secure</quote>). In this case
+there is an additional item A= followed by the name of the authenticator that
+was used. If an authenticated identification was set up by the authenticator’s
+<option>server_set_id</option> option, this is logged too, separated by a colon from the
+authenticator name.
+</para>
+<para>
+<indexterm role="concept">
+<primary>size</primary>
+<secondary>of message</secondary>
+</indexterm>
+The id field records the existing message id, if present. The size of the
+received message is given by the S field. When the message is delivered,
+headers may be removed or added, so that the size of delivered copies of the
+message may not correspond with this value (and indeed may be different to each
+other).
+</para>
+<para>
+The <option>log_selector</option> option can be used to request the logging of additional
+data when a message is received. See section <xref linkend="SECTlogselector"/> below.
+</para>
+</section>
+<section id="SECID252">
+<title>Logging deliveries</title>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>delivery line</secondary>
+</indexterm>
+The format of the single-line entry in the main log that is written for every
+delivery is shown in one of the examples below, for local and remote
+deliveries, respectively. Each example has been split into multiple lines in order
+to fit it on the page:
+</para>
+<literallayout class="monospaced">
+2002-10-31 08:59:13 16ZCW1-0005MB-00 => marv
+ <marv@hitch.fict.example> R=localuser T=local_delivery
+2002-10-31 09:00:10 16ZCW1-0005MB-00 =>
+ monk@holistic.fict.example R=dnslookup T=remote_smtp
+ H=holistic.fict.example [192.168.234.234]
+</literallayout>
+<para>
+For ordinary local deliveries, the original address is given in angle brackets
+after the final delivery address, which might be a pipe or a file. If
+intermediate address(es) exist between the original and the final address, the
+last of these is given in parentheses after the final address. The R and T
+fields record the router and transport that were used to process the address.
+</para>
+<para>
+If SMTP AUTH was used for the delivery there is an additional item A=
+followed by the name of the authenticator that was used.
+If an authenticated identification was set up by the authenticator’s <option>client_set_id</option>
+option, this is logged too, separated by a colon from the authenticator name.
+</para>
+<para>
+If a shadow transport was run after a successful local delivery, the log line
+for the successful delivery has an item added on the end, of the form
+</para>
+<literallayout>
+<literal>ST=<</literal><emphasis>shadow transport name</emphasis><literal>></literal>
+</literallayout>
+<para>
+If the shadow transport did not succeed, the error message is put in
+parentheses afterwards.
+</para>
+<para>
+<indexterm role="concept">
+<primary>asterisk</primary>
+<secondary>after IP address</secondary>
+</indexterm>
+When more than one address is included in a single delivery (for example, two
+SMTP RCPT commands in one transaction) the second and subsequent addresses are
+flagged with <literal>-></literal> instead of <literal>=></literal>. When two or more messages are delivered
+down a single SMTP connection, an asterisk follows the IP address in the log
+lines for the second and subsequent messages.
+When two or more messages are delivered down a single TLS connection, the
+DNS and some TLS-related information logged for the first message delivered
+will not be present in the log lines for the second and subsequent messages.
+TLS cipher information is still available.
+</para>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>cutthrough; logging</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>cutthrough</primary>
+<secondary>logging</secondary>
+</indexterm>
+When delivery is done in cutthrough mode it is flagged with <literal>>></literal> and the log
+line precedes the reception line, since cutthrough waits for a possible
+rejection from the destination in case it can reject the sourced item.
+</para>
+<para>
+The generation of a reply message by a filter file gets logged as a
+<quote>delivery</quote> to the addressee, preceded by <quote>></quote>.
+</para>
+<para>
+The <option>log_selector</option> option can be used to request the logging of additional
+data when a message is delivered. See section <xref linkend="SECTlogselector"/> below.
+</para>
+</section>
+<section id="SECID253">
+<title>Discarded deliveries</title>
+<para>
+<indexterm role="concept">
+<primary>discarded messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>discarded</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>discarded; logging</secondary>
+</indexterm>
+When a message is discarded as a result of the command <quote>seen finish</quote> being
+obeyed in a filter file which generates no deliveries, a log entry of the form
+</para>
+<literallayout class="monospaced">
+2002-12-10 00:50:49 16auJc-0001UB-00 => discarded
+ <low.club@bridge.example> R=userforward
+</literallayout>
+<para>
+is written, to record why no deliveries are logged. When a message is discarded
+because it is aliased to <quote>:blackhole:</quote> the log line is like this:
+</para>
+<literallayout class="monospaced">
+1999-03-02 09:44:33 10HmaX-0005vi-00 => :blackhole:
+ <hole@nowhere.example> R=blackhole_router
+</literallayout>
+</section>
+<section id="SECID254">
+<title>Deferred deliveries</title>
+<para>
+When a delivery is deferred, a line of the following form is logged:
+</para>
+<literallayout class="monospaced">
+2002-12-19 16:20:23 16aiQz-0002Q5-00 == marvin@endrest.example
+ R=dnslookup T=smtp defer (146): Connection refused
+</literallayout>
+<para>
+In the case of remote deliveries, the error is the one that was given for the
+last IP address that was tried. Details of individual SMTP failures are also
+written to the log, so the above line would be preceded by something like
+</para>
+<literallayout class="monospaced">
+2002-12-19 16:20:23 16aiQz-0002Q5-00 Failed to connect to
+ mail1.endrest.example [192.168.239.239]: Connection refused
+</literallayout>
+<para>
+When a deferred address is skipped because its retry time has not been reached,
+a message is written to the log, but this can be suppressed by setting an
+appropriate value in <option>log_selector</option>.
+</para>
+</section>
+<section id="SECID255">
+<title>Delivery failures</title>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>failure; logging</secondary>
+</indexterm>
+If a delivery fails because an address cannot be routed, a line of the
+following form is logged:
+</para>
+<literallayout class="monospaced">
+1995-12-19 16:20:23 0tRiQz-0002Q5-00 ** jim@trek99.example
+ <jim@trek99.example>: unknown mail domain
+</literallayout>
+<para>
+If a delivery fails at transport time, the router and transport are shown, and
+the response from the remote host is included, as in this example:
+</para>
+<literallayout class="monospaced">
+2002-07-11 07:14:17 17SXDU-000189-00 ** ace400@pb.example
+ R=dnslookup T=remote_smtp: SMTP error from remote mailer
+ after pipelined RCPT TO:<ace400@pb.example>: host
+ pbmail3.py.example [192.168.63.111]: 553 5.3.0
+ <ace400@pb.example>...Addressee unknown
+</literallayout>
+<para>
+The word <quote>pipelined</quote> indicates that the SMTP PIPELINING extension was being
+used. See <option>hosts_avoid_esmtp</option> in the <command>smtp</command> transport for a way of
+disabling PIPELINING. The log lines for all forms of delivery failure are
+flagged with <literal>**</literal>.
+</para>
+</section>
+<section id="SECID256">
+<title>Fake deliveries</title>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>fake; logging</secondary>
+</indexterm>
+If a delivery does not actually take place because the <option>-N</option> option has been
+used to suppress it, a normal delivery line is written to the log, except that
+<quote>=></quote> is replaced by <quote>*></quote>.
+</para>
+</section>
+<section id="SECID257">
+<title>Completion</title>
+<para>
+A line of the form
+</para>
+<literallayout class="monospaced">
+2002-10-31 09:00:11 16ZCW1-0005MB-00 Completed
+</literallayout>
+<para>
+is written to the main log when a message is about to be removed from the spool
+at the end of its processing.
+</para>
+</section>
+<section id="SECID258">
+<title>Summary of Fields in Log Lines</title>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>summary of fields</secondary>
+</indexterm>
+A summary of the field identifiers that are used in log lines is shown in
+the following table:
+</para>
+<literallayout>
+<literal>A </literal> authenticator name (and optional id and sender)
+<literal>C </literal> SMTP confirmation on delivery
+<literal> </literal> command list for <quote>no mail in SMTP session</quote>
+<literal>CV </literal> certificate verification status
+<literal>D </literal> duration of <quote>no mail in SMTP session</quote>
+<literal>DKIM</literal> domain verified in incoming message
+<literal>DN </literal> distinguished name from peer certificate
+<literal>DS </literal> DNSSEC secured lookups
+<literal>DT </literal> on <literal>=></literal>, <emphasis>==</emphasis> and <emphasis>**</emphasis> lines: time taken for, or to attempt, a delivery
+<literal>F </literal> sender address (on delivery lines)
+<literal>H </literal> host name and IP address
+<literal>I </literal> local interface used
+<literal>id </literal> message id (from header) for incoming message
+<literal>K </literal> CHUNKING extension used
+<literal>L </literal> on <literal><=</literal> and <literal>=></literal> lines: PIPELINING extension used
+<literal>M8S </literal> 8BITMIME status for incoming message
+<literal>P </literal> on <literal><=</literal> lines: protocol used
+<literal> </literal> on <literal>=></literal> and <literal>**</literal> lines: return path
+<literal>PRDR</literal> PRDR extension used
+<literal>PRX </literal> on <literal><=</literal> and <literal>=></literal> lines: proxy address
+<literal>Q </literal> alternate queue name
+<literal>QT </literal> on <literal>=></literal> lines: time spent on queue so far
+<literal> </literal> on <quote>Completed</quote> lines: time spent on queue
+<literal>R </literal> on <literal><=</literal> lines: reference for local bounce
+<literal> </literal> on <literal>=></literal> <literal>>></literal> <literal>**</literal> and <literal>==</literal> lines: router name
+<literal>RT </literal> on <literal><=</literal> lines: time taken for reception
+<literal>S </literal> size of message in bytes
+<literal>SNI </literal> server name indication from TLS client hello
+<literal>ST </literal> shadow transport name
+<literal>T </literal> on <literal><=</literal> lines: message subject (topic)
+<literal>TFO </literal> connection took advantage of TCP Fast Open
+<literal> </literal> on <literal>=></literal> <literal>**</literal> and <literal>==</literal> lines: transport name
+<literal>U </literal> local user or RFC 1413 identity
+<literal>X </literal> TLS cipher suite
+</literallayout>
+</section>
+<section id="SECID259">
+<title>Other log entries</title>
+<para>
+Various other types of log entry are written from time to time. Most should be
+self-explanatory. Among the more common are:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>time not reached</secondary>
+</indexterm>
+<emphasis>retry time not reached</emphasis> An address previously suffered a temporary error
+during routing or local delivery, and the time to retry has not yet arrived.
+This message is not written to an individual message log file unless it happens
+during the first delivery attempt.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>retry time not reached for any host</emphasis> An address previously suffered
+temporary errors during remote delivery, and the retry time has not yet arrived
+for any of the hosts to which it is routed.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>spool directory</primary>
+<secondary>file locked</secondary>
+</indexterm>
+<emphasis>spool file locked</emphasis> An attempt to deliver a message cannot proceed because
+some other Exim process is already working on the message. This can be quite
+common if queue running processes are started at frequent intervals. The
+<emphasis>exiwhat</emphasis> utility script can be used to find out what Exim processes are
+doing.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>error</primary>
+<secondary>ignored</secondary>
+</indexterm>
+<emphasis>error ignored</emphasis> There are several circumstances that give rise to this
+message:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+Exim failed to deliver a bounce message whose age was greater than
+<option>ignore_bounce_errors_after</option>. The bounce was discarded.
+</para>
+</listitem>
+<listitem>
+<para>
+A filter file set up a delivery using the <quote>noerror</quote> option, and the delivery
+failed. The delivery was discarded.
+</para>
+</listitem>
+<listitem>
+<para>
+A delivery set up by a router configured with
+</para>
+<literallayout class="monospaced">
+ errors_to = <>
+</literallayout>
+<para>
+failed. The delivery was discarded.
+</para>
+</listitem>
+</orderedlist>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>DKIM</primary>
+<secondary>log line</secondary>
+</indexterm>
+<emphasis>DKIM: d=</emphasis> Verbose results of a DKIM verification attempt, if enabled for
+logging and the message has a DKIM signature header.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECTlogselector">
+<title>Reducing or increasing what is logged</title>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>selectors</secondary>
+</indexterm>
+By setting the <option>log_selector</option> global option, you can disable some of Exim’s
+default logging, or you can request additional logging. The value of
+<option>log_selector</option> is made up of names preceded by plus or minus characters. For
+example:
+</para>
+<literallayout class="monospaced">
+log_selector = +arguments -retry_defer
+</literallayout>
+<para>
+The list of optional log items is in the following table, with the default
+selection marked by asterisks:
+</para>
+<literallayout>
+<literal> 8bitmime </literal> received 8BITMIME status
+<literal>*acl_warn_skipped </literal> skipped <option>warn</option> statement in ACL
+<literal> address_rewrite </literal> address rewriting
+<literal> all_parents </literal> all parents in => lines
+<literal> arguments </literal> command line arguments
+<literal>*connection_reject </literal> connection rejections
+<literal>*delay_delivery </literal> immediate delivery delayed
+<literal> deliver_time </literal> time taken to attempt delivery
+<literal> delivery_size </literal> add <literal>S=</literal><emphasis>nnn</emphasis> to => lines
+<literal>*dkim </literal> DKIM verified domain on <= lines
+<literal> dkim_verbose </literal> separate full DKIM verification result line, per signature
+<literal>*dnslist_defer </literal> defers of DNS list (aka RBL) lookups
+<literal> dnssec </literal> DNSSEC secured lookups
+<literal>*etrn </literal> ETRN commands
+<literal>*host_lookup_failed </literal> as it says
+<literal> ident_timeout </literal> timeout for ident connection
+<literal> incoming_interface </literal> local interface on <= and => lines
+<literal> incoming_port </literal> remote port on <= lines
+<literal>*lost_incoming_connection </literal> as it says (includes timeouts)
+<literal> millisec </literal> millisecond timestamps and RT,QT,DT,D times
+<literal>*msg_id </literal> on <= lines, Message-ID: header value
+<literal> msg_id_created </literal> on <= lines, Message-ID: header value when one had to be added
+<literal> outgoing_interface </literal> local interface on => lines
+<literal> outgoing_port </literal> add remote port to => lines
+<literal>*queue_run </literal> start and end queue runs
+<literal> queue_time </literal> time on queue for one recipient
+<literal> queue_time_overall </literal> time on queue for whole message
+<literal> pid </literal> Exim process id
+<literal> pipelining </literal> PIPELINING use, on <= and => lines
+<literal> proxy </literal> proxy address on <= and => lines
+<literal> receive_time </literal> time taken to receive message
+<literal> received_recipients </literal> recipients on <= lines
+<literal> received_sender </literal> sender on <= lines
+<literal>*rejected_header </literal> header contents on reject log
+<literal>*retry_defer </literal> <quote>retry time not reached</quote>
+<literal> return_path_on_delivery </literal> put return path on => and ** lines
+<literal> sender_on_delivery </literal> add sender to => lines
+<literal>*sender_verify_fail </literal> sender verification failures
+<literal>*size_reject </literal> rejection because too big
+<literal>*skip_delivery </literal> delivery skipped in a queue run
+<literal>*smtp_confirmation </literal> SMTP confirmation on => lines
+<literal> smtp_connection </literal> incoming SMTP connections
+<literal> smtp_incomplete_transaction</literal> incomplete SMTP transactions
+<literal> smtp_mailauth </literal> AUTH argument to MAIL commands
+<literal> smtp_no_mail </literal> session with no MAIL commands
+<literal> smtp_protocol_error </literal> SMTP protocol errors
+<literal> smtp_syntax_error </literal> SMTP syntax errors
+<literal> subject </literal> contents of <emphasis>Subject:</emphasis> on <= lines
+<literal>*tls_certificate_verified </literal> certificate verification status
+<literal>*tls_cipher </literal> TLS cipher suite on <= and => lines
+<literal> tls_peerdn </literal> TLS peer DN on <= and => lines
+<literal> tls_sni </literal> TLS SNI on <= lines
+<literal> unknown_in_list </literal> DNS lookup failed in list match
+
+<literal> all </literal> all of the above
+</literallayout>
+<para>
+See also the <option>slow_lookup_log</option> main configuration option,
+section <xref linkend="SECID99"/>
+</para>
+<para>
+More details on each of these items follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>8BITMIME</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>8BITMIME</secondary>
+</indexterm>
+<option>8bitmime</option>: This causes Exim to log any 8BITMIME status of received messages,
+which may help in tracking down interoperability issues with ancient MTAs
+that are not 8bit clean. This is added to the <quote><=</quote> line, tagged with
+<literal>M8S=</literal> and a value of <literal>0</literal>, <literal>7</literal> or <literal>8</literal>, corresponding to "not given",
+<literal>7BIT</literal> and <literal>8BITMIME</literal> respectively.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary><option>warn</option> ACL verb</primary>
+<secondary>log when skipping</secondary>
+</indexterm>
+<option>acl_warn_skipped</option>: When an ACL <option>warn</option> statement is skipped because one of
+its conditions cannot be evaluated, a log line to this effect is written if
+this log selector is set.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>rewriting</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>rewriting</primary>
+<secondary>logging</secondary>
+</indexterm>
+<option>address_rewrite</option>: This applies both to global rewrites and per-transport
+rewrites, but not to rewrites in filters run as an unprivileged user (because
+such users cannot access the log).
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>full parentage</secondary>
+</indexterm>
+<option>all_parents</option>: Normally only the original and final addresses are logged on
+delivery lines; with this selector, intermediate parents are given in
+parentheses between them.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>Exim arguments</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Exim arguments, logging</primary>
+</indexterm>
+<option>arguments</option>: This causes Exim to write the arguments with which it was called
+to the main log, preceded by the current working directory. This is a debugging
+feature, added to make it easier to find out how certain MUAs call
+<filename>/usr/sbin/sendmail</filename>. The logging does not happen if Exim has given up root
+privilege because it was called with the <option>-C</option> or <option>-D</option> options. Arguments
+that are empty or that contain white space are quoted. Non-printing characters
+are shown as escape sequences. This facility cannot log unrecognized arguments,
+because the arguments are checked before the configuration file is read. The
+only way to log such cases is to interpose a script such as <filename>util/logargs.sh</filename>
+between the caller and Exim.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>connection rejections</secondary>
+</indexterm>
+<option>connection_reject</option>: A log entry is written whenever an incoming SMTP
+connection is rejected, for whatever reason.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>delayed delivery</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>delayed delivery, logging</primary>
+</indexterm>
+<option>delay_delivery</option>: A log entry is written whenever a delivery process is not
+started for an incoming message because the load is too high or too many
+messages were received on one connection. Logging does not occur if no delivery
+process is started because <option>queue_only</option> is set or <option>-odq</option> was used.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>delivery duration</secondary>
+</indexterm>
+<option>deliver_time</option>: For each delivery, the amount of real time it has taken to
+perform the actual delivery is logged as DT=<<emphasis>time</emphasis>>, for example, <literal>DT=1s</literal>.
+If millisecond logging is enabled, short times will be shown with greater
+precision, eg. <literal>DT=0.304s</literal>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>message size on delivery</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>size</primary>
+<secondary>of message</secondary>
+</indexterm>
+<option>delivery_size</option>: For each delivery, the size of message delivered is added to
+the <quote>=></quote> line, tagged with S=.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>DKIM verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DKIM</primary>
+<secondary>verification logging</secondary>
+</indexterm>
+<option>dkim</option>: For message acceptance log lines, when an DKIM signature in the header
+verifies successfully a tag of DKIM is added, with one of the verified domains.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>DKIM verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DKIM</primary>
+<secondary>verification logging</secondary>
+</indexterm>
+<option>dkim_verbose</option>: A log entry is written for each attempted DKIM verification.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>dnslist defer</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS list</primary>
+<secondary>logging defer</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>black list (DNS)</primary>
+</indexterm>
+<option>dnslist_defer</option>: A log entry is written if an attempt to look up a host in a
+DNS black list suffers a temporary error.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>dnssec</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>dnssec</primary>
+<secondary>logging</secondary>
+</indexterm>
+<option>dnssec</option>: For message acceptance and (attempted) delivery log lines, when
+dns lookups gave secure results a tag of DS is added.
+For acceptance this covers the reverse and forward lookups for host name verification.
+It does not cover helo-name verification.
+For delivery this covers the SRV, MX, A and/or AAAA lookups.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>ETRN commands</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ETRN</primary>
+<secondary>logging</secondary>
+</indexterm>
+<option>etrn</option>: Every valid ETRN command that is received is logged, before the ACL
+is run to determine whether or not it is actually accepted. An invalid ETRN
+command, or one received within a message transaction is not logged by this
+selector (see <option>smtp_syntax_error</option> and <option>smtp_protocol_error</option>).
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>host lookup failure</secondary>
+</indexterm>
+<option>host_lookup_failed</option>: When a lookup of a host’s IP addresses fails to find
+any addresses, or when a lookup of an IP address fails to find a host name, a
+log line is written. This logging does not apply to direct DNS lookups when
+routing email addresses, but it does apply to <quote>byname</quote> lookups.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>ident timeout</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>RFC 1413</primary>
+<secondary>logging timeout</secondary>
+</indexterm>
+<option>ident_timeout</option>: A log line is written whenever an attempt to connect to a
+client’s ident port times out.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>incoming interface</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>local interface</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>local address and port</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP/IP</primary>
+<secondary>logging local address and port</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>interface</primary>
+<secondary>logging</secondary>
+</indexterm>
+<option>incoming_interface</option>: The interface on which a message was received is added
+to the <quote><=</quote> line as an IP address in square brackets, tagged by I= and
+followed by a colon and the port number. The local interface and port are also
+added to other SMTP log lines, for example, <quote>SMTP connection from</quote>, to
+rejection lines, and (despite the name) to outgoing <quote>=></quote> and <quote>-></quote> lines.
+The latter can be disabled by turning off the <option>outgoing_interface</option> option.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>incoming proxy address</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>proxy</primary>
+<secondary>logging proxy address</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP/IP</primary>
+<secondary>logging proxy address</secondary>
+</indexterm>
+<option>proxy</option>: The internal (closest to the system running Exim) IP address
+of the proxy, tagged by PRX=, on the <quote><=</quote> line for a message accepted
+on a proxied connection
+or the <quote>=></quote> line for a message delivered on a proxied connection.
+See <xref linkend="SECTproxyInbound"/> for more information.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>incoming remote port</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>port</primary>
+<secondary>logging remote</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP/IP</primary>
+<secondary>logging incoming remote port</secondary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$sender_fullhost</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><varname>$sender_rcvhost</varname></primary>
+</indexterm>
+<option>incoming_port</option>: The remote port number from which a message was received is
+added to log entries and <emphasis>Received:</emphasis> header lines, following the IP address
+in square brackets, and separated from it by a colon. This is implemented by
+changing the value that is put in the <varname>$sender_fullhost</varname> and
+<varname>$sender_rcvhost</varname> variables. Recording the remote port number has become more
+important with the widening use of NAT (see RFC 2505).
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>dropped connection</secondary>
+</indexterm>
+<option>lost_incoming_connection</option>: A log line is written when an incoming SMTP
+connection is unexpectedly dropped.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>millisecond timestamps</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>millisecond</primary>
+<secondary>logging</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>timestamps</primary>
+<secondary>millisecond, in logs</secondary>
+</indexterm>
+<option>millisec</option>: Timestamps have a period and three decimal places of finer granularity
+appended to the seconds value.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>message id</secondary>
+</indexterm>
+<option>msg_id</option>: The value of the Message-ID: header.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>msg_id_created</option>: The value of the Message-ID: header, when one had to be created.
+This will be either because the message is a bounce, or was submitted locally
+(submission mode) without one.
+The field identifier will have an asterix appended: <quote>id*=</quote>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>outgoing interface</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>local interface</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>local address and port</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP/IP</primary>
+<secondary>logging local address and port</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>interface</primary>
+<secondary>logging</secondary>
+</indexterm>
+<option>outgoing_interface</option>: If <option>incoming_interface</option> is turned on, then the
+interface on which a message was sent is added to delivery lines as an I= tag
+followed by IP address in square brackets. You can disable this by turning
+off the <option>outgoing_interface</option> option.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>outgoing remote port</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>port</primary>
+<secondary>logging outgoing remote</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TCP/IP</primary>
+<secondary>logging outgoing remote port</secondary>
+</indexterm>
+<option>outgoing_port</option>: The remote port number is added to delivery log lines (those
+containing => tags) following the IP address.
+The local port is also added if <option>incoming_interface</option> and
+<option>outgoing_interface</option> are both enabled.
+This option is not included in the default setting, because for most ordinary
+configurations, the remote port number is always 25 (the SMTP port), and the
+local port is a random ephemeral port.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>process ids in</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>pid (process id)</primary>
+<secondary>in log lines</secondary>
+</indexterm>
+<option>pid</option>: The current process id is added to every log line, in square brackets,
+immediately after the time and date.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>pipelining</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>pipelining</primary>
+<secondary>logging outgoing</secondary>
+</indexterm>
+<option>pipelining</option>: A field is added to delivery and accept
+log lines when the ESMTP PIPELINING extension was used.
+The field is a single "L".
+</para>
+<para>
+On accept lines, where PIPELINING was offered but not used by the client,
+the field has a minus appended.
+</para>
+<para>
+<indexterm role="concept">
+<primary>pipelining</primary>
+<secondary>early connection</secondary>
+</indexterm>
+If Exim is built with the SUPPORT_PIPE_CONNECT build option
+accept "L" fields have a period appended if the feature was
+offered but not used, or an asterisk appended if used.
+Delivery "L" fields have an asterisk appended if used.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>queue run</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue runner</primary>
+<secondary>logging</secondary>
+</indexterm>
+<option>queue_run</option>: The start and end of every queue run are logged.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>queue time</secondary>
+</indexterm>
+<option>queue_time</option>: The amount of time the message has been in the queue on the
+local host is logged as QT=<<emphasis>time</emphasis>> on delivery (<literal>=></literal>) lines, for example,
+<literal>QT=3m45s</literal>. The clock starts when Exim starts to receive the message, so it
+includes reception time as well as the delivery time for the current address.
+This means that it may be longer than the difference between the arrival and
+delivery log line times, because the arrival log line is not written until the
+message has been successfully received.
+If millisecond logging is enabled, short times will be shown with greater
+precision, eg. <literal>QT=1.578s</literal>.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>queue_time_overall</option>: The amount of time the message has been in the queue on
+the local host is logged as QT=<<emphasis>time</emphasis>> on <quote>Completed</quote> lines, for
+example, <literal>QT=3m45s</literal>. The clock starts when Exim starts to receive the
+message, so it includes reception time as well as the total delivery time.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>receive duration</secondary>
+</indexterm>
+<option>receive_time</option>: For each message, the amount of real time it has taken to
+perform the reception is logged as RT=<<emphasis>time</emphasis>>, for example, <literal>RT=1s</literal>.
+If millisecond logging is enabled, short times will be shown with greater
+precision, eg. <literal>RT=0.204s</literal>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>recipients</secondary>
+</indexterm>
+<option>received_recipients</option>: The recipients of a message are listed in the main log
+as soon as the message is received. The list appears at the end of the log line
+that is written when a message is received, preceded by the word <quote>for</quote>. The
+addresses are listed after they have been qualified, but before any rewriting
+has taken place.
+Recipients that were discarded by an ACL for MAIL or RCPT do not appear
+in the list.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>sender reception</secondary>
+</indexterm>
+<option>received_sender</option>: The unrewritten original sender of a message is added to
+the end of the log line that records the message’s arrival, after the word
+<quote>from</quote> (before the recipients if <option>received_recipients</option> is also set).
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>header lines for rejection</secondary>
+</indexterm>
+<option>rejected_header</option>: If a message’s header has been received at the time a
+rejection is written to the reject log, the complete header is added to the
+log. Header logging can be turned off individually for messages that are
+rejected by the <function>local_scan()</function> function (see section <xref linkend="SECTapiforloc"/>).
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>retry defer</secondary>
+</indexterm>
+<option>retry_defer</option>: A log line is written if a delivery is deferred because a
+retry time has not yet been reached. However, this <quote>retry time not reached</quote>
+message is always omitted from individual message logs after the first delivery
+attempt.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>return path</secondary>
+</indexterm>
+<option>return_path_on_delivery</option>: The return path that is being transmitted with
+the message is included in delivery and bounce lines, using the tag P=.
+This is omitted if no delivery actually happens, for example, if routing fails,
+or if delivery is to <filename>/dev/null</filename> or to <literal>:blackhole:</literal>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>sender on delivery</secondary>
+</indexterm>
+<option>sender_on_delivery</option>: The message’s sender address is added to every delivery
+and bounce line, tagged by F= (for <quote>from</quote>).
+This is the original sender that was received with the message; it is not
+necessarily the same as the outgoing return path.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>sender verify failure</secondary>
+</indexterm>
+<option>sender_verify_fail</option>: If this selector is unset, the separate log line that
+gives details of a sender verification failure is not written. Log lines for
+the rejection of SMTP commands contain just <quote>sender verify failed</quote>, so some
+detail is lost.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>size rejection</secondary>
+</indexterm>
+<option>size_reject</option>: A log line is written whenever a message is rejected because
+it is too big.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>frozen messages; skipped</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>logging skipping</secondary>
+</indexterm>
+<option>skip_delivery</option>: A log line is written whenever a message is skipped during a
+queue run because it is frozen or because another process is already delivering
+it.
+<indexterm role="concept">
+<primary><quote>spool file is locked</quote></primary>
+</indexterm>
+The message that is written is <quote>spool file is locked</quote>.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>smtp confirmation</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>logging confirmation</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>LMTP</primary>
+<secondary>logging confirmation</secondary>
+</indexterm>
+<option>smtp_confirmation</option>: The response to the final <quote>.</quote> in the SMTP or LMTP dialogue for
+outgoing messages is added to delivery log lines in the form <literal>C=</literal><<emphasis>text</emphasis>>.
+A number of MTAs (including Exim) return an identifying string in this
+response.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>SMTP connections</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>logging connections</secondary>
+</indexterm>
+<option>smtp_connection</option>: A log line is written whenever an incoming SMTP connection is
+established or closed, unless the connection is from a host that matches
+<option>hosts_connection_nolog</option>. (In contrast, <option>lost_incoming_connection</option> applies
+only when the closure is unexpected.) This applies to connections from local
+processes that use <option>-bs</option> as well as to TCP/IP connections. If a connection is
+dropped in the middle of a message, a log line is always written, whether or
+not this selector is set, but otherwise nothing is written at the start and end
+of connections unless this selector is enabled.
+</para>
+<para>
+For TCP/IP connections to an Exim daemon, the current number of connections is
+included in the log message for each new connection, but note that the count is
+reset if the daemon is restarted.
+Also, because connections are closed (and the closure is logged) in
+subprocesses, the count may not include connections that have been closed but
+whose termination the daemon has not yet noticed. Thus, while it is possible to
+match up the opening and closing of connections in the log, the value of the
+logged counts may not be entirely accurate.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>SMTP transaction; incomplete</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>logging incomplete transactions</secondary>
+</indexterm>
+<option>smtp_incomplete_transaction</option>: When a mail transaction is aborted by
+RSET, QUIT, loss of connection, or otherwise, the incident is logged,
+and the message sender plus any accepted recipients are included in the log
+line. This can provide evidence of dictionary attacks.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>non-MAIL SMTP sessions</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>MAIL</primary>
+<secondary>logging session without</secondary>
+</indexterm>
+<option>smtp_no_mail</option>: A line is written to the main log whenever an accepted SMTP
+connection terminates without having issued a MAIL command. This includes both
+the case when the connection is dropped, and the case when QUIT is used. It
+does not include cases where the connection is rejected right at the start (by
+an ACL, or because there are too many connections, or whatever). These cases
+already have their own log lines.
+</para>
+<para>
+The log line that is written contains the identity of the client in the usual
+way, followed by D= and a time, which records the duration of the connection.
+If the connection was authenticated, this fact is logged exactly as it is for
+an incoming message, with an A= item. If the connection was encrypted, CV=,
+DN=, and X= items may appear as they do for an incoming message, controlled by
+the same logging options.
+</para>
+<para>
+Finally, if any SMTP commands were issued during the connection, a C= item
+is added to the line, listing the commands that were used. For example,
+</para>
+<literallayout class="monospaced">
+C=EHLO,QUIT
+</literallayout>
+<para>
+shows that the client issued QUIT straight after EHLO. If there were fewer
+than 20 commands, they are all listed. If there were more than 20 commands,
+the last 20 are listed, preceded by <quote>...</quote>. However, with the default
+setting of 10 for <option>smtp_accept_max_nonmail</option>, the connection will in any case
+have been aborted before 20 non-mail commands are processed.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>smtp_mailauth</option>: A third subfield with the authenticated sender,
+colon-separated, is appended to the A= item for a message arrival or delivery
+log line, if an AUTH argument to the SMTP MAIL command (see <xref linkend="SECTauthparamail"/>)
+was accepted or used.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>SMTP protocol error</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>logging protocol error</secondary>
+</indexterm>
+<option>smtp_protocol_error</option>: A log line is written for every SMTP protocol error
+encountered. Exim does not have perfect detection of all protocol errors
+because of transmission delays and the use of pipelining. If PIPELINING has
+been advertised to a client, an Exim server assumes that the client will use
+it, and therefore it does not count <quote>expected</quote> errors (for example, RCPT
+received after rejecting MAIL) as protocol errors.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>logging syntax errors</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>syntax errors; logging</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTP</primary>
+<secondary>unknown command; logging</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>unknown SMTP command</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>SMTP syntax error</secondary>
+</indexterm>
+<option>smtp_syntax_error</option>: A log line is written for every SMTP syntax error
+encountered. An unrecognized command is treated as a syntax error. For an
+external connection, the host identity is given; for an internal connection
+using <option>-bs</option> the sender identification (normally the calling user) is given.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>subject</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>subject, logging</primary>
+</indexterm>
+<option>subject</option>: The subject of the message is added to the arrival log line,
+preceded by <quote>T=</quote> (T for <quote>topic</quote>, since S is already used for <quote>size</quote>).
+Any MIME <quote>words</quote> in the subject are decoded. The <option>print_topbitchars</option> option
+specifies whether characters with values greater than 127 should be logged
+unchanged, or whether they should be rendered as escape sequences.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>certificate verification</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>DANE</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>DANE</primary>
+<secondary>logging</secondary>
+</indexterm>
+<option>tls_certificate_verified</option>: An extra item is added to <= and => log lines
+when TLS is in use. The item is <literal>CV=yes</literal> if the peer’s certificate was
+verified
+using a CA trust anchor,
+<literal>CA=dane</literal> if using a DNS trust anchor,
+and <literal>CV=no</literal> if not.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>TLS cipher</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>logging cipher</secondary>
+</indexterm>
+<option>tls_cipher</option>: When a message is sent or received over an encrypted
+connection, the cipher suite used is added to the log line, preceded by X=.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>TLS peer DN</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>logging peer DN</secondary>
+</indexterm>
+<option>tls_peerdn</option>: When a message is sent or received over an encrypted
+connection, and a certificate is supplied by the remote host, the peer DN is
+added to the log line, preceded by DN=.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>TLS SNI</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>TLS</primary>
+<secondary>logging SNI</secondary>
+</indexterm>
+<option>tls_sni</option>: When a message is received over an encrypted connection, and
+the remote host provided the Server Name Indication extension, the SNI is
+added to the log line, preceded by SNI=.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>DNS failure in list</secondary>
+</indexterm>
+<option>unknown_in_list</option>: This setting causes a log entry to be written when the
+result of a list match is failure because a DNS lookup failed.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID260">
+<title>Message log</title>
+<para>
+<indexterm role="concept">
+<primary>message</primary>
+<secondary>log file for</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>message log; description of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><filename>msglog</filename> directory</primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>preserve_message_logs</option></primary>
+</indexterm>
+In addition to the general log files, Exim writes a log file for each message
+that it handles. The names of these per-message logs are the message ids, and
+they are kept in the <filename>msglog</filename> sub-directory of the spool directory. Each
+message log contains copies of the log lines that apply to the message. This
+makes it easier to inspect the status of an individual message without having
+to search the main log. A message log is deleted when processing of the message
+is complete, unless <option>preserve_message_logs</option> is set, but this should be used
+only with great care because they can fill up your disk very quickly.
+</para>
+<para>
+On a heavily loaded system, it may be desirable to disable the use of
+per-message logs, in order to reduce disk I/O. This can be done by setting the
+<option>message_logs</option> option false.
+<indexterm role="concept" startref="IIDloggen" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPutils">
+<title>Exim utilities</title>
+<para>
+<indexterm role="concept" id="IIDutils" class="startofrange">
+<primary>utilities</primary>
+</indexterm>
+A number of utility scripts and programs are supplied with Exim and are
+described in this chapter. There is also the Exim Monitor, which is covered in
+the next chapter. The utilities described here are:
+</para>
+<informaltable frame="none">
+<tgroup cols="3" colsep="0" rowsep="0">
+<colspec colwidth="7*" align="left"/>
+<colspec colwidth="15*" align="left"/>
+<colspec colwidth="40*" align="left"/>
+<tbody>
+<row>
+<entry> <xref linkend="SECTfinoutwha"/></entry>
+<entry><emphasis>exiwhat</emphasis></entry>
+<entry>list what Exim processes are doing</entry>
+</row>
+<row>
+<entry> <xref linkend="SECTgreptheque"/></entry>
+<entry><emphasis>exiqgrep</emphasis></entry>
+<entry>grep the queue</entry>
+</row>
+<row>
+<entry> <xref linkend="SECTsumtheque"/></entry>
+<entry><emphasis>exiqsumm</emphasis></entry>
+<entry>summarize the queue</entry>
+</row>
+<row>
+<entry> <xref linkend="SECTextspeinf"/></entry>
+<entry><emphasis>exigrep</emphasis></entry>
+<entry>search the main log</entry>
+</row>
+<row>
+<entry> <xref linkend="SECTexipick"/></entry>
+<entry><emphasis>exipick</emphasis></entry>
+<entry>select messages on various criteria</entry>
+</row>
+<row>
+<entry> <xref linkend="SECTcyclogfil"/></entry>
+<entry><emphasis>exicyclog</emphasis></entry>
+<entry>cycle (rotate) log files</entry>
+</row>
+<row>
+<entry> <xref linkend="SECTmailstat"/></entry>
+<entry><emphasis>eximstats</emphasis></entry>
+<entry>extract statistics from the log</entry>
+</row>
+<row>
+<entry> <xref linkend="SECTcheckaccess"/></entry>
+<entry><emphasis>exim_checkaccess</emphasis></entry>
+<entry>check address acceptance from given IP</entry>
+</row>
+<row>
+<entry> <xref linkend="SECTdbmbuild"/></entry>
+<entry><emphasis>exim_dbmbuild</emphasis></entry>
+<entry>build a DBM file</entry>
+</row>
+<row>
+<entry> <xref linkend="SECTfinindret"/></entry>
+<entry><emphasis>exinext</emphasis></entry>
+<entry>extract retry information</entry>
+</row>
+<row>
+<entry> <xref linkend="SECThindatmai"/></entry>
+<entry><emphasis>exim_dumpdb</emphasis></entry>
+<entry>dump a hints database</entry>
+</row>
+<row>
+<entry> <xref linkend="SECThindatmai"/></entry>
+<entry><emphasis>exim_tidydb</emphasis></entry>
+<entry>clean up a hints database</entry>
+</row>
+<row>
+<entry> <xref linkend="SECThindatmai"/></entry>
+<entry><emphasis>exim_fixdb</emphasis></entry>
+<entry>patch a hints database</entry>
+</row>
+<row>
+<entry> <xref linkend="SECTmailboxmaint"/></entry>
+<entry><emphasis>exim_lock</emphasis></entry>
+<entry>lock a mailbox file</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Another utility that might be of use to sites with many MTAs is Tom Kistner’s
+<emphasis>exilog</emphasis>. It provides log visualizations across multiple Exim servers. See
+<emphasis role="bold"><ulink url="https://duncanthrax.net/exilog/">https://duncanthrax.net/exilog/</ulink></emphasis> for details.
+</para>
+<section id="SECTfinoutwha">
+<title>Finding out what Exim processes are doing (exiwhat)</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>exiwhat</emphasis></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>process, querying</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>SIGUSR1</primary>
+</indexterm>
+On operating systems that can restart a system call after receiving a signal
+(most modern OS), an Exim process responds to the SIGUSR1 signal by writing
+a line describing what it is doing to the file <filename>exim-process.info</filename> in the
+Exim spool directory. The <emphasis>exiwhat</emphasis> script sends the signal to all Exim
+processes it can find, having first emptied the file. It then waits for one
+second to allow the Exim processes to react before displaying the results. In
+order to run <emphasis>exiwhat</emphasis> successfully you have to have sufficient privilege to
+send the signal to the Exim processes, so it is normally run as root.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: This is not an efficient process. It is intended for occasional
+use by system administrators. It is not sensible, for example, to set up a
+script that sends SIGUSR1 signals to Exim processes at short intervals.
+</para>
+<para>
+Unfortunately, the <emphasis>ps</emphasis> command that <emphasis>exiwhat</emphasis> uses to find Exim processes
+varies in different operating systems. Not only are different options used,
+but the format of the output is different. For this reason, there are some
+system configuration options that configure exactly how <emphasis>exiwhat</emphasis> works. If
+it doesn’t seem to be working for you, check the following compile-time
+options:
+</para>
+<literallayout>
+<literal>EXIWHAT_PS_CMD </literal> the command for running <emphasis>ps</emphasis>
+<literal>EXIWHAT_PS_ARG </literal> the argument for <emphasis>ps</emphasis>
+<literal>EXIWHAT_EGREP_ARG </literal> the argument for <emphasis>egrep</emphasis> to select from <emphasis>ps</emphasis> output
+<literal>EXIWHAT_KILL_ARG </literal> the argument for the <emphasis>kill</emphasis> command
+</literallayout>
+<para>
+An example of typical output from <emphasis>exiwhat</emphasis> is
+</para>
+<literallayout class="monospaced">
+164 daemon: -q1h, listening on port 25
+10483 running queue: waiting for 0tAycK-0002ij-00 (10492)
+10492 delivering 0tAycK-0002ij-00 to mail.ref.example
+ [10.19.42.42] (editor@ref.example)
+10592 handling incoming call from [192.168.243.242]
+10628 accepting a local non-SMTP message
+</literallayout>
+<para>
+The first number in the output line is the process number. The third line has
+been split here, in order to fit it on the page.
+</para>
+</section>
+<section id="SECTgreptheque">
+<title>Selective queue listing (exiqgrep)</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>exiqgrep</emphasis></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>grepping</secondary>
+</indexterm>
+This utility is a Perl script contributed by Matt Hubbard. It runs
+</para>
+<literallayout class="monospaced">
+exim -bpu
+</literallayout>
+<para>
+or (in case <emphasis role="bold">-a</emphasis> switch is specified)
+</para>
+<literallayout class="monospaced">
+exim -bp
+</literallayout>
+<para>
+The <emphasis role="bold">-C</emphasis> option is used to specify an alternate <filename>exim.conf</filename> which might
+contain alternate exim configuration the queue management might be using.
+</para>
+<para>
+to obtain a queue listing, and then greps the output to select messages
+that match given criteria. The following selection options are available:
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">-f</emphasis> <<emphasis>regex</emphasis>></term>
+<listitem>
+<para>
+Match the sender address using a case-insensitive search. The field that is
+tested is enclosed in angle brackets, so you can test for bounce messages with
+</para>
+<literallayout class="monospaced">
+exiqgrep -f '^<>$'
+</literallayout>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">-r</emphasis> <<emphasis>regex</emphasis>></term>
+<listitem>
+<para>
+Match a recipient address using a case-insensitive search. The field that is
+tested is not enclosed in angle brackets.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">-s</emphasis> <<emphasis>regex</emphasis>></term>
+<listitem>
+<para>
+Match against the size field.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">-y</emphasis> <<emphasis>seconds</emphasis>></term>
+<listitem>
+<para>
+Match messages that are younger than the given time.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">-o</emphasis> <<emphasis>seconds</emphasis>></term>
+<listitem>
+<para>
+Match messages that are older than the given time.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">-z</emphasis></term>
+<listitem>
+<para>
+Match only frozen messages.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">-x</emphasis></term>
+<listitem>
+<para>
+Match only non-frozen messages.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">-G</emphasis> <<emphasis>queuename</emphasis>></term>
+<listitem>
+<para>
+Match only messages in the given queue. Without this, the default queue is searched.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+The following options control the format of the output:
+</para>
+<variablelist>
+<varlistentry>
+<term><emphasis role="bold">-c</emphasis></term>
+<listitem>
+<para>
+Display only the count of matching messages.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">-l</emphasis></term>
+<listitem>
+<para>
+Long format – display the full message information as output by Exim. This is
+the default.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">-i</emphasis></term>
+<listitem>
+<para>
+Display message ids only.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">-b</emphasis></term>
+<listitem>
+<para>
+Brief format – one line per message.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">-R</emphasis></term>
+<listitem>
+<para>
+Display messages in reverse order.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><emphasis role="bold">-a</emphasis></term>
+<listitem>
+<para>
+Include delivered recipients in queue listing.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+There is one more option, <option>-h</option>, which outputs a list of options.
+</para>
+</section>
+<section id="SECTsumtheque">
+<title>Summarizing the queue (exiqsumm)</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>exiqsumm</emphasis></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>summary</secondary>
+</indexterm>
+The <emphasis>exiqsumm</emphasis> utility is a Perl script which reads the output of <literal>exim
+-bp</literal> and produces a summary of the messages in the queue. Thus, you use it by
+running a command such as
+</para>
+<literallayout class="monospaced">
+exim -bp | exiqsumm
+</literallayout>
+<para>
+The output consists of one line for each domain that has messages waiting for
+it, as in the following example:
+</para>
+<literallayout class="monospaced">
+3 2322 74m 66m msn.com.example
+</literallayout>
+<para>
+Each line lists the number of pending deliveries for a domain, their total
+volume, and the length of time that the oldest and the newest messages have
+been waiting. Note that the number of pending deliveries is greater than the
+number of messages when messages have more than one recipient.
+</para>
+<para>
+A summary line is output at the end. By default the output is sorted on the
+domain name, but <emphasis>exiqsumm</emphasis> has the options <option>-a</option> and <option>-c</option>, which cause
+the output to be sorted by oldest message and by count of messages,
+respectively. There are also three options that split the messages for each
+domain into two or more subcounts: <option>-b</option> separates bounce messages, <option>-f</option>
+separates frozen messages, and <option>-s</option> separates messages according to their
+sender.
+</para>
+<para>
+The output of <emphasis>exim -bp</emphasis> contains the original addresses in the message, so
+this also applies to the output from <emphasis>exiqsumm</emphasis>. No domains from addresses
+generated by aliasing or forwarding are included (unless the <option>one_time</option>
+option of the <command>redirect</command> router has been used to convert them into <quote>top
+level</quote> addresses).
+</para>
+</section>
+<section id="SECTextspeinf">
+<title>Extracting specific information from the log (exigrep)</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>exigrep</emphasis></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>extracts; grepping for</secondary>
+</indexterm>
+The <emphasis>exigrep</emphasis> utility is a Perl script that searches one or more main log
+files for entries that match a given pattern. When it finds a match, it
+extracts all the log entries for the relevant message, not just those that
+match the pattern. Thus, <emphasis>exigrep</emphasis> can extract complete log entries for a
+given message, or all mail for a given user, or for a given host, for example.
+The input files can be in Exim log format or syslog format.
+If a matching log line is not associated with a specific message, it is
+included in <emphasis>exigrep</emphasis>’s output without any additional lines. The usage is:
+</para>
+<literallayout>
+<literal>exigrep [-t<</literal><emphasis>n</emphasis><literal>>] [-I] [-l] [-M] [-v] <</literal><emphasis>pattern</emphasis><literal>> [<</literal><emphasis>log file</emphasis><literal>>] ...</literal>
+</literallayout>
+<para>
+If no log filenames are given on the command line, the standard input is read.
+</para>
+<para>
+The <option>-t</option> argument specifies a number of seconds. It adds an additional
+condition for message selection. Messages that are complete are shown only if
+they spent more than <<emphasis>n</emphasis>> seconds in the queue.
+</para>
+<para>
+By default, <emphasis>exigrep</emphasis> does case-insensitive matching. The <option>-I</option> option
+makes it case-sensitive. This may give a performance improvement when searching
+large log files. Without <option>-I</option>, the Perl pattern matches use Perl’s <literal>/i</literal>
+option; with <option>-I</option> they do not. In both cases it is possible to change the
+case sensitivity within the pattern by using <literal>(?i)</literal> or <literal>(?-i)</literal>.
+</para>
+<para>
+The <option>-l</option> option means <quote>literal</quote>, that is, treat all characters in the
+pattern as standing for themselves. Otherwise the pattern must be a Perl
+regular expression.
+</para>
+<para>
+The <option>-v</option> option inverts the matching condition. That is, a line is selected
+if it does <emphasis>not</emphasis> match the pattern.
+</para>
+<para>
+The <option>-M</option> options means <quote>related messages</quote>. <emphasis>exigrep</emphasis> will show messages
+that are generated as a result/response to a message that <emphasis>exigrep</emphasis> matched
+normally.
+</para>
+<para>
+Example of <option>-M</option>:
+user_a sends a message to user_b, which generates a bounce back to user_b. If
+<emphasis>exigrep</emphasis> is used to search for <quote>user_a</quote>, only the first message will be
+displayed. But if <emphasis>exigrep</emphasis> is used to search for <quote>user_b</quote>, the first and
+the second (bounce) message will be displayed. Using <option>-M</option> with <emphasis>exigrep</emphasis>
+when searching for <quote>user_a</quote> will show both messages since the bounce is
+<quote>related</quote> to or a <quote>result</quote> of the first message that was found by the
+search term.
+</para>
+<para>
+If the location of a <emphasis>zcat</emphasis> command is known from the definition of
+ZCAT_COMMAND in <filename>Local/Makefile</filename>, <emphasis>exigrep</emphasis> automatically passes any file
+whose name ends in COMPRESS_SUFFIX through <emphasis>zcat</emphasis> as it searches it.
+If the ZCAT_COMMAND is not executable, <emphasis>exigrep</emphasis> tries to use
+autodetection of some well known compression extensions.
+</para>
+</section>
+<section id="SECTexipick">
+<title>Selecting messages by various criteria (exipick)</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>exipick</emphasis></primary>
+</indexterm>
+John Jetmore’s <emphasis>exipick</emphasis> utility is included in the Exim distribution. It
+lists messages from the queue according to a variety of criteria. For details
+of <emphasis>exipick</emphasis>’s facilities, run <emphasis>exipick</emphasis> with
+the <option>--help</option> option.
+</para>
+</section>
+<section id="SECTcyclogfil">
+<title>Cycling log files (exicyclog)</title>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>cycling local files</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>cycling logs</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>exicyclog</emphasis></primary>
+</indexterm>
+The <emphasis>exicyclog</emphasis> script can be used to cycle (rotate) <emphasis>mainlog</emphasis> and
+<emphasis>rejectlog</emphasis> files. This is not necessary if only syslog is being used, or if
+you are using log files with datestamps in their names (see section
+<xref linkend="SECTdatlogfil"/>). Some operating systems have their own standard mechanisms
+for log cycling, and these can be used instead of <emphasis>exicyclog</emphasis> if preferred.
+There are two command line options for <emphasis>exicyclog</emphasis>:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<option>-k</option> <<emphasis>count</emphasis>> specifies the number of log files to keep, overriding the
+default that is set when Exim is built. The default default is 10.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>-l</option> <<emphasis>path</emphasis>> specifies the log file path, in the same format as Exim’s
+<option>log_file_path</option> option (for example, <literal>/var/log/exim_%slog</literal>), again
+overriding the script’s default, which is to find the setting from Exim’s
+configuration.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Each time <emphasis>exicyclog</emphasis> is run the filenames get <quote>shuffled down</quote> by one. If
+the main log filename is <filename>mainlog</filename> (the default) then when <emphasis>exicyclog</emphasis> is
+run <filename>mainlog</filename> becomes <filename>mainlog.01</filename>, the previous <filename>mainlog.01</filename> becomes
+<filename>mainlog.02</filename> and so on, up to the limit that is set in the script or by the
+<option>-k</option> option. Log files whose numbers exceed the limit are discarded. Reject
+logs are handled similarly.
+</para>
+<para>
+If the limit is greater than 99, the script uses 3-digit numbers such as
+<filename>mainlog.001</filename>, <filename>mainlog.002</filename>, etc. If you change from a number less than 99
+to one that is greater, or <emphasis>vice versa</emphasis>, you will have to fix the names of
+any existing log files.
+</para>
+<para>
+If no <filename>mainlog</filename> file exists, the script does nothing. Files that <quote>drop off</quote>
+the end are deleted. All files with numbers greater than 01 are compressed,
+using a compression command which is configured by the COMPRESS_COMMAND
+setting in <filename>Local/Makefile</filename>. It is usual to run <emphasis>exicyclog</emphasis> daily from a
+root <option>crontab</option> entry of the form
+</para>
+<literallayout class="monospaced">
+1 0 * * * su exim -c /usr/exim/bin/exicyclog
+</literallayout>
+<para>
+assuming you have used the name <quote>exim</quote> for the Exim user. You can run
+<emphasis>exicyclog</emphasis> as root if you wish, but there is no need.
+</para>
+</section>
+<section id="SECTmailstat">
+<title>Mail statistics (eximstats)</title>
+<para>
+<indexterm role="concept">
+<primary>statistics</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>eximstats</emphasis></primary>
+</indexterm>
+A Perl script called <emphasis>eximstats</emphasis> is provided for extracting statistical
+information from log files. The output is either plain text, or HTML.
+</para>
+<para>
+The <emphasis>eximstats</emphasis> script has been hacked about quite a bit over time. The
+latest version is the result of some extensive revision by Steve Campbell. A
+lot of information is given by default, but there are options for suppressing
+various parts of it. Following any options, the arguments to the script are a
+list of files, which should be main log files. For example:
+</para>
+<literallayout class="monospaced">
+eximstats -nr /var/spool/exim/log/mainlog.01
+</literallayout>
+<para>
+By default, <emphasis>eximstats</emphasis> extracts information about the number and volume of
+messages received from or delivered to various hosts. The information is sorted
+both by message count and by volume, and the top fifty hosts in each category
+are listed on the standard output. Similar information, based on email
+addresses or domains instead of hosts can be requested by means of various
+options. For messages delivered and received locally, similar statistics are
+also produced per user.
+</para>
+<para>
+The output also includes total counts and statistics about delivery errors, and
+histograms showing the number of messages received and deliveries made in each
+hour of the day. A delivery with more than one address in its envelope (for
+example, an SMTP transaction with more than one RCPT command) is counted
+as a single delivery by <emphasis>eximstats</emphasis>.
+</para>
+<para>
+Though normally more deliveries than receipts are reported (as messages may
+have multiple recipients), it is possible for <emphasis>eximstats</emphasis> to report more
+messages received than delivered, even though the queue is empty at the start
+and end of the period in question. If an incoming message contains no valid
+recipients, no deliveries are recorded for it. A bounce message is handled as
+an entirely separate message.
+</para>
+<para>
+<emphasis>eximstats</emphasis> always outputs a grand total summary giving the volume and number
+of messages received and deliveries made, and the number of hosts involved in
+each case. It also outputs the number of messages that were delayed (that is,
+not completely delivered at the first attempt), and the number that had at
+least one address that failed.
+</para>
+<para>
+The remainder of the output is in sections that can be independently disabled
+or modified by various options. It consists of a summary of deliveries by
+transport, histograms of messages received and delivered per time interval
+(default per hour), information about the time messages spent in the queue,
+a list of relayed messages, lists of the top fifty sending hosts, local
+senders, destination hosts, and destination local users by count and by volume,
+and a list of delivery errors that occurred.
+</para>
+<para>
+The relay information lists messages that were actually relayed, that is, they
+came from a remote host and were directly delivered to some other remote host,
+without being processed (for example, for aliasing or forwarding) locally.
+</para>
+<para>
+There are quite a few options for <emphasis>eximstats</emphasis> to control exactly what it
+outputs. These are documented in the Perl script itself, and can be extracted
+by running the command <command>perldoc</command> on the script. For example:
+</para>
+<literallayout class="monospaced">
+perldoc /usr/exim/bin/eximstats
+</literallayout>
+</section>
+<section id="SECTcheckaccess">
+<title>Checking access policy (exim_checkaccess)</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>exim_checkaccess</emphasis></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>policy control</primary>
+<secondary>checking access</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>checking access</primary>
+</indexterm>
+The <option>-bh</option> command line argument allows you to run a fake SMTP session with
+debugging output, in order to check what Exim is doing when it is applying
+policy controls to incoming SMTP mail. However, not everybody is sufficiently
+familiar with the SMTP protocol to be able to make full use of <option>-bh</option>, and
+sometimes you just want to answer the question <quote>Does this address have
+access?</quote> without bothering with any further details.
+</para>
+<para>
+The <emphasis>exim_checkaccess</emphasis> utility is a <quote>packaged</quote> version of <option>-bh</option>. It takes
+two arguments, an IP address and an email address:
+</para>
+<literallayout class="monospaced">
+exim_checkaccess 10.9.8.7 A.User@a.domain.example
+</literallayout>
+<para>
+The utility runs a call to Exim with the <option>-bh</option> option, to test whether the
+given email address would be accepted in a RCPT command in a TCP/IP
+connection from the host with the given IP address. The output of the utility
+is either the word <quote>accepted</quote>, or the SMTP error response, for example:
+</para>
+<literallayout class="monospaced">
+Rejected:
+550 Relay not permitted
+</literallayout>
+<para>
+When running this test, the utility uses <literal><></literal> as the envelope sender address
+for the MAIL command, but you can change this by providing additional
+options. These are passed directly to the Exim command. For example, to specify
+that the test is to be run with the sender address <emphasis>himself@there.example</emphasis>
+you can use:
+</para>
+<literallayout class="monospaced">
+exim_checkaccess 10.9.8.7 A.User@a.domain.example \
+ -f himself@there.example
+</literallayout>
+<para>
+Note that these additional Exim command line items must be given after the two
+mandatory arguments.
+</para>
+<para>
+Because the <option>exim_checkaccess</option> uses <option>-bh</option>, it does not perform callouts
+while running its checks. You can run checks that include callouts by using
+<option>-bhc</option>, but this is not yet available in a <quote>packaged</quote> form.
+</para>
+</section>
+<section id="SECTdbmbuild">
+<title>Making DBM files (exim_dbmbuild)</title>
+<para>
+<indexterm role="concept">
+<primary>DBM</primary>
+<secondary>building dbm files</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>building DBM files</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>exim_dbmbuild</emphasis></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>lower casing</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>binary zero</primary>
+<secondary>in lookup key</secondary>
+</indexterm>
+The <emphasis>exim_dbmbuild</emphasis> program reads an input file containing keys and data in
+the format used by the <command>lsearch</command> lookup (see section
+<xref linkend="SECTsinglekeylookups"/>). It writes a DBM file using the lower-cased alias
+names as keys and the remainder of the information as data. The lower-casing
+can be prevented by calling the program with the <option>-nolc</option> option.
+</para>
+<para>
+A terminating zero is included as part of the key string. This is expected by
+the <command>dbm</command> lookup type. However, if the option <option>-nozero</option> is given,
+<emphasis>exim_dbmbuild</emphasis> creates files without terminating zeroes in either the key
+strings or the data strings. The <command>dbmnz</command> lookup type can be used with such
+files.
+</para>
+<para>
+The program requires two arguments: the name of the input file (which can be a
+single hyphen to indicate the standard input), and the name of the output file.
+It creates the output under a temporary name, and then renames it if all went
+well.
+</para>
+<para>
+<indexterm role="concept">
+<primary>USE_DB</primary>
+</indexterm>
+If the native DB interface is in use (USE_DB is set in a compile-time
+configuration file – this is common in free versions of Unix) the two
+filenames must be different, because in this mode the Berkeley DB functions
+create a single output file using exactly the name given. For example,
+</para>
+<literallayout class="monospaced">
+exim_dbmbuild /etc/aliases /etc/aliases.db
+</literallayout>
+<para>
+reads the system alias file and creates a DBM version of it in
+<filename>/etc/aliases.db</filename>.
+</para>
+<para>
+In systems that use the <emphasis>ndbm</emphasis> routines (mostly proprietary versions of
+Unix), two files are used, with the suffixes <filename>.dir</filename> and <filename>.pag</filename>. In this
+environment, the suffixes are added to the second argument of
+<emphasis>exim_dbmbuild</emphasis>, so it can be the same as the first. This is also the case
+when the Berkeley functions are used in compatibility mode (though this is not
+recommended), because in that case it adds a <filename>.db</filename> suffix to the filename.
+</para>
+<para>
+If a duplicate key is encountered, the program outputs a warning, and when it
+finishes, its return code is 1 rather than zero, unless the <option>-noduperr</option>
+option is used. By default, only the first of a set of duplicates is used –
+this makes it compatible with <command>lsearch</command> lookups. There is an option
+<option>-lastdup</option> which causes it to use the data for the last duplicate instead.
+There is also an option <option>-nowarn</option>, which stops it listing duplicate keys to
+<option>stderr</option>. For other errors, where it doesn’t actually make a new file, the
+return code is 2.
+</para>
+</section>
+<section id="SECTfinindret">
+<title>Finding individual retry times (exinext)</title>
+<para>
+<indexterm role="concept">
+<primary>retry</primary>
+<secondary>times</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>exinext</emphasis></primary>
+</indexterm>
+A utility called <emphasis>exinext</emphasis> (mostly a Perl script) provides the ability to
+fish specific information out of the retry database. Given a mail domain (or a
+complete address), it looks up the hosts for that domain, and outputs any retry
+information for the hosts or for the domain. At present, the retry information
+is obtained by running <emphasis>exim_dumpdb</emphasis> (see below) and post-processing the
+output. For example:
+</para>
+<literallayout class="monospaced">
+$ exinext piglet@milne.fict.example
+kanga.milne.example:192.168.8.1 error 146: Connection refused
+ first failed: 21-Feb-1996 14:57:34
+ last tried: 21-Feb-1996 14:57:34
+ next try at: 21-Feb-1996 15:02:34
+roo.milne.example:192.168.8.3 error 146: Connection refused
+ first failed: 20-Jan-1996 13:12:08
+ last tried: 21-Feb-1996 11:42:03
+ next try at: 21-Feb-1996 19:42:03
+ past final cutoff time
+</literallayout>
+<para>
+You can also give <emphasis>exinext</emphasis> a local part, without a domain, and it
+will give any retry information for that local part in your default domain.
+A message id can be used to obtain retry information pertaining to a specific
+message. This exists only when an attempt to deliver a message to a remote host
+suffers a message-specific error (see section <xref linkend="SECToutSMTPerr"/>).
+<emphasis>exinext</emphasis> is not particularly efficient, but then it is not expected to be
+run very often.
+</para>
+<para>
+The <emphasis>exinext</emphasis> utility calls Exim to find out information such as the location
+of the spool directory. The utility has <option>-C</option> and <option>-D</option> options, which are
+passed on to the <emphasis>exim</emphasis> commands. The first specifies an alternate Exim
+configuration file, and the second sets macros for use within the configuration
+file. These features are mainly to help in testing, but might also be useful in
+environments where more than one configuration file is in use.
+</para>
+</section>
+<section id="SECThindatmai">
+<title>Hints database maintenance</title>
+<para>
+<indexterm role="concept">
+<primary>hints database</primary>
+<secondary>maintenance</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>maintaining Exim’s hints database</primary>
+</indexterm>
+Three utility programs are provided for maintaining the DBM files that Exim
+uses to contain its delivery hint information. Each program requires two
+arguments. The first specifies the name of Exim’s spool directory, and the
+second is the name of the database it is to operate on. These are as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<emphasis>retry</emphasis>: the database of retry information
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>wait-</emphasis><<emphasis>transport name</emphasis>>: databases of information about messages waiting
+for remote hosts
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>callout</emphasis>: the callout cache
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>ratelimit</emphasis>: the data for implementing the ratelimit ACL condition
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>misc</emphasis>: other hints data
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The <emphasis>misc</emphasis> database is used for
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Serializing ETRN runs (when <option>smtp_etrn_serialize</option> is set)
+</para>
+</listitem>
+<listitem>
+<para>
+Serializing delivery to a specific host (when <option>serialize_hosts</option> is set in an
+<command>smtp</command> transport)
+</para>
+</listitem>
+<listitem>
+<para>
+Limiting the concurrency of specific transports (when <option>max_parallel</option> is set
+in a transport)
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID261">
+<title>exim_dumpdb</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>exim_dumpdb</emphasis></primary>
+</indexterm>
+The entire contents of a database are written to the standard output by the
+<emphasis>exim_dumpdb</emphasis> program, which has no options or arguments other than the
+spool and database names. For example, to dump the retry database:
+</para>
+<literallayout class="monospaced">
+exim_dumpdb /var/spool/exim retry
+</literallayout>
+<para>
+Two lines of output are produced for each entry:
+</para>
+<literallayout class="monospaced">
+T:mail.ref.example:192.168.242.242 146 77 Connection refused
+31-Oct-1995 12:00:12 02-Nov-1995 12:21:39 02-Nov-1995 20:21:39 *
+</literallayout>
+<para>
+The first item on the first line is the key of the record. It starts with one
+of the letters R, or T, depending on whether it refers to a routing or
+transport retry. For a local delivery, the next part is the local address; for
+a remote delivery it is the name of the remote host, followed by its failing IP
+address (unless <option>retry_include_ip_address</option> is set false on the <command>smtp</command>
+transport). If the remote port is not the standard one (port 25), it is added
+to the IP address. Then there follows an error code, an additional error code,
+and a textual description of the error.
+</para>
+<para>
+The three times on the second line are the time of first failure, the time of
+the last delivery attempt, and the computed time for the next attempt. The line
+ends with an asterisk if the cutoff time for the last retry rule has been
+exceeded.
+</para>
+<para>
+Each output line from <emphasis>exim_dumpdb</emphasis> for the <emphasis>wait-xxx</emphasis> databases
+consists of a host name followed by a list of ids for messages that are or were
+waiting to be delivered to that host. If there are a very large number for any
+one host, continuation records, with a sequence number added to the host name,
+may be seen. The data in these records is often out of date, because a message
+may be routed to several alternative hosts, and Exim makes no effort to keep
+cross-references.
+</para>
+</section>
+<section id="SECID262">
+<title>exim_tidydb</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>exim_tidydb</emphasis></primary>
+</indexterm>
+The <emphasis>exim_tidydb</emphasis> utility program is used to tidy up the contents of a hints
+database. If run with no options, it removes all records that are more than 30
+days old. The age is calculated from the date and time that the record was last
+updated. Note that, in the case of the retry database, it is <emphasis>not</emphasis> the time
+since the first delivery failure. Information about a host that has been down
+for more than 30 days will remain in the database, provided that the record is
+updated sufficiently often.
+</para>
+<para>
+The cutoff date can be altered by means of the <option>-t</option> option, which must be
+followed by a time. For example, to remove all records older than a week from
+the retry database:
+</para>
+<literallayout class="monospaced">
+exim_tidydb -t 7d /var/spool/exim retry
+</literallayout>
+<para>
+Both the <emphasis>wait-xxx</emphasis> and <emphasis>retry</emphasis> databases contain items that involve
+message ids. In the former these appear as data in records keyed by host –
+they were messages that were waiting for that host – and in the latter they
+are the keys for retry information for messages that have suffered certain
+types of error. When <emphasis>exim_tidydb</emphasis> is run, a check is made to ensure that
+message ids in database records are those of messages that are still on the
+queue. Message ids for messages that no longer exist are removed from
+<emphasis>wait-xxx</emphasis> records, and if this leaves any records empty, they are deleted.
+For the <emphasis>retry</emphasis> database, records whose keys are non-existent message ids are
+removed. The <emphasis>exim_tidydb</emphasis> utility outputs comments on the standard output
+whenever it removes information from the database.
+</para>
+<para>
+Certain records are automatically removed by Exim when they are no longer
+needed, but others are not. For example, if all the MX hosts for a domain are
+down, a retry record is created for each one. If the primary MX host comes back
+first, its record is removed when Exim successfully delivers to it, but the
+records for the others remain because Exim has not tried to use those hosts.
+</para>
+<para>
+It is important, therefore, to run <emphasis>exim_tidydb</emphasis> periodically on all the
+hints databases. You should do this at a quiet time of day, because it requires
+a database to be locked (and therefore inaccessible to Exim) while it does its
+work. Removing records from a DBM file does not normally make the file smaller,
+but all the common DBM libraries are able to re-use the space that is released.
+After an initial phase of increasing in size, the databases normally reach a
+point at which they no longer get any bigger, as long as they are regularly
+tidied.
+</para>
+<para>
+<emphasis role="bold">Warning</emphasis>: If you never run <emphasis>exim_tidydb</emphasis>, the space used by the hints
+databases is likely to keep on increasing.
+</para>
+</section>
+<section id="SECID263">
+<title>exim_fixdb</title>
+<para>
+<indexterm role="concept">
+<primary><emphasis>exim_fixdb</emphasis></primary>
+</indexterm>
+The <emphasis>exim_fixdb</emphasis> program is a utility for interactively modifying databases.
+Its main use is for testing Exim, but it might also be occasionally useful for
+getting round problems in a live system. It has no options, and its interface
+is somewhat crude. On entry, it prompts for input with a right angle-bracket. A
+key of a database record can then be entered, and the data for that record is
+displayed.
+</para>
+<para>
+If <quote>d</quote> is typed at the next prompt, the entire record is deleted. For all
+except the <emphasis>retry</emphasis> database, that is the only operation that can be carried
+out. For the <emphasis>retry</emphasis> database, each field is output preceded by a number, and
+data for individual fields can be changed by typing the field number followed
+by new data, for example:
+</para>
+<literallayout class="monospaced">
+> 4 951102:1000
+</literallayout>
+<para>
+resets the time of the next delivery attempt. Time values are given as a
+sequence of digit pairs for year, month, day, hour, and minute. Colons can be
+used as optional separators.
+</para>
+</section>
+<section id="SECTmailboxmaint">
+<title>Mailbox maintenance (exim_lock)</title>
+<para>
+<indexterm role="concept">
+<primary>mailbox</primary>
+<secondary>maintenance</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>exim_lock</emphasis></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>locking mailboxes</primary>
+</indexterm>
+The <emphasis>exim_lock</emphasis> utility locks a mailbox file using the same algorithm as
+Exim. For a discussion of locking issues, see section <xref linkend="SECTopappend"/>.
+<emphasis>Exim_lock</emphasis> can be used to prevent any modification of a mailbox by Exim or
+a user agent while investigating a problem. The utility requires the name of
+the file as its first argument. If the locking is successful, the second
+argument is run as a command (using C’s <function>system()</function> function); if there is no
+second argument, the value of the SHELL environment variable is used; if this
+is unset or empty, <filename>/bin/sh</filename> is run. When the command finishes, the mailbox
+is unlocked and the utility ends. The following options are available:
+</para>
+<variablelist>
+<varlistentry>
+<term><option>-fcntl</option></term>
+<listitem>
+<para>
+Use <function>fcntl()</function> locking on the open mailbox.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-flock</option></term>
+<listitem>
+<para>
+Use <function>flock()</function> locking on the open mailbox, provided the operating system
+supports it.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-interval</option></term>
+<listitem>
+<para>
+This must be followed by a number, which is a number of seconds; it sets the
+interval to sleep between retries (default 3).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-lockfile</option></term>
+<listitem>
+<para>
+Create a lock file before opening the mailbox.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-mbx</option></term>
+<listitem>
+<para>
+Lock the mailbox using MBX rules.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-q</option></term>
+<listitem>
+<para>
+Suppress verification output.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-retries</option></term>
+<listitem>
+<para>
+This must be followed by a number; it sets the number of times to try to get
+the lock (default 10).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-restore_time</option></term>
+<listitem>
+<para>
+This option causes <option>exim_lock</option> to restore the modified and read times to the
+locked file before exiting. This allows you to access a locked mailbox (for
+example, to take a backup copy) without disturbing the times that the user
+subsequently sees.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-timeout</option></term>
+<listitem>
+<para>
+This must be followed by a number, which is a number of seconds; it sets a
+timeout to be used with a blocking <function>fcntl()</function> lock. If it is not set (the
+default), a non-blocking call is used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-v</option></term>
+<listitem>
+<para>
+Generate verbose output.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+If none of <option>-fcntl</option>, <option>-flock</option>, <option>-lockfile</option> or <option>-mbx</option> are given, the
+default is to create a lock file and also to use <function>fcntl()</function> locking on the
+mailbox, which is the same as Exim’s default. The use of <option>-flock</option> or
+<option>-fcntl</option> requires that the file be writeable; the use of <option>-lockfile</option>
+requires that the directory containing the file be writeable. Locking by lock
+file does not last forever; Exim assumes that a lock file is expired if it is
+more than 30 minutes old.
+</para>
+<para>
+The <option>-mbx</option> option can be used with either or both of <option>-fcntl</option> or
+<option>-flock</option>. It assumes <option>-fcntl</option> by default. MBX locking causes a shared lock
+to be taken out on the open mailbox, and an exclusive lock on the file
+<filename>/tmp/.n.m</filename> where <emphasis>n</emphasis> and <emphasis>m</emphasis> are the device number and inode
+number of the mailbox file. When the locking is released, if an exclusive lock
+can be obtained for the mailbox, the file in <filename>/tmp</filename> is deleted.
+</para>
+<para>
+The default output contains verification of the locking that takes place. The
+<option>-v</option> option causes some additional information to be given. The <option>-q</option> option
+suppresses all output except error messages.
+</para>
+<para>
+A command such as
+</para>
+<literallayout class="monospaced">
+exim_lock /var/spool/mail/spqr
+</literallayout>
+<para>
+runs an interactive shell while the file is locked, whereas
+</para>
+<literallayout>
+<literal>exim_lock -q /var/spool/mail/spqr <<End</literal>
+<<emphasis>some commands</emphasis>>
+<literal>End</literal>
+</literallayout>
+<para>
+runs a specific non-interactive sequence of commands while the file is locked,
+suppressing all verification output. A single command can be run by a command
+such as
+</para>
+<literallayout class="monospaced">
+exim_lock -q /var/spool/mail/spqr \
+ "cp /var/spool/mail/spqr /some/where"
+</literallayout>
+<para>
+Note that if a command is supplied, it must be entirely contained within the
+second argument – hence the quotes.
+<indexterm role="concept" startref="IIDutils" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPeximon">
+<title>The Exim monitor</title>
+<para>
+<indexterm role="concept" id="IIDeximon" class="startofrange">
+<primary>Exim monitor</primary>
+<secondary>description</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>X-windows</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><emphasis>eximon</emphasis></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>Local/eximon.conf</primary>
+</indexterm>
+<indexterm role="concept">
+<primary><filename>exim_monitor/EDITME</filename></primary>
+</indexterm>
+The Exim monitor is an application which displays in an X window information
+about the state of Exim’s queue and what Exim is doing. An admin user can
+perform certain operations on messages from this GUI interface; however all
+such facilities are also available from the command line, and indeed, the
+monitor itself makes use of the command line to perform any actions requested.
+</para>
+<section id="SECID264">
+<title>Running the monitor</title>
+<para>
+The monitor is started by running the script called <emphasis>eximon</emphasis>. This is a shell
+script that sets up a number of environment variables, and then runs the
+binary called <filename>eximon.bin</filename>. The default appearance of the monitor window can
+be changed by editing the <filename>Local/eximon.conf</filename> file created by editing
+<filename>exim_monitor/EDITME</filename>. Comments in that file describe what the various
+parameters are for.
+</para>
+<para>
+The parameters that get built into the <emphasis>eximon</emphasis> script can be overridden for
+a particular invocation by setting up environment variables of the same names,
+preceded by <literal>EXIMON_</literal>. For example, a shell command such as
+</para>
+<literallayout class="monospaced">
+EXIMON_LOG_DEPTH=400 eximon
+</literallayout>
+<para>
+(in a Bourne-compatible shell) runs <emphasis>eximon</emphasis> with an overriding setting of
+the LOG_DEPTH parameter. If EXIMON_LOG_FILE_PATH is set in the environment, it
+overrides the Exim log file configuration. This makes it possible to have
+<emphasis>eximon</emphasis> tailing log data that is written to syslog, provided that MAIL.INFO
+syslog messages are routed to a file on the local host.
+</para>
+<para>
+X resources can be used to change the appearance of the window in the normal
+way. For example, a resource setting of the form
+</para>
+<literallayout class="monospaced">
+Eximon*background: gray94
+</literallayout>
+<para>
+changes the colour of the background to light grey rather than white. The
+stripcharts are drawn with both the data lines and the reference lines in
+black. This means that the reference lines are not visible when on top of the
+data. However, their colour can be changed by setting a resource called
+<quote>highlight</quote> (an odd name, but that’s what the Athena stripchart widget uses).
+For example, if your X server is running Unix, you could set up lighter
+reference lines in the stripcharts by obeying
+</para>
+<literallayout class="monospaced">
+xrdb -merge <<End
+Eximon*highlight: gray
+End
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>admin user</primary>
+</indexterm>
+In order to see the contents of messages in the queue, and to operate on them,
+<emphasis>eximon</emphasis> must either be run as root or by an admin user.
+</para>
+<para>
+The command-line parameters of <emphasis>eximon</emphasis> are passed to <filename>eximon.bin</filename> and may
+contain X11 resource parameters interpreted by the X11 library. In addition,
+if the first parameter starts with the string "gdb" then it is removed and the
+binary is invoked under gdb (the parameter is used as the gdb command-name, so
+versioned variants of gdb can be invoked).
+</para>
+<para>
+The monitor’s window is divided into three parts. The first contains one or
+more stripcharts and two action buttons, the second contains a <quote>tail</quote> of the
+main log file, and the third is a display of the queue of messages awaiting
+delivery, with two more action buttons. The following sections describe these
+different parts of the display.
+</para>
+</section>
+<section id="SECID265">
+<title>The stripcharts</title>
+<para>
+<indexterm role="concept">
+<primary>stripchart</primary>
+</indexterm>
+The first stripchart is always a count of messages in the queue. Its name can
+be configured by setting QUEUE_STRIPCHART_NAME in the
+<filename>Local/eximon.conf</filename> file. The remaining stripcharts are defined in the
+configuration script by regular expression matches on log file entries, making
+it possible to display, for example, counts of messages delivered to certain
+hosts or using certain transports. The supplied defaults display counts of
+received and delivered messages, and of local and SMTP deliveries. The default
+period between stripchart updates is one minute; this can be adjusted by a
+parameter in the <filename>Local/eximon.conf</filename> file.
+</para>
+<para>
+The stripchart displays rescale themselves automatically as the value they are
+displaying changes. There are always 10 horizontal lines in each chart; the
+title string indicates the value of each division when it is greater than one.
+For example, <quote>x2</quote> means that each division represents a value of 2.
+</para>
+<para>
+It is also possible to have a stripchart which shows the percentage fullness of
+a particular disk partition, which is useful when local deliveries are confined
+to a single partition.
+</para>
+<para>
+<indexterm role="concept">
+<primary><option>statvfs</option> function</primary>
+</indexterm>
+This relies on the availability of the <function>statvfs()</function> function or equivalent in
+the operating system. Most, but not all versions of Unix that support Exim have
+this. For this particular stripchart, the top of the chart always represents
+100%, and the scale is given as <quote>x10%</quote>. This chart is configured by setting
+SIZE_STRIPCHART and (optionally) SIZE_STRIPCHART_NAME in the
+<filename>Local/eximon.conf</filename> file.
+</para>
+</section>
+<section id="SECID266">
+<title>Main action buttons</title>
+<para>
+<indexterm role="concept">
+<primary>size</primary>
+<secondary>of monitor window</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Exim monitor</primary>
+<secondary>window size</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>window size</primary>
+</indexterm>
+Below the stripcharts there is an action button for quitting the monitor. Next
+to this is another button marked <quote>Size</quote>. They are placed here so that
+shrinking the window to its default minimum size leaves just the queue count
+stripchart and these two buttons visible. Pressing the <quote>Size</quote> button causes
+the window to expand to its maximum size, unless it is already at the maximum,
+in which case it is reduced to its minimum.
+</para>
+<para>
+When expanding to the maximum, if the window cannot be fully seen where it
+currently is, it is moved back to where it was the last time it was at full
+size. When it is expanding from its minimum size, the old position is
+remembered, and next time it is reduced to the minimum it is moved back there.
+</para>
+<para>
+The idea is that you can keep a reduced window just showing one or two
+stripcharts at a convenient place on your screen, easily expand it to show
+the full window when required, and just as easily put it back to what it was.
+The idea is copied from what the <emphasis>twm</emphasis> window manager does for its
+<emphasis>f.fullzoom</emphasis> action. The minimum size of the window can be changed by setting
+the MIN_HEIGHT and MIN_WIDTH values in <filename>Local/eximon.conf</filename>.
+</para>
+<para>
+Normally, the monitor starts up with the window at its full size, but it can be
+built so that it starts up with the window at its smallest size, by setting
+START_SMALL=yes in <filename>Local/eximon.conf</filename>.
+</para>
+</section>
+<section id="SECID267">
+<title>The log display</title>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>tail of; in monitor</secondary>
+</indexterm>
+The second section of the window is an area in which a display of the tail of
+the main log is maintained.
+To save space on the screen, the timestamp on each log line is shortened by
+removing the date and, if <option>log_timezone</option> is set, the timezone.
+The log tail is not available when the only destination for logging data is
+syslog, unless the syslog lines are routed to a local file whose name is passed
+to <emphasis>eximon</emphasis> via the EXIMON_LOG_FILE_PATH environment variable.
+</para>
+<para>
+The log sub-window has a scroll bar at its lefthand side which can be used to
+move back to look at earlier text, and the up and down arrow keys also have a
+scrolling effect. The amount of log that is kept depends on the setting of
+LOG_BUFFER in <filename>Local/eximon.conf</filename>, which specifies the amount of memory
+to use. When this is full, the earlier 50% of data is discarded – this is
+much more efficient than throwing it away line by line. The sub-window also has
+a horizontal scroll bar for accessing the ends of long log lines. This is the
+only means of horizontal scrolling; the right and left arrow keys are not
+available. Text can be cut from this part of the window using the mouse in the
+normal way. The size of this subwindow is controlled by parameters in the
+configuration file <filename>Local/eximon.conf</filename>.
+</para>
+<para>
+Searches of the text in the log window can be carried out by means of the ^R
+and ^S keystrokes, which default to a reverse and a forward search,
+respectively. The search covers only the text that is displayed in the window.
+It cannot go further back up the log.
+</para>
+<para>
+The point from which the search starts is indicated by a caret marker. This is
+normally at the end of the text in the window, but can be positioned explicitly
+by pointing and clicking with the left mouse button, and is moved automatically
+by a successful search. If new text arrives in the window when it is scrolled
+back, the caret remains where it is, but if the window is not scrolled back,
+the caret is moved to the end of the new text.
+</para>
+<para>
+Pressing ^R or ^S pops up a window into which the search text can be typed.
+There are buttons for selecting forward or reverse searching, for carrying out
+the search, and for cancelling. If the <quote>Search</quote> button is pressed, the search
+happens and the window remains so that further searches can be done. If the
+<quote>Return</quote> key is pressed, a single search is done and the window is closed. If
+^C is typed the search is cancelled.
+</para>
+<para>
+The searching facility is implemented using the facilities of the Athena text
+widget. By default this pops up a window containing both <quote>search</quote> and
+<quote>replace</quote> options. In order to suppress the unwanted <quote>replace</quote> portion for
+eximon, a modified version of the <option>TextPop</option> widget is distributed with Exim.
+However, the linkers in BSDI and HP-UX seem unable to handle an externally
+provided version of <option>TextPop</option> when the remaining parts of the text widget
+come from the standard libraries. The compile-time option EXIMON_TEXTPOP can be
+unset to cut out the modified <option>TextPop</option>, making it possible to build Eximon
+on these systems, at the expense of having unwanted items in the search popup
+window.
+</para>
+</section>
+<section id="SECID268">
+<title>The queue display</title>
+<para>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>display in monitor</secondary>
+</indexterm>
+The bottom section of the monitor window contains a list of all messages that
+are in the queue, which includes those currently being received or delivered,
+as well as those awaiting delivery. The size of this subwindow is controlled by
+parameters in the configuration file <filename>Local/eximon.conf</filename>, and the frequency
+at which it is updated is controlled by another parameter in the same file –
+the default is 5 minutes, since queue scans can be quite expensive. However,
+there is an <quote>Update</quote> action button just above the display which can be used
+to force an update of the queue display at any time.
+</para>
+<para>
+When a host is down for some time, a lot of pending mail can build up for it,
+and this can make it hard to deal with other messages in the queue. To help
+with this situation there is a button next to <quote>Update</quote> called <quote>Hide</quote>. If
+pressed, a dialogue box called <quote>Hide addresses ending with</quote> is put up. If you
+type anything in here and press <quote>Return</quote>, the text is added to a chain of
+such texts, and if every undelivered address in a message matches at least one
+of the texts, the message is not displayed.
+</para>
+<para>
+If there is an address that does not match any of the texts, all the addresses
+are displayed as normal. The matching happens on the ends of addresses so, for
+example, <emphasis>cam.ac.uk</emphasis> specifies all addresses in Cambridge, while
+<emphasis>xxx@foo.com.example</emphasis> specifies just one specific address. When any hiding
+has been set up, a button called <quote>Unhide</quote> is displayed. If pressed, it
+cancels all hiding. Also, to ensure that hidden messages do not get forgotten,
+a hide request is automatically cancelled after one hour.
+</para>
+<para>
+While the dialogue box is displayed, you can’t press any buttons or do anything
+else to the monitor window. For this reason, if you want to cut text from the
+queue display to use in the dialogue box, you have to do the cutting before
+pressing the <quote>Hide</quote> button.
+</para>
+<para>
+The queue display contains, for each unhidden queued message, the length of
+time it has been in the queue, the size of the message, the message id, the
+message sender, and the first undelivered recipient, all on one line. If it is
+a bounce message, the sender is shown as <quote><></quote>. If there is more than one
+recipient to which the message has not yet been delivered, subsequent ones are
+listed on additional lines, up to a maximum configured number, following which
+an ellipsis is displayed. Recipients that have already received the message are
+not shown.
+</para>
+<para>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>display</secondary>
+</indexterm>
+If a message is frozen, an asterisk is displayed at the left-hand side.
+</para>
+<para>
+The queue display has a vertical scroll bar, and can also be scrolled by means
+of the arrow keys. Text can be cut from it using the mouse in the normal way.
+The text searching facilities, as described above for the log window, are also
+available, but the caret is always moved to the end of the text when the queue
+display is updated.
+</para>
+</section>
+<section id="SECID269">
+<title>The queue menu</title>
+<para>
+<indexterm role="concept">
+<primary>queue</primary>
+<secondary>menu in monitor</secondary>
+</indexterm>
+If the <option>shift</option> key is held down and the left button is clicked when the mouse
+pointer is over the text for any message, an action menu pops up, and the first
+line of the queue display for the message is highlighted. This does not affect
+any selected text.
+</para>
+<para>
+If you want to use some other event for popping up the menu, you can set the
+MENU_EVENT parameter in <filename>Local/eximon.conf</filename> to change the default, or
+set EXIMON_MENU_EVENT in the environment before starting the monitor. The
+value set in this parameter is a standard X event description. For example, to
+run eximon using <option>ctrl</option> rather than <option>shift</option> you could use
+</para>
+<literallayout class="monospaced">
+EXIMON_MENU_EVENT='Ctrl<Btn1Down>' eximon
+</literallayout>
+<para>
+The title of the menu is the message id, and it contains entries which act as
+follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<emphasis>message log</emphasis>: The contents of the message log for the message are displayed
+in a new text window.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>headers</emphasis>: Information from the spool file that contains the envelope
+information and headers is displayed in a new text window. See chapter
+<xref linkend="CHAPspool"/> for a description of the format of spool files.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>body</emphasis>: The contents of the spool file containing the body of the message are
+displayed in a new text window. There is a default limit of 20,000 bytes to the
+amount of data displayed. This can be changed by setting the BODY_MAX
+option at compile time, or the EXIMON_BODY_MAX option at runtime.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>deliver message</emphasis>: A call to Exim is made using the <option>-M</option> option to request
+delivery of the message. This causes an automatic thaw if the message is
+frozen. The <option>-v</option> option is also set, and the output from Exim is displayed in
+a new text window. The delivery is run in a separate process, to avoid holding
+up the monitor while the delivery proceeds.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>freeze message</emphasis>: A call to Exim is made using the <option>-Mf</option> option to request
+that the message be frozen.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>thawing messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>unfreezing messages</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>thawing</secondary>
+</indexterm>
+<emphasis>thaw message</emphasis>: A call to Exim is made using the <option>-Mt</option> option to request
+that the message be thawed.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>delivery</primary>
+<secondary>forcing failure</secondary>
+</indexterm>
+<emphasis>give up on msg</emphasis>: A call to Exim is made using the <option>-Mg</option> option to request
+that Exim gives up trying to deliver the message. A bounce message is generated
+for any remaining undelivered addresses.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>remove message</emphasis>: A call to Exim is made using the <option>-Mrm</option> option to request
+that the message be deleted from the system without generating a bounce
+message.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>add recipient</emphasis>: A dialog box is displayed into which a recipient address can
+be typed. If the address is not qualified and the QUALIFY_DOMAIN parameter
+is set in <filename>Local/eximon.conf</filename>, the address is qualified with that domain.
+Otherwise it must be entered as a fully qualified address. Pressing RETURN
+causes a call to Exim to be made using the <option>-Mar</option> option to request that an
+additional recipient be added to the message, unless the entry box is empty, in
+which case no action is taken.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>mark delivered</emphasis>: A dialog box is displayed into which a recipient address
+can be typed. If the address is not qualified and the QUALIFY_DOMAIN parameter
+is set in <filename>Local/eximon.conf</filename>, the address is qualified with that domain.
+Otherwise it must be entered as a fully qualified address. Pressing RETURN
+causes a call to Exim to be made using the <option>-Mmd</option> option to mark the given
+recipient address as already delivered, unless the entry box is empty, in which
+case no action is taken.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>mark all delivered</emphasis>: A call to Exim is made using the <option>-Mmad</option> option to
+mark all recipient addresses as already delivered.
+</para>
+</listitem>
+<listitem>
+<para>
+<emphasis>edit sender</emphasis>: A dialog box is displayed initialized with the current
+sender’s address. Pressing RETURN causes a call to Exim to be made using the
+<option>-Mes</option> option to replace the sender address, unless the entry box is empty,
+in which case no action is taken. If you want to set an empty sender (as in
+bounce messages), you must specify it as <quote><></quote>. Otherwise, if the address is
+not qualified and the QUALIFY_DOMAIN parameter is set in <filename>Local/eximon.conf</filename>,
+the address is qualified with that domain.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+When a delivery is forced, a window showing the <option>-v</option> output is displayed. In
+other cases when a call to Exim is made, if there is any output from Exim (in
+particular, if the command fails) a window containing the command and the
+output is displayed. Otherwise, the results of the action are normally apparent
+from the log and queue displays. However, if you set ACTION_OUTPUT=yes in
+<filename>Local/eximon.conf</filename>, a window showing the Exim command is always opened, even
+if no output is generated.
+</para>
+<para>
+The queue display is automatically updated for actions such as freezing and
+thawing, unless ACTION_QUEUE_UPDATE=no has been set in
+<filename>Local/eximon.conf</filename>. In this case the <quote>Update</quote> button has to be used to
+force an update of the display after one of these actions.
+</para>
+<para>
+In any text window that is displayed as result of a menu action, the normal
+cut-and-paste facility is available, and searching can be carried out using ^R
+and ^S, as described above for the log tail window.
+<indexterm role="concept" startref="IIDeximon" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPsecurity">
+<title>Security considerations</title>
+<para>
+<indexterm role="concept" id="IIDsecurcon" class="startofrange">
+<primary>security</primary>
+<secondary>discussion of</secondary>
+</indexterm>
+This chapter discusses a number of issues concerned with security, some of
+which are also covered in other parts of this manual.
+</para>
+<para>
+For reasons that this author does not understand, some people have promoted
+Exim as a <quote>particularly secure</quote> mailer. Perhaps it is because of the
+existence of this chapter in the documentation. However, the intent of the
+chapter is simply to describe the way Exim works in relation to certain
+security concerns, not to make any specific claims about the effectiveness of
+its security as compared with other MTAs.
+</para>
+<para>
+What follows is a description of the way Exim is supposed to be. Best efforts
+have been made to try to ensure that the code agrees with the theory, but an
+absence of bugs can never be guaranteed. Any that are reported will get fixed
+as soon as possible.
+</para>
+<section id="SECID286">
+<title>Building a more <quote>hardened</quote> Exim</title>
+<para>
+<indexterm role="concept">
+<primary>security</primary>
+<secondary>build-time features</secondary>
+</indexterm>
+There are a number of build-time options that can be set in <filename>Local/Makefile</filename>
+to create Exim binaries that are <quote>harder</quote> to attack, in particular by a rogue
+Exim administrator who does not have the root password, or by someone who has
+penetrated the Exim (but not the root) account. These options are as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+ALT_CONFIG_PREFIX can be set to a string that is required to match the
+start of any filenames used with the <option>-C</option> option. When it is set, these
+filenames are also not allowed to contain the sequence <quote>/../</quote>. (However, if
+the value of the <option>-C</option> option is identical to the value of CONFIGURE_FILE in
+<filename>Local/Makefile</filename>, Exim ignores <option>-C</option> and proceeds as usual.) There is no
+default setting for <option>ALT_CONFIG_PREFIX</option>.
+</para>
+<para>
+If the permitted configuration files are confined to a directory to
+which only root has access, this guards against someone who has broken
+into the Exim account from running a privileged Exim with an arbitrary
+configuration file, and using it to break into other accounts.
+</para>
+</listitem>
+<listitem>
+<para>
+If a non-trusted configuration file (i.e. not the default configuration file
+or one which is trusted by virtue of being listed in the TRUSTED_CONFIG_LIST
+file) is specified with <option>-C</option>, or if macros are given with <option>-D</option> (but see
+the next item), then root privilege is retained only if the caller of Exim is
+root. This locks out the possibility of testing a configuration using <option>-C</option>
+right through message reception and delivery, even if the caller is root. The
+reception works, but by that time, Exim is running as the Exim user, so when
+it re-execs to regain privilege for the delivery, the use of <option>-C</option> causes
+privilege to be lost. However, root can test reception and delivery using two
+separate commands.
+</para>
+</listitem>
+<listitem>
+<para>
+The WHITELIST_D_MACROS build option declares some macros to be safe to override
+with <option>-D</option> if the real uid is one of root, the Exim run-time user or the
+CONFIGURE_OWNER, if defined. The potential impact of this option is limited by
+requiring the run-time value supplied to <option>-D</option> to match a regex that errs on
+the restrictive side. Requiring build-time selection of safe macros is onerous
+but this option is intended solely as a transition mechanism to permit
+previously-working configurations to continue to work after release 4.73.
+</para>
+</listitem>
+<listitem>
+<para>
+If DISABLE_D_OPTION is defined, the use of the <option>-D</option> command line option
+is disabled.
+</para>
+</listitem>
+<listitem>
+<para>
+FIXED_NEVER_USERS can be set to a colon-separated list of users that are
+never to be used for any deliveries. This is like the <option>never_users</option> runtime
+option, but it cannot be overridden; the runtime option adds additional users
+to the list. The default setting is <quote>root</quote>; this prevents a non-root user who
+is permitted to modify the runtime file from using Exim as a way to get root.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID270">
+<title>Root privilege</title>
+<para>
+<indexterm role="concept">
+<primary>setuid</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>root privilege</primary>
+</indexterm>
+The Exim binary is normally setuid to root, which means that it gains root
+privilege (runs as root) when it starts execution. In some special cases (for
+example, when the daemon is not in use and there are no local deliveries), it
+may be possible to run Exim setuid to some user other than root. This is
+discussed in the next section. However, in most installations, root privilege
+is required for two things:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+To set up a socket connected to the standard SMTP port (25) when initialising
+the listening daemon. If Exim is run from <emphasis>inetd</emphasis>, this privileged action is
+not required.
+</para>
+</listitem>
+<listitem>
+<para>
+To be able to change uid and gid in order to read users’ <filename>.forward</filename> files and
+perform local deliveries as the receiving user or as specified in the
+configuration.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+It is not necessary to be root to do any of the other things Exim does, such as
+receiving messages and delivering them externally over SMTP, and it is
+obviously more secure if Exim does not run as root except when necessary.
+For this reason, a user and group for Exim to use must be defined in
+<filename>Local/Makefile</filename>. These are known as <quote>the Exim user</quote> and <quote>the Exim
+group</quote>. Their values can be changed by the runtime configuration, though this
+is not recommended. Often a user called <emphasis>exim</emphasis> is used, but some sites use
+<emphasis>mail</emphasis> or another user name altogether.
+</para>
+<para>
+Exim uses <function>setuid()</function> whenever it gives up root privilege. This is a permanent
+abdication; the process cannot regain root afterwards. Prior to release 4.00,
+<function>seteuid()</function> was used in some circumstances, but this is no longer the case.
+</para>
+<para>
+After a new Exim process has interpreted its command line options, it changes
+uid and gid in the following cases:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-C</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-D</option></primary>
+</indexterm>
+If the <option>-C</option> option is used to specify an alternate configuration file, or if
+the <option>-D</option> option is used to define macro values for the configuration, and the
+calling process is not running as root, the uid and gid are changed to those of
+the calling process.
+However, if DISABLE_D_OPTION is defined in <filename>Local/Makefile</filename>, the <option>-D</option>
+option may not be used at all.
+If WHITELIST_D_MACROS is defined in <filename>Local/Makefile</filename>, then some macro values
+can be supplied if the calling process is running as root, the Exim run-time
+user or CONFIGURE_OWNER, if defined.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="option">
+<primary><option>-be</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-bf</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-bF</option></primary>
+</indexterm>
+If the expansion test option (<option>-be</option>) or one of the filter testing options
+(<option>-bf</option> or <option>-bF</option>) are used, the uid and gid are changed to those of the
+calling process.
+</para>
+</listitem>
+<listitem>
+<para>
+If the process is not a daemon process or a queue runner process or a delivery
+process or a process for testing address routing (started with <option>-bt</option>), the
+uid and gid are changed to the Exim user and group. This means that Exim always
+runs under its own uid and gid when receiving messages. This also applies when
+testing address verification
+<indexterm role="option">
+<primary><option>-bv</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-bh</option></primary>
+</indexterm>
+(the <option>-bv</option> option) and testing incoming message policy controls (the <option>-bh</option>
+option).
+</para>
+</listitem>
+<listitem>
+<para>
+For a daemon, queue runner, delivery, or address testing process, the uid
+remains as root at this stage, but the gid is changed to the Exim group.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+The processes that initially retain root privilege behave as follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+A daemon process changes the gid to the Exim group and the uid to the Exim
+user after setting up one or more listening sockets. The <function>initgroups()</function>
+function is called, so that if the Exim user is in any additional groups, they
+will be used during message reception.
+</para>
+</listitem>
+<listitem>
+<para>
+A queue runner process retains root privilege throughout its execution. Its
+job is to fork a controlled sequence of delivery processes.
+</para>
+</listitem>
+<listitem>
+<para>
+A delivery process retains root privilege throughout most of its execution,
+but any actual deliveries (that is, the transports themselves) are run in
+subprocesses which always change to a non-root uid and gid. For local
+deliveries this is typically the uid and gid of the owner of the mailbox; for
+remote deliveries, the Exim uid and gid are used. Once all the delivery
+subprocesses have been run, a delivery process changes to the Exim uid and gid
+while doing post-delivery tidying up such as updating the retry database and
+generating bounce and warning messages.
+</para>
+<para>
+While the recipient addresses in a message are being routed, the delivery
+process runs as root. However, if a user’s filter file has to be processed,
+this is done in a subprocess that runs under the individual user’s uid and
+gid. A system filter is run as root unless <option>system_filter_user</option> is set.
+</para>
+</listitem>
+<listitem>
+<para>
+A process that is testing addresses (the <option>-bt</option> option) runs as root so that
+the routing is done in the same environment as a message delivery.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECTrunexiwitpri">
+<title>Running Exim without privilege</title>
+<para>
+<indexterm role="concept">
+<primary>privilege, running without</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>unprivileged running</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>root privilege</primary>
+<secondary>running without</secondary>
+</indexterm>
+Some installations like to run Exim in an unprivileged state for more of its
+operation, for added security. Support for this mode of operation is provided
+by the global option <option>deliver_drop_privilege</option>. When this is set, the uid and
+gid are changed to the Exim user and group at the start of a delivery process
+(and also queue runner and address testing processes). This means that address
+routing is no longer run as root, and the deliveries themselves cannot change
+to any other uid.
+</para>
+<para>
+<indexterm role="concept">
+<primary>SIGHUP</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>daemon</primary>
+<secondary>restarting</secondary>
+</indexterm>
+Leaving the binary setuid to root, but setting <option>deliver_drop_privilege</option> means
+that the daemon can still be started in the usual way, and it can respond
+correctly to SIGHUP because the re-invocation regains root privilege.
+</para>
+<para>
+An alternative approach is to make Exim setuid to the Exim user and also setgid
+to the Exim group. If you do this, the daemon must be started from a root
+process. (Calling Exim from a root process makes it behave in the way it does
+when it is setuid root.) However, the daemon cannot restart itself after a
+SIGHUP signal because it cannot regain privilege.
+</para>
+<para>
+It is still useful to set <option>deliver_drop_privilege</option> in this case, because it
+stops Exim from trying to re-invoke itself to do a delivery after a message has
+been received. Such a re-invocation is a waste of resources because it has no
+effect.
+</para>
+<para>
+If restarting the daemon is not an issue (for example, if <option>mua_wrapper</option> is
+set, or <emphasis>inetd</emphasis> is being used instead of a daemon), having the binary setuid
+to the Exim user seems a clean approach, but there is one complication:
+</para>
+<para>
+In this style of operation, Exim is running with the real uid and gid set to
+those of the calling process, and the effective uid/gid set to Exim’s values.
+Ideally, any association with the calling process’ uid/gid should be dropped,
+that is, the real uid/gid should be reset to the effective values so as to
+discard any privileges that the caller may have. While some operating systems
+have a function that permits this action for a non-root effective uid, quite a
+number of them do not. Because of this lack of standardization, Exim does not
+address this problem at this time.
+</para>
+<para>
+For this reason, the recommended approach for <quote>mostly unprivileged</quote> running
+is to keep the Exim binary setuid to root, and to set
+<option>deliver_drop_privilege</option>. This also has the advantage of allowing a daemon to
+be used in the most straightforward way.
+</para>
+<para>
+If you configure Exim not to run delivery processes as root, there are a
+number of restrictions on what you can do:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+You can deliver only as the Exim user/group. You should explicitly use the
+<option>user</option> and <option>group</option> options to override routers or local transports that
+normally deliver as the recipient. This makes sure that configurations that
+work in this mode function the same way in normal mode. Any implicit or
+explicit specification of another user causes an error.
+</para>
+</listitem>
+<listitem>
+<para>
+Use of <filename>.forward</filename> files is severely restricted, such that it is usually
+not worthwhile to include them in the configuration.
+</para>
+</listitem>
+<listitem>
+<para>
+Users who wish to use <filename>.forward</filename> would have to make their home directory and
+the file itself accessible to the Exim user. Pipe and append-to-file entries,
+and their equivalents in Exim filters, cannot be used. While they could be
+enabled in the Exim user’s name, that would be insecure and not very useful.
+</para>
+</listitem>
+<listitem>
+<para>
+Unless the local user mailboxes are all owned by the Exim user (possible in
+some POP3 or IMAP-only environments):
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+They must be owned by the Exim group and be writeable by that group. This
+implies you must set <option>mode</option> in the appendfile configuration, as well as the
+mode of the mailbox files themselves.
+</para>
+</listitem>
+<listitem>
+<para>
+You must set <option>no_check_owner</option>, since most or all of the files will not be
+owned by the Exim user.
+</para>
+</listitem>
+<listitem>
+<para>
+You must set <option>file_must_exist</option>, because Exim cannot set the owner correctly
+on a newly created mailbox when unprivileged. This also implies that new
+mailboxes need to be created manually.
+</para>
+</listitem>
+</orderedlist>
+</listitem>
+</itemizedlist>
+<para>
+These restrictions severely restrict what can be done in local deliveries.
+However, there are no restrictions on remote deliveries. If you are running a
+gateway host that does no local deliveries, setting <option>deliver_drop_privilege</option>
+gives more security at essentially no cost.
+</para>
+<para>
+If you are using the <option>mua_wrapper</option> facility (see chapter
+<xref linkend="CHAPnonqueueing"/>), <option>deliver_drop_privilege</option> is forced to be true.
+</para>
+</section>
+<section id="SECID271">
+<title>Delivering to local files</title>
+<para>
+Full details of the checks applied by <command>appendfile</command> before it writes to a file
+are given in chapter <xref linkend="CHAPappendfile"/>.
+</para>
+</section>
+<section id="SECTsecconslocalcmds">
+<title>Running local commands</title>
+<para>
+<indexterm role="concept">
+<primary>security</primary>
+<secondary>local commands</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>security</primary>
+<secondary>command injection attacks</secondary>
+</indexterm>
+There are a number of ways in which an administrator can configure Exim to run
+commands based upon received, untrustworthy, data. Further, in some
+configurations a user who can control a <filename>.forward</filename> file can also arrange to
+run commands. Configuration to check includes, but is not limited to:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Use of <option>use_shell</option> in the pipe transport: various forms of shell command
+injection may be possible with this option present. It is dangerous and should
+be used only with considerable caution. Consider constraints which whitelist
+allowed characters in a variable which is to be used in a pipe transport that
+has <option>use_shell</option> enabled.
+</para>
+</listitem>
+<listitem>
+<para>
+A number of options such as <option>forbid_filter_run</option>, <option>forbid_filter_perl</option>,
+<option>forbid_filter_dlfunc</option> and so forth which restrict facilities available to
+<filename>.forward</filename> files in a redirect router. If Exim is running on a central mail
+hub to which ordinary users do not have shell access, but home directories are
+NFS mounted (for instance) then administrators should review the list of these
+forbid options available, and should bear in mind that the options that may
+need forbidding can change as new features are added between releases.
+</para>
+</listitem>
+<listitem>
+<para>
+The <option>${run...}</option> expansion item does not use a shell by default, but
+administrators can configure use of <filename>/bin/sh</filename> as part of the command.
+Such invocations should be viewed with prejudicial suspicion.
+</para>
+</listitem>
+<listitem>
+<para>
+Administrators who use embedded Perl are advised to explore how Perl’s
+taint checking might apply to their usage.
+</para>
+</listitem>
+<listitem>
+<para>
+Use of <option>${expand...}</option> is somewhat analogous to shell’s eval builtin and
+administrators are well advised to view its use with suspicion, in case (for
+instance) it allows a local-part to contain embedded Exim directives.
+</para>
+</listitem>
+<listitem>
+<para>
+Use of <option>${match_local_part...}</option> and friends becomes more dangerous if
+Exim was built with EXPAND_LISTMATCH_RHS defined: the second string in
+each can reference arbitrary lists and files, rather than just being a list
+of opaque strings.
+The EXPAND_LISTMATCH_RHS option was added and set false by default because of
+real-world security vulnerabilities caused by its use with untrustworthy data
+injected in, for SQL injection attacks.
+Consider the use of the <option>inlisti</option> expansion condition instead.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECTsecconfdata">
+<title>Trust in configuration data</title>
+<para>
+<indexterm role="concept">
+<primary>security</primary>
+<secondary>data sources</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>security</primary>
+<secondary>regular expressions</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>regular expressions</primary>
+<secondary>security</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>PCRE</primary>
+<secondary>security</secondary>
+</indexterm>
+If configuration data for Exim can come from untrustworthy sources, there
+are some issues to be aware of:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Use of <option>${expand...}</option> may provide a path for shell injection attacks.
+</para>
+</listitem>
+<listitem>
+<para>
+Letting untrusted data provide a regular expression is unwise.
+</para>
+</listitem>
+<listitem>
+<para>
+Using <option>${match...}</option> to apply a fixed regular expression against untrusted
+data may result in pathological behaviour within PCRE. Be aware of what
+"backtracking" means and consider options for being more strict with a regular
+expression. Avenues to explore include limiting what can match (avoiding <literal>.</literal>
+when <literal>[a-z0-9]</literal> or other character class will do), use of atomic grouping and
+possessive quantifiers or just not using regular expressions against untrusted
+data.
+</para>
+</listitem>
+<listitem>
+<para>
+It can be important to correctly use <option>${quote:...}</option>,
+<option>${quote_local_part:...}</option> and <option>${quote_</option><<emphasis>lookup-type</emphasis>><option>:...}</option> expansion
+items to ensure that data is correctly constructed.
+</para>
+</listitem>
+<listitem>
+<para>
+Some lookups might return multiple results, even though normal usage is only
+expected to yield one result.
+</para>
+</listitem>
+</itemizedlist>
+</section>
+<section id="SECID272">
+<title>IPv4 source routing</title>
+<para>
+<indexterm role="concept">
+<primary>source routing</primary>
+<secondary>in IP packets</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>IP source routing</primary>
+</indexterm>
+Many operating systems suppress IP source-routed packets in the kernel, but
+some cannot be made to do this, so Exim does its own check. It logs incoming
+IPv4 source-routed TCP calls, and then drops them. Things are all different in
+IPv6. No special checking is currently done.
+</para>
+</section>
+<section id="SECID273">
+<title>The VRFY, EXPN, and ETRN commands in SMTP</title>
+<para>
+Support for these SMTP commands is disabled by default. If required, they can
+be enabled by defining suitable ACLs.
+</para>
+</section>
+<section id="SECID274">
+<title>Privileged users</title>
+<para>
+<indexterm role="concept">
+<primary>trusted users</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>admin user</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>privileged user</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>user</primary>
+<secondary>trusted</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>user</primary>
+<secondary>admin</secondary>
+</indexterm>
+Exim recognizes two sets of users with special privileges. Trusted users are
+able to submit new messages to Exim locally, but supply their own sender
+addresses and information about a sending host. For other users submitting
+local messages, Exim sets up the sender address from the uid, and doesn’t
+permit a remote host to be specified.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>-f</option></primary>
+</indexterm>
+However, an untrusted user is permitted to use the <option>-f</option> command line option
+in the special form <option>-f <></option> to indicate that a delivery failure for the
+message should not cause an error report. This affects the message’s envelope,
+but it does not affect the <emphasis>Sender:</emphasis> header. Untrusted users may also be
+permitted to use specific forms of address with the <option>-f</option> option by setting
+the <option>untrusted_set_sender</option> option.
+</para>
+<para>
+Trusted users are used to run processes that receive mail messages from some
+other mail domain and pass them on to Exim for delivery either locally, or over
+the Internet. Exim trusts a caller that is running as root, as the Exim user,
+as any user listed in the <option>trusted_users</option> configuration option, or under any
+group listed in the <option>trusted_groups</option> option.
+</para>
+<para>
+Admin users are permitted to do things to the messages on Exim’s queue. They
+can freeze or thaw messages, cause them to be returned to their senders, remove
+them entirely, or modify them in various ways. In addition, admin users can run
+the Exim monitor and see all the information it is capable of providing, which
+includes the contents of files on the spool.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>-M</option></primary>
+</indexterm>
+<indexterm role="option">
+<primary><option>-q</option></primary>
+</indexterm>
+By default, the use of the <option>-M</option> and <option>-q</option> options to cause Exim to attempt
+delivery of messages on its queue is restricted to admin users. This
+restriction can be relaxed by setting the <option>no_prod_requires_admin</option> option.
+Similarly, the use of <option>-bp</option> (and its variants) to list the contents of the
+queue is also restricted to admin users. This restriction can be relaxed by
+setting <option>no_queue_list_requires_admin</option>.
+</para>
+<para>
+Exim recognizes an admin user if the calling process is running as root or as
+the Exim user or if any of the groups associated with the calling process is
+the Exim group. It is not necessary actually to be running under the Exim
+group. However, if admin users who are not root or the Exim user are to access
+the contents of files on the spool via the Exim monitor (which runs
+unprivileged), Exim must be built to allow group read access to its spool
+files.
+</para>
+<para>
+By default, regular users are trusted to perform basic testing and
+introspection commands, as themselves. This setting can be tightened by
+setting the <option>commandline_checks_require_admin</option> option.
+This affects most of the checking options,
+such as <option>-be</option> and anything else <option>-b*</option>.
+</para>
+</section>
+<section id="SECID275">
+<title>Spool files</title>
+<para>
+<indexterm role="concept">
+<primary>spool directory</primary>
+<secondary>files</secondary>
+</indexterm>
+Exim’s spool directory and everything it contains is owned by the Exim user and
+set to the Exim group. The mode for spool files is defined in the
+<filename>Local/Makefile</filename> configuration file, and defaults to 0640. This means that
+any user who is a member of the Exim group can access these files.
+</para>
+</section>
+<section id="SECID276">
+<title>Use of argv[0]</title>
+<para>
+Exim examines the last component of <option>argv[0]</option>, and if it matches one of a set
+of specific strings, Exim assumes certain options. For example, calling Exim
+with the last component of <option>argv[0]</option> set to <quote>rsmtp</quote> is exactly equivalent
+to calling it with the option <option>-bS</option>. There are no security implications in
+this.
+</para>
+</section>
+<section id="SECID277">
+<title>Use of %f formatting</title>
+<para>
+The only use made of <quote>%f</quote> by Exim is in formatting load average values. These
+are actually stored in integer variables as 1000 times the load average.
+Consequently, their range is limited and so therefore is the length of the
+converted output.
+</para>
+</section>
+<section id="SECID278">
+<title>Embedded Exim path</title>
+<para>
+Exim uses its own path name, which is embedded in the code, only when it needs
+to re-exec in order to regain root privilege. Therefore, it is not root when it
+does so. If some bug allowed the path to get overwritten, it would lead to an
+arbitrary program’s being run as exim, not as root.
+</para>
+</section>
+<section id="SECTdynmoddir">
+<title>Dynamic module directory</title>
+<para>
+Any dynamically loadable modules must be installed into the directory
+defined in <literal>LOOKUP_MODULE_DIR</literal> in <filename>Local/Makefile</filename> for Exim to permit
+loading it.
+</para>
+</section>
+<section id="SECID279">
+<title>Use of sprintf()</title>
+<para>
+<indexterm role="concept">
+<primary><function>sprintf()</function></primary>
+</indexterm>
+A large number of occurrences of <quote>sprintf</quote> in the code are actually calls to
+<emphasis>string_sprintf()</emphasis>, a function that returns the result in malloc’d store.
+The intermediate formatting is done into a large fixed buffer by a function
+that runs through the format string itself, and checks the length of each
+conversion before performing it, thus preventing buffer overruns.
+</para>
+<para>
+The remaining uses of <function>sprintf()</function> happen in controlled circumstances where
+the output buffer is known to be sufficiently long to contain the converted
+string.
+</para>
+</section>
+<section id="SECID280">
+<title>Use of debug_printf() and log_write()</title>
+<para>
+Arbitrary strings are passed to both these functions, but they do their
+formatting by calling the function <emphasis>string_vformat()</emphasis>, which runs through
+the format string itself, and checks the length of each conversion.
+</para>
+</section>
+<section id="SECID281">
+<title>Use of strcat() and strcpy()</title>
+<para>
+These are used only in cases where the output buffer is known to be large
+enough to hold the result.
+<indexterm role="concept" startref="IIDsecurcon" class="endofrange"/>
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPspool">
+<title>Format of spool files</title>
+<para>
+<indexterm role="concept" id="IIDforspo1" class="startofrange">
+<primary>format</primary>
+<secondary>spool files</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDforspo2" class="startofrange">
+<primary>spool directory</primary>
+<secondary>format of files</secondary>
+</indexterm>
+<indexterm role="concept" id="IIDforspo3" class="startofrange">
+<primary>spool files</primary>
+<secondary>format of</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>spool files</primary>
+<secondary>editing</secondary>
+</indexterm>
+A message on Exim’s queue consists of two files, whose names are the message id
+followed by -D and -H, respectively. The data portion of the message is kept in
+the -D file on its own. The message’s envelope, status, and headers are all
+kept in the -H file, whose format is described in this chapter. Each of these
+two files contains the final component of its own name as its first line. This
+is insurance against disk crashes where the directory is lost but the files
+themselves are recoverable.
+</para>
+<para>
+The file formats may be changed, or new formats added, at any release.
+Spool files are not intended as an interface to other programs
+and should not be used as such.
+</para>
+<para>
+Some people are tempted into editing -D files in order to modify messages. You
+need to be extremely careful if you do this; it is not recommended and you are
+on your own if you do it. Here are some of the pitfalls:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+You must ensure that Exim does not try to deliver the message while you are
+fiddling with it. The safest way is to take out a write lock on the -D file,
+which is what Exim itself does, using <function>fcntl()</function>. If you update the file in
+place, the lock will be retained. If you write a new file and rename it, the
+lock will be lost at the instant of rename.
+</para>
+</listitem>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$body_linecount</varname></primary>
+</indexterm>
+If you change the number of lines in the file, the value of
+<varname>$body_linecount</varname>, which is stored in the -H file, will be incorrect and can
+cause incomplete transmission of messages or undeliverable messages.
+</para>
+</listitem>
+<listitem>
+<para>
+If the message is in MIME format, you must take care not to break it.
+</para>
+</listitem>
+<listitem>
+<para>
+If the message is cryptographically signed, any change will invalidate the
+signature.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+All in all, modifying -D files is fraught with danger.
+</para>
+<para>
+Files whose names end with -J may also be seen in the <filename>input</filename> directory (or
+its subdirectories when <option>split_spool_directory</option> is set). These are journal
+files, used to record addresses to which the message has been delivered during
+the course of a delivery attempt. If there are still undelivered recipients at
+the end, the -H file is updated, and the -J file is deleted. If, however, there
+is some kind of crash (for example, a power outage) before this happens, the -J
+file remains in existence. When Exim next processes the message, it notices the
+-J file and uses it to update the -H file before starting the next delivery
+attempt.
+</para>
+<para>
+Files whose names end with -K or .eml may also be seen in the spool.
+These are temporaries used for DKIM or malware processing, when that is used.
+They should be tidied up by normal operations; any old ones are probably
+relics of crashes and can be removed.
+</para>
+<section id="SECID282">
+<title>Format of the -H file</title>
+<para>
+<indexterm role="concept">
+<primary>uid (user id)</primary>
+<secondary>in spool file</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>gid (group id)</primary>
+<secondary>in spool file</secondary>
+</indexterm>
+The second line of the -H file contains the login name for the uid of the
+process that called Exim to read the message, followed by the numerical uid and
+gid. For a locally generated message, this is normally the user who sent the
+message. For a message received over TCP/IP via the daemon, it is
+normally the Exim user.
+</para>
+<para>
+The third line of the file contains the address of the message’s sender as
+transmitted in the envelope, contained in angle brackets. The sender address is
+empty for bounce messages. For incoming SMTP mail, the sender address is given
+in the MAIL command. For locally generated mail, the sender address is
+created by Exim from the login name of the current user and the configured
+<option>qualify_domain</option>. However, this can be overridden by the <option>-f</option> option or a
+leading <quote>From </quote> line if the caller is trusted, or if the supplied address is
+<quote><></quote> or an address that matches <option>untrusted_set_senders</option>.
+</para>
+<para>
+The fourth line contains two numbers. The first is the time that the message
+was received, in the conventional Unix form – the number of seconds since the
+start of the epoch. The second number is a count of the number of messages
+warning of delayed delivery that have been sent to the sender.
+</para>
+<para>
+There follow a number of lines starting with a hyphen. These can appear in any
+order, and are omitted when not relevant:
+</para>
+<variablelist>
+<varlistentry>
+<term><option>-acl</option> <<emphasis>number</emphasis>> <<emphasis>length</emphasis>></term>
+<listitem>
+<para>
+This item is obsolete, and is not generated from Exim release 4.61 onwards;
+<option>-aclc</option> and <option>-aclm</option> are used instead. However, <option>-acl</option> is still
+recognized, to provide backward compatibility. In the old format, a line of
+this form is present for every ACL variable that is not empty. The number
+identifies the variable; the <option>acl_c</option><emphasis role="bold">x</emphasis> variables are numbered 0–9 and
+the <option>acl_m</option><emphasis role="bold">x</emphasis> variables are numbered 10–19. The length is the length of
+the data string for the variable. The string itself starts at the beginning of
+the next line, and is followed by a newline character. It may contain internal
+newlines.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-aclc</option> <<emphasis>rest-of-name</emphasis>> <<emphasis>length</emphasis>></term>
+<listitem>
+<para>
+A line of this form is present for every ACL connection variable that is
+defined. Note that there is a space between <option>-aclc</option> and the rest of the name.
+The length is the length of the data string for the variable. The string itself
+starts at the beginning of the next line, and is followed by a newline
+character. It may contain internal newlines.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-aclm</option> <<emphasis>rest-of-name</emphasis>> <<emphasis>length</emphasis>></term>
+<listitem>
+<para>
+A line of this form is present for every ACL message variable that is defined.
+Note that there is a space between <option>-aclm</option> and the rest of the name. The
+length is the length of the data string for the variable. The string itself
+starts at the beginning of the next line, and is followed by a newline
+character. It may contain internal newlines.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-active_hostname</option> <<emphasis>hostname</emphasis>></term>
+<listitem>
+<para>
+This is present if, when the message was received over SMTP, the value of
+<varname>$smtp_active_hostname</varname> was different to the value of <varname>$primary_hostname</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-allow_unqualified_recipient</option></term>
+<listitem>
+<para>
+This is present if unqualified recipient addresses are permitted in header
+lines (to stop such addresses from being qualified if rewriting occurs at
+transport time). Local messages that were input using <option>-bnq</option> and remote
+messages from hosts that match <option>recipient_unqualified_hosts</option> set this flag.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-allow_unqualified_sender</option></term>
+<listitem>
+<para>
+This is present if unqualified sender addresses are permitted in header lines
+(to stop such addresses from being qualified if rewriting occurs at transport
+time). Local messages that were input using <option>-bnq</option> and remote messages from
+hosts that match <option>sender_unqualified_hosts</option> set this flag.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-auth_id</option> <<emphasis>text</emphasis>></term>
+<listitem>
+<para>
+The id information for a message received on an authenticated SMTP connection
+– the value of the <varname>$authenticated_id</varname> variable.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-auth_sender</option> <<emphasis>address</emphasis>></term>
+<listitem>
+<para>
+The address of an authenticated sender – the value of the
+<varname>$authenticated_sender</varname> variable.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-body_linecount</option> <<emphasis>number</emphasis>></term>
+<listitem>
+<para>
+This records the number of lines in the body of the message, and is
+present unless <option>-spool_file_wireformat</option> is.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-body_zerocount</option> <<emphasis>number</emphasis>></term>
+<listitem>
+<para>
+This records the number of binary zero bytes in the body of the message, and is
+present if the number is greater than zero.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-deliver_firsttime</option></term>
+<listitem>
+<para>
+This is written when a new message is first added to the spool. When the spool
+file is updated after a deferral, it is omitted.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-frozen</option> <<emphasis>time</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>frozen messages</primary>
+<secondary>spool data</secondary>
+</indexterm>
+The message is frozen, and the freezing happened at <<emphasis>time</emphasis>>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-helo_name</option> <<emphasis>text</emphasis>></term>
+<listitem>
+<para>
+This records the host name as specified by a remote host in a HELO or EHLO
+command.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-host_address</option> <<emphasis>address</emphasis>>.<<emphasis>port</emphasis>></term>
+<listitem>
+<para>
+This records the IP address of the host from which the message was received and
+the remote port number that was used. It is omitted for locally generated
+messages.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-host_auth</option> <<emphasis>text</emphasis>></term>
+<listitem>
+<para>
+If the message was received on an authenticated SMTP connection, this records
+the name of the authenticator – the value of the
+<varname>$sender_host_authenticated</varname> variable.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-host_lookup_failed</option></term>
+<listitem>
+<para>
+This is present if an attempt to look up the sending host’s name from its IP
+address failed. It corresponds to the <varname>$host_lookup_failed</varname> variable.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-host_name</option> <<emphasis>text</emphasis>></term>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>reverse DNS lookup</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>DNS</primary>
+<secondary>reverse lookup</secondary>
+</indexterm>
+This records the name of the remote host from which the message was received,
+if the host name was looked up from the IP address when the message was being
+received. It is not present if no reverse lookup was done.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-ident</option> <<emphasis>text</emphasis>></term>
+<listitem>
+<para>
+For locally submitted messages, this records the login of the originating user,
+unless it was a trusted user and the <option>-oMt</option> option was used to specify an
+ident value. For messages received over TCP/IP, this records the ident string
+supplied by the remote host, if any.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-interface_address</option> <<emphasis>address</emphasis>>.<<emphasis>port</emphasis>></term>
+<listitem>
+<para>
+This records the IP address of the local interface and the port number through
+which a message was received from a remote host. It is omitted for locally
+generated messages.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-local</option></term>
+<listitem>
+<para>
+The message is from a local sender.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-localerror</option></term>
+<listitem>
+<para>
+The message is a locally-generated bounce message.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-local_scan</option> <<emphasis>string</emphasis>></term>
+<listitem>
+<para>
+This records the data string that was returned by the <function>local_scan()</function> function
+when the message was received – the value of the <varname>$local_scan_data</varname>
+variable. It is omitted if no data was returned.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-manual_thaw</option></term>
+<listitem>
+<para>
+The message was frozen but has been thawed manually, that is, by an explicit
+Exim command rather than via the auto-thaw process.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-N</option></term>
+<listitem>
+<para>
+A testing delivery process was started using the <option>-N</option> option to suppress any
+actual deliveries, but delivery was deferred. At any further delivery attempts,
+<option>-N</option> is assumed.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-received_protocol</option></term>
+<listitem>
+<para>
+This records the value of the <varname>$received_protocol</varname> variable, which contains
+the name of the protocol by which the message was received.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-sender_set_untrusted</option></term>
+<listitem>
+<para>
+The envelope sender of this message was set by an untrusted local caller (used
+to ensure that the caller is displayed in queue listings).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-spam_score_int</option> <<emphasis>number</emphasis>></term>
+<listitem>
+<para>
+If a message was scanned by SpamAssassin, this is present. It records the value
+of <varname>$spam_score_int</varname>.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-spool_file_wireformat</option></term>
+<listitem>
+<para>
+The -D file for this message is in wire-format (for ESMTP CHUNKING)
+rather than Unix-format.
+The line-ending is CRLF rather than newline.
+There is still, however, no leading-dot-stuffing.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-tls_certificate_verified</option></term>
+<listitem>
+<para>
+A TLS certificate was received from the client that sent this message, and the
+certificate was verified by the server.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-tls_cipher</option> <<emphasis>cipher name</emphasis>></term>
+<listitem>
+<para>
+When the message was received over an encrypted connection, this records the
+name of the cipher suite that was used.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>-tls_peerdn</option> <<emphasis>peer DN</emphasis>></term>
+<listitem>
+<para>
+When the message was received over an encrypted connection, and a certificate
+was received from the client, this records the Distinguished Name from that
+certificate.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+Any of the above may have an extra hyphen prepended, to indicate the the
+corresponding data is untrusted.
+</para>
+<para>
+Following the options there is a list of those addresses to which the message
+is not to be delivered. This set of addresses is initialized from the command
+line when the <option>-t</option> option is used and <option>extract_addresses_remove_arguments</option>
+is set; otherwise it starts out empty. Whenever a successful delivery is made,
+the address is added to this set. The addresses are kept internally as a
+balanced binary tree, and it is a representation of that tree which is written
+to the spool file. If an address is expanded via an alias or forward file, the
+original address is added to the tree when deliveries to all its child
+addresses are complete.
+</para>
+<para>
+If the tree is empty, there is a single line in the spool file containing just
+the text <quote>XX</quote>. Otherwise, each line consists of two letters, which are either
+Y or N, followed by an address. The address is the value for the node of the
+tree, and the letters indicate whether the node has a left branch and/or a
+right branch attached to it, respectively. If branches exist, they immediately
+follow. Here is an example of a three-node tree:
+</para>
+<literallayout class="monospaced">
+YY darcy@austen.fict.example
+NN alice@wonderland.fict.example
+NN editor@thesaurus.ref.example
+</literallayout>
+<para>
+After the non-recipients tree, there is a list of the message’s recipients.
+This is a simple list, preceded by a count. It includes all the original
+recipients of the message, including those to whom the message has already been
+delivered. In the simplest case, the list contains one address per line. For
+example:
+</para>
+<literallayout class="monospaced">
+4
+editor@thesaurus.ref.example
+darcy@austen.fict.example
+rdo@foundation
+alice@wonderland.fict.example
+</literallayout>
+<para>
+However, when a child address has been added to the top-level addresses as a
+result of the use of the <option>one_time</option> option on a <command>redirect</command> router, each
+line is of the following form:
+</para>
+<literallayout>
+<<emphasis>top-level address</emphasis>> <<emphasis>errors_to address</emphasis>> <<emphasis>length</emphasis>>,<<emphasis>parent number</emphasis>>#<<emphasis>flag bits</emphasis>>
+</literallayout>
+<para>
+The 01 flag bit indicates the presence of the three other fields that follow
+the top-level address. Other bits may be used in future to support additional
+fields. The <<emphasis>parent number</emphasis>> is the offset in the recipients list of the
+original parent of the <quote>one time</quote> address. The first two fields are the
+envelope sender that is associated with this address and its length. If the
+length is zero, there is no special envelope sender (there are then two space
+characters in the line). A non-empty field can arise from a <command>redirect</command> router
+that has an <option>errors_to</option> setting.
+</para>
+<para>
+A blank line separates the envelope and status information from the headers
+which follow. A header may occupy several lines of the file, and to save effort
+when reading it in, each header is preceded by a number and an identifying
+character. The number is the number of characters in the header, including any
+embedded newlines and the terminating newline. The character is one of the
+following:
+</para>
+<informaltable frame="none">
+<tgroup cols="2" colsep="0" rowsep="0">
+<colspec colwidth="50pt" align="left"/>
+<colspec colwidth="254pt" align="left"/>
+<tbody>
+<row>
+<entry><<emphasis>blank</emphasis>></entry>
+<entry>header in which Exim has no special interest</entry>
+</row>
+<row>
+<entry><literal>B</literal></entry>
+<entry><emphasis>Bcc:</emphasis> header</entry>
+</row>
+<row>
+<entry><literal>C</literal></entry>
+<entry><emphasis>Cc:</emphasis> header</entry>
+</row>
+<row>
+<entry><literal>F</literal></entry>
+<entry><emphasis>From:</emphasis> header</entry>
+</row>
+<row>
+<entry><literal>I</literal></entry>
+<entry><emphasis>Message-id:</emphasis> header</entry>
+</row>
+<row>
+<entry><literal>P</literal></entry>
+<entry><emphasis>Received:</emphasis> header – P for <quote>postmark</quote></entry>
+</row>
+<row>
+<entry><literal>R</literal></entry>
+<entry><emphasis>Reply-To:</emphasis> header</entry>
+</row>
+<row>
+<entry><literal>S</literal></entry>
+<entry><emphasis>Sender:</emphasis> header</entry>
+</row>
+<row>
+<entry><literal>T</literal></entry>
+<entry><emphasis>To:</emphasis> header</entry>
+</row>
+<row>
+<entry><literal>*</literal></entry>
+<entry>replaced or deleted header</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Deleted or replaced (rewritten) headers remain in the spool file for debugging
+purposes. They are not transmitted when the message is delivered. Here is a
+typical set of headers:
+</para>
+<literallayout class="monospaced">
+111P Received: by hobbit.fict.example with local (Exim 4.00)
+id 14y9EI-00026G-00; Fri, 11 May 2001 10:28:59 +0100
+049 Message-Id: <E14y9EI-00026G-00@hobbit.fict.example>
+038* X-rewrote-sender: bb@hobbit.fict.example
+042* From: Bilbo Baggins <bb@hobbit.fict.example>
+049F From: Bilbo Baggins <B.Baggins@hobbit.fict.example>
+099* To: alice@wonderland.fict.example, rdo@foundation,
+darcy@austen.fict.example, editor@thesaurus.ref.example
+104T To: alice@wonderland.fict.example, rdo@foundation.example,
+darcy@austen.fict.example, editor@thesaurus.ref.example
+038 Date: Fri, 11 May 2001 10:28:59 +0100
+</literallayout>
+<para>
+The asterisked headers indicate that the envelope sender, <emphasis>From:</emphasis> header, and
+<emphasis>To:</emphasis> header have been rewritten, the last one because routing expanded the
+unqualified domain <emphasis>foundation</emphasis>.
+<indexterm role="concept" startref="IIDforspo1" class="endofrange"/>
+<indexterm role="concept" startref="IIDforspo2" class="endofrange"/>
+<indexterm role="concept" startref="IIDforspo3" class="endofrange"/>
+</para>
+</section>
+<section id="SECID282a">
+<title>Format of the -D file</title>
+<para>
+The data file is traditionally in Unix-standard format: lines are ended with
+an ASCII newline character.
+However, when the <option>spool_wireformat</option> main option is used some -D files
+can have an alternate format.
+This is flagged by a <option>-spool_file_wireformat</option> line in the corresponding -H file.
+The -D file lines (not including the first name-component line) are
+suitable for direct copying to the wire when transmitting using the
+ESMTP CHUNKING option, meaning lower processing overhead.
+Lines are terminated with an ASCII CRLF pair.
+There is no dot-stuffing (and no dot-termination).
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPdkim">
+<title>DKIM, SPF and DMARC</title>
+<titleabbrev>DKIM, SPF and DMARC Support</titleabbrev>
+<section id="SECDKIM">
+<title>DKIM (DomainKeys Identified Mail)</title>
+<para>
+<indexterm role="concept">
+<primary>DKIM</primary>
+</indexterm>
+</para>
+<para>
+DKIM is a mechanism by which messages sent by some entity can be provably
+linked to a domain which that entity controls. It permits reputation to
+be tracked on a per-domain basis, rather than merely upon source IP address.
+DKIM is documented in RFC 6376.
+</para>
+<para>
+As DKIM relies on the message being unchanged in transit, messages handled
+by a mailing-list (which traditionally adds to the message) will not match
+any original DKIM signature.
+</para>
+<para>
+DKIM support is compiled into Exim by default if TLS support is present.
+It can be disabled by setting DISABLE_DKIM=yes in <filename>Local/Makefile</filename>.
+</para>
+<para>
+Exim’s DKIM implementation allows for
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+Signing outgoing messages: This function is implemented in the SMTP transport.
+It can co-exist with all other Exim features
+(including transport filters)
+except cutthrough delivery.
+</para>
+</listitem>
+<listitem>
+<para>
+Verifying signatures in incoming messages: This is implemented by an additional
+ACL (acl_smtp_dkim), which can be called several times per message, with
+different signature contexts.
+</para>
+</listitem>
+</orderedlist>
+<para>
+In typical Exim style, the verification implementation does not include any
+default "policy". Instead it enables you to build your own policy using
+Exim’s standard controls.
+</para>
+<para>
+Please note that verification of DKIM signatures in incoming mail is turned
+on by default for logging (in the <= line) purposes.
+</para>
+<para>
+Additional log detail can be enabled using the <option>dkim_verbose</option> log_selector.
+When set, for each signature in incoming email,
+exim will log a line displaying the most important signature details, and the
+signature status. Here is an example (with line-breaks added for clarity):
+</para>
+<literallayout class="monospaced">
+2009-09-09 10:22:28 1MlIRf-0003LU-U3 DKIM:
+ d=facebookmail.com s=q1-2009b
+ c=relaxed/relaxed a=rsa-sha1
+ i=@facebookmail.com t=1252484542 [verification succeeded]
+</literallayout>
+<para>
+You might want to turn off DKIM verification processing entirely for internal
+or relay mail sources. To do that, set the <option>dkim_disable_verify</option> ACL
+control modifier. This should typically be done in the RCPT ACL, at points
+where you accept mail from relay sources (internal hosts or authenticated
+senders).
+</para>
+</section>
+<section id="SECDKIMSIGN">
+<title>Signing outgoing messages</title>
+<para>
+<indexterm role="concept">
+<primary>DKIM</primary>
+<secondary>signing</secondary>
+</indexterm>
+</para>
+<para>
+For signing to be usable you must have published a DKIM record in DNS.
+Note that RFC 8301 (which does not cover EC keys) says:
+</para>
+<literallayout class="monospaced">
+rsa-sha1 MUST NOT be used for signing or verifying.
+
+Signers MUST use RSA keys of at least 1024 bits for all keys.
+Signers SHOULD use RSA keys of at least 2048 bits.
+</literallayout>
+<para>
+Note also that the key content (the ’p=’ field)
+in the DNS record is different between RSA and EC keys;
+for the former it is the base64 of the ASN.1 for the RSA public key
+(equivalent to the private-key .pem with the header/trailer stripped)
+but for EC keys it is the base64 of the pure key; no ASN.1 wrapping.
+</para>
+<para>
+Signing is enabled by setting private options on the SMTP transport.
+These options take (expandable) strings as arguments.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>unset</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_domain</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>list</emphasis>†<emphasis></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+The domain(s) you want to sign with.
+After expansion, this can be a list.
+Each element in turn,
+lowercased,
+is put into the <option>$dkim_domain</option> expansion variable
+while expanding the remaining signing options.
+If it is empty after expansion, DKIM signing is not done,
+and no error will result even if <option>dkim_strict</option> is set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>unset</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_selector</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis></entry>
+<entry>Default: <emphasis>list</emphasis>†<emphasis></emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This sets the key selector string.
+After expansion, which can use <varname>$dkim_domain</varname>, this can be a list.
+Each element in turn is put in the expansion
+variable <option>$dkim_selector</option> which may be used in the <option>dkim_private_key</option>
+option along with <option>$dkim_domain</option>.
+If the option is empty after expansion, DKIM signing is not done for this domain,
+and no error will result even if <option>dkim_strict</option> is set.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dkim_private_key</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_private_key</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This sets the private key to use.
+You can use the <option>$dkim_domain</option> and
+<option>$dkim_selector</option> expansion variables to determine the private key to use.
+The result can either
+</para>
+<itemizedlist>
+<listitem>
+<para>
+be a valid RSA private key in ASCII armor (.pem file), including line breaks
+</para>
+</listitem>
+<listitem>
+<para>
+with GnuTLS 3.6.0 or OpenSSL 1.1.1 or later,
+be a valid Ed25519 private key (same format as above)
+</para>
+</listitem>
+<listitem>
+<para>
+start with a slash, in which case it is treated as a file that contains
+the private key
+</para>
+</listitem>
+<listitem>
+<para>
+be "0", "false" or the empty string, in which case the message will not
+be signed. This case will not result in an error, even if <option>dkim_strict</option>
+is set.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+To generate keys under OpenSSL:
+</para>
+<literallayout class="monospaced">
+openssl genrsa -out dkim_rsa.private 2048
+openssl rsa -in dkim_rsa.private -out /dev/stdout -pubout -outform PEM
+</literallayout>
+<para>
+The result file from the first command should be retained, and
+this option set to use it.
+Take the base-64 lines from the output of the second command, concatenated,
+for the DNS TXT record.
+See section 3.6 of RFC6376 for the record specification.
+</para>
+<para>
+Under GnuTLS:
+</para>
+<literallayout class="monospaced">
+certtool --generate-privkey --rsa --bits=2048 --password='' -8 --outfile=dkim_rsa.private
+certtool --load-privkey=dkim_rsa.private --pubkey-info
+</literallayout>
+<para>
+Note that RFC 8301 says:
+</para>
+<literallayout class="monospaced">
+Signers MUST use RSA keys of at least 1024 bits for all keys.
+Signers SHOULD use RSA keys of at least 2048 bits.
+</literallayout>
+<para>
+EC keys for DKIM are defined by RFC 8463.
+They are considerably smaller than RSA keys for equivalent protection.
+As they are a recent development, users should consider dual-signing
+(by setting a list of selectors, and an expansion for this option)
+for some transition period.
+The "_CRYPTO_SIGN_ED25519" macro will be defined if support is present
+for EC keys.
+</para>
+<para>
+OpenSSL 1.1.1 and GnuTLS 3.6.0 can create Ed25519 private keys:
+</para>
+<literallayout class="monospaced">
+openssl genpkey -algorithm ed25519 -out dkim_ed25519.private
+certtool --generate-privkey --key-type=ed25519 --outfile=dkim_ed25519.private
+</literallayout>
+<para>
+To produce the required public key value for a DNS record:
+</para>
+<literallayout class="monospaced">
+openssl pkey -outform DER -pubout -in dkim_ed25519.private | tail -c +13 | base64
+certtool --load_privkey=dkim_ed25519.private --pubkey_info --outder | tail -c +13 | base64
+</literallayout>
+<para>
+Exim also supports an alternate format
+of Ed25519 keys in DNS which was a candidate during development
+of the standard, but not adopted.
+A future release will probably drop that support.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dkim_hash</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_hash</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>sha256</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+Can be set to any one of the supported hash methods, which are:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<literal>sha1</literal> – should not be used, is old and insecure
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>sha256</literal> – the default
+</para>
+</listitem>
+<listitem>
+<para>
+<literal>sha512</literal> – possibly more secure but less well supported
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Note that RFC 8301 says:
+</para>
+<literallayout class="monospaced">
+rsa-sha1 MUST NOT be used for signing or verifying.
+</literallayout>
+<para>
+<indexterm role="option">
+<primary><option>dkim_identity</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_identity</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If set after expansion, the value is used to set an "i=" tag in
+the signing header. The DKIM standards restrict the permissible
+syntax of this optional tag to a mail address, with possibly-empty
+local part, an @, and a domain identical to or subdomain of the "d="
+tag value. Note that Exim does not check the value.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dkim_canon</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_canon</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option sets the canonicalization method used when signing a message.
+The DKIM RFC currently supports two methods: "simple" and "relaxed".
+The option defaults to "relaxed" when unset. Note: the current implementation
+only supports signing with the same canonicalization method for both headers and body.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dkim_strict</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_strict</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option defines how Exim behaves when signing a message that
+should be signed fails for some reason. When the expansion evaluates to
+either <quote>1</quote> or <quote>true</quote>, Exim will defer. Otherwise Exim will send the message
+unsigned. You can use the <option>$dkim_domain</option> and <option>$dkim_selector</option> expansion
+variables here.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dkim_sign_headers</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_sign_headers</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>string</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>see below</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+If set, this option must expand to a colon-separated
+list of header names.
+Headers with these names, or the absence or such a header, will be included
+in the message signature.
+When unspecified, the header names listed in RFC4871 will be used,
+whether or not each header is present in the message.
+The default list is available for the expansion in the macro
+<quote>_DKIM_SIGN_HEADERS</quote>
+</para>
+<para revisionflag="changed">
+and an oversigning variant is in <quote>_DKIM_OVERSIGN_HEADERS</quote>.
+</para>
+<para>
+If a name is repeated, multiple headers by that name (or the absence thereof)
+will be signed. The textually later headers in the headers part of the
+message are signed first, if there are multiples.
+</para>
+<para>
+A name can be prefixed with either an <quote>=</quote> or a <quote>+</quote> character.
+If an <quote>=</quote> prefix is used, all headers that are present with this name
+will be signed.
+If a <quote>+</quote> prefix if used, all headers that are present with this name
+will be signed, and one signature added for a missing header with the
+name will be appended.
+</para>
+<para>
+<indexterm role="option">
+<primary><option>dkim_timestamps</option></primary>
+</indexterm>
+</para>
+<informaltable frame="all">
+<tgroup cols="4" colsep="0" rowsep="0">
+<colspec colwidth="8*" align="left"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="center"/>
+<colspec colwidth="6*" align="right"/>
+<tbody>
+<row>
+<entry><option>dkim_timestamps</option></entry>
+<entry>Use: <emphasis>smtp</emphasis></entry>
+<entry>Type: <emphasis>integer</emphasis>†<emphasis></emphasis></entry>
+<entry>Default: <emphasis>unset</emphasis></entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+<para>
+This option controls the inclusion of timestamp information in the signature.
+If not set, no such information will be included.
+Otherwise, must be an unsigned number giving an offset in seconds from the current time
+for the expiry tag
+(eg. 1209600 for two weeks);
+both creation (t=) and expiry (x=) tags will be included.
+</para>
+<para>
+RFC 6376 lists these tags as RECOMMENDED.
+</para>
+</section>
+<section id="SECDKIMVFY">
+<title>Verifying DKIM signatures in incoming mail</title>
+<para>
+<indexterm role="concept">
+<primary>DKIM</primary>
+<secondary>verification</secondary>
+</indexterm>
+</para>
+<para>
+Verification of DKIM signatures in SMTP incoming email is done for all
+messages for which an ACL control <option>dkim_disable_verify</option> has not been set.
+<indexterm role="concept">
+<primary>DKIM</primary>
+<secondary>selecting signature algorithms</secondary>
+</indexterm>
+Individual classes of signature algorithm can be ignored by changing
+the main options <option>dkim_verify_hashes</option> or <option>dkim_verify_keytypes</option>.
+The <option>dkim_verify_minimal</option> option can be set to cease verification
+processing for a message once the first passing signature is found.
+</para>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>expansion item</secondary>
+</indexterm>
+Performing verification sets up information used by the
+<option>authresults</option> expansion item.
+</para>
+<para>
+For most purposes the default option settings suffice and the remainder
+of this section can be ignored.
+</para>
+<para>
+The results of verification are made available to the
+<option>acl_smtp_dkim</option> ACL, which can examine and modify them.
+A missing ACL definition defaults to accept.
+By default, the ACL is called once for each
+syntactically(!) correct signature in the incoming message.
+If any ACL call does not accept, the message is not accepted.
+If a cutthrough delivery was in progress for the message, that is
+summarily dropped (having wasted the transmission effort).
+</para>
+<para>
+To evaluate the verification result in the ACL
+a large number of expansion variables
+containing the signature status and its details are set up during the
+runtime of the ACL.
+</para>
+<para>
+Calling the ACL only for existing signatures is not sufficient to build
+more advanced policies. For that reason, the main option
+<option>dkim_verify_signers</option>, and an expansion variable
+<option>$dkim_signers</option> exist.
+</para>
+<para>
+The main option <option>dkim_verify_signers</option> can be set to a colon-separated
+list of DKIM domains or identities for which the ACL <option>acl_smtp_dkim</option> is
+called. It is expanded when the message has been received. At this point,
+the expansion variable <option>$dkim_signers</option> already contains a colon-separated
+list of signer domains and identities for the message. When
+<option>dkim_verify_signers</option> is not specified in the main configuration,
+it defaults as:
+</para>
+<literallayout class="monospaced">
+dkim_verify_signers = $dkim_signers
+</literallayout>
+<para>
+This leads to the default behaviour of calling <option>acl_smtp_dkim</option> for each
+DKIM signature in the message. Current DKIM verifiers may want to explicitly
+call the ACL for known domains or identities. This would be achieved as follows:
+</para>
+<literallayout class="monospaced">
+dkim_verify_signers = paypal.com:ebay.com:$dkim_signers
+</literallayout>
+<para>
+This would result in <option>acl_smtp_dkim</option> always being called for "paypal.com"
+and "ebay.com", plus all domains and identities that have signatures in the message.
+You can also be more creative in constructing your policy. For example:
+</para>
+<literallayout class="monospaced">
+dkim_verify_signers = $sender_address_domain:$dkim_signers
+</literallayout>
+<para>
+If a domain or identity is listed several times in the (expanded) value of
+<option>dkim_verify_signers</option>, the ACL is only called once for that domain or identity.
+</para>
+<para>
+Note that if the option is set using untrustworthy data
+(such as the From: header)
+care should be taken to force lowercase for domains
+and for the domain part if identities.
+The default setting can be regarded as trustworthy in this respect.
+</para>
+<para>
+If multiple signatures match a domain (or identity), the ACL is called once
+for each matching signature.
+</para>
+<para>
+Inside the DKIM ACL, the following expansion variables are
+available (from most to least important):
+</para>
+<variablelist>
+<varlistentry>
+<term><option>$dkim_cur_signer</option></term>
+<listitem>
+<para>
+The signer that is being evaluated in this ACL run. This can be a domain or
+an identity. This is one of the list items from the expanded main option
+<option>dkim_verify_signers</option> (see above).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_verify_status</option></term>
+<listitem>
+<para>
+Within the DKIM ACL,
+a string describing the general status of the signature. One of
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<option>none</option>: There is no signature in the message for the current domain or
+identity (as reflected by <option>$dkim_cur_signer</option>).
+</para>
+</listitem>
+<listitem>
+<para>
+<option>invalid</option>: The signature could not be verified due to a processing error.
+More detail is available in <option>$dkim_verify_reason</option>.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>fail</option>: Verification of the signature failed. More detail is
+available in <option>$dkim_verify_reason</option>.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>pass</option>: The signature passed verification. It is valid.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+This variable can be overwritten using an ACL ’set’ modifier.
+This might, for instance, be done to enforce a policy restriction on
+hash-method or key-size:
+</para>
+<literallayout class="monospaced">
+ warn condition = ${if eq {$dkim_verify_status}{pass}}
+ condition = ${if eq {${length_3:$dkim_algo}}{rsa}}
+ condition = ${if or {{eq {$dkim_algo}{rsa-sha1}} \
+ {< {$dkim_key_length}{1024}}}}
+ logwrite = NOTE: forcing DKIM verify fail (was pass)
+ set dkim_verify_status = fail
+ set dkim_verify_reason = hash too weak or key too short
+</literallayout>
+<para>
+So long as a DKIM ACL is defined (it need do no more than accept),
+after all the DKIM ACL runs have completed, the value becomes a
+colon-separated list of the values after each run.
+This is maintained for the mime, prdr and data ACLs.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_verify_reason</option></term>
+<listitem>
+<para>
+A string giving a little bit more detail when <option>$dkim_verify_status</option> is either
+"fail" or "invalid". One of
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<option>pubkey_unavailable</option> (when <option>$dkim_verify_status</option>="invalid"): The public
+key for the domain could not be retrieved. This may be a temporary problem.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>pubkey_syntax</option> (when <option>$dkim_verify_status</option>="invalid"): The public key
+record for the domain is syntactically invalid.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>bodyhash_mismatch</option> (when <option>$dkim_verify_status</option>="fail"): The calculated
+body hash does not match the one specified in the signature header. This
+means that the message body was modified in transit.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>signature_incorrect</option> (when <option>$dkim_verify_status</option>="fail"): The signature
+could not be verified. This may mean that headers were modified,
+re-written or otherwise changed in a way which is incompatible with
+DKIM verification. It may of course also mean that the signature is forged.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+This variable can be overwritten, with any value, using an ACL ’set’ modifier.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_domain</option></term>
+<listitem>
+<para>
+The signing domain. IMPORTANT: This variable is only populated if there is
+an actual signature in the message for the current domain or identity (as
+reflected by <option>$dkim_cur_signer</option>).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_identity</option></term>
+<listitem>
+<para>
+The signing identity, if present. IMPORTANT: This variable is only populated
+if there is an actual signature in the message for the current domain or
+identity (as reflected by <option>$dkim_cur_signer</option>).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_selector</option></term>
+<listitem>
+<para>
+The key record selector string.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_algo</option></term>
+<listitem>
+<para>
+The algorithm used. One of ’rsa-sha1’ or ’rsa-sha256’.
+If running under GnuTLS 3.6.0 or OpenSSL 1.1.1 or later,
+may also be ’ed25519-sha256’.
+The "_CRYPTO_SIGN_ED25519" macro will be defined if support is present
+for EC keys.
+</para>
+<para>
+Note that RFC 8301 says:
+</para>
+<literallayout class="monospaced">
+rsa-sha1 MUST NOT be used for signing or verifying.
+
+DKIM signatures identified as having been signed with historic
+algorithms (currently, rsa-sha1) have permanently failed evaluation
+</literallayout>
+<para>
+To enforce this you must either have a DKIM ACL which checks this variable
+and overwrites the <varname>$dkim_verify_status</varname> variable as discussed above,
+or have set the main option <option>dkim_verify_hashes</option> to exclude
+processing of such signatures.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_canon_body</option></term>
+<listitem>
+<para>
+The body canonicalization method. One of ’relaxed’ or ’simple’.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_canon_headers</option></term>
+<listitem>
+<para>
+The header canonicalization method. One of ’relaxed’ or ’simple’.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_copiedheaders</option></term>
+<listitem>
+<para>
+A transcript of headers and their values which are included in the signature
+(copied from the ’z=’ tag of the signature).
+Note that RFC6376 requires that verification fail if the From: header is
+not included in the signature. Exim does not enforce this; sites wishing
+strict enforcement should code the check explicitly.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_bodylength</option></term>
+<listitem>
+<para>
+The number of signed body bytes. If zero ("0"), the body is unsigned. If no
+limit was set by the signer, "9999999999999" is returned. This makes sure
+that this variable always expands to an integer value.
+<emphasis role="bold">Note:</emphasis> The presence of the signature tag specifying a signing body length
+is one possible route to spoofing of valid DKIM signatures.
+A paranoid implementation might wish to regard signature where this variable
+shows less than the "no limit" return as being invalid.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_created</option></term>
+<listitem>
+<para>
+UNIX timestamp reflecting the date and time when the signature was created.
+When this was not specified by the signer, "0" is returned.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_expires</option></term>
+<listitem>
+<para>
+UNIX timestamp reflecting the date and time when the signer wants the
+signature to be treated as "expired". When this was not specified by the
+signer, "9999999999999" is returned. This makes it possible to do useful
+integer size comparisons against this value.
+Note that Exim does not check this value.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_headernames</option></term>
+<listitem>
+<para>
+A colon-separated list of names of headers included in the signature.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_key_testing</option></term>
+<listitem>
+<para>
+"1" if the key record has the "testing" flag set, "0" if not.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_key_nosubdomains</option></term>
+<listitem>
+<para>
+"1" if the key record forbids subdomaining, "0" otherwise.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_key_srvtype</option></term>
+<listitem>
+<para>
+Service type (tag s=) from the key record. Defaults to "*" if not specified
+in the key record.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_key_granularity</option></term>
+<listitem>
+<para>
+Key granularity (tag g=) from the key record. Defaults to "*" if not specified
+in the key record.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_key_notes</option></term>
+<listitem>
+<para>
+Notes from the key record (tag n=).
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>$dkim_key_length</option></term>
+<listitem>
+<para>
+Number of bits in the key.
+</para>
+<para revisionflag="changed">
+Valid only once the key is loaded, which is at the time the header signature
+is verified, which is after the body hash is.
+</para>
+<para>
+Note that RFC 8301 says:
+</para>
+<literallayout class="monospaced">
+Verifiers MUST NOT consider signatures using RSA keys of
+less than 1024 bits as valid signatures.
+</literallayout>
+<para>
+This is enforced by the default setting for the <option>dkim_verify_min_keysizes</option>
+option.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+In addition, two ACL conditions are provided:
+</para>
+<variablelist>
+<varlistentry>
+<term><option>dkim_signers</option></term>
+<listitem>
+<para>
+ACL condition that checks a colon-separated list of domains or identities
+for a match against the domain or identity that the ACL is currently verifying
+(reflected by <option>$dkim_cur_signer</option>). This is typically used to restrict an ACL
+verb to a group of domains or identities. For example:
+</para>
+<literallayout class="monospaced">
+# Warn when Mail purportedly from GMail has no gmail signature
+warn sender_domains = gmail.com
+ dkim_signers = gmail.com
+ dkim_status = none
+ log_message = GMail sender without gmail.com DKIM signature
+</literallayout>
+<para>
+Note that the above does not check for a total lack of DKIM signing;
+for that check for empty <varname>$h_DKIM-Signature:</varname> in the data ACL.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>dkim_status</option></term>
+<listitem>
+<para>
+ACL condition that checks a colon-separated list of possible DKIM verification
+results against the actual result of verification. This is typically used
+to restrict an ACL verb to a list of verification outcomes, for example:
+</para>
+<literallayout class="monospaced">
+deny sender_domains = paypal.com:paypal.de
+ dkim_signers = paypal.com:paypal.de
+ dkim_status = none:invalid:fail
+ message = Mail from Paypal with invalid/missing signature
+</literallayout>
+<para>
+The possible status keywords are: ’none’,’invalid’,’fail’ and ’pass’. Please
+see the documentation of the <option>$dkim_verify_status</option> expansion variable above
+for more information of what they mean.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</section>
+<section id="SECSPF">
+<title>SPF (Sender Policy Framework)</title>
+<para>
+<indexterm role="concept">
+<primary>SPF</primary>
+<secondary>verification</secondary>
+</indexterm>
+</para>
+<para>
+SPF is a mechanism whereby a domain may assert which IP addresses may transmit
+messages with its domain in the envelope from, documented by RFC 7208.
+For more information on SPF see <emphasis role="bold"><ulink url="http://www.open-spf.org">http://www.open-spf.org</ulink></emphasis>, a static copy of
+the <emphasis role="bold"><ulink url="http://openspf.org">http://openspf.org</ulink></emphasis>.
+</para>
+<para>
+Messages sent by a system not authorised will fail checking of such assertions.
+This includes retransmissions done by traditional forwarders.
+</para>
+<para>
+SPF verification support is built into Exim if SUPPORT_SPF=yes is set in
+<filename>Local/Makefile</filename>. The support uses the <filename>libspf2</filename> library
+<emphasis role="bold"><ulink url="https://www.libspf2.org/">https://www.libspf2.org/</ulink></emphasis>.
+There is no Exim involvement in the transmission of messages;
+publishing certain DNS records is all that is required.
+</para>
+<para>
+For verification, an ACL condition and an expansion lookup are provided.
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>expansion item</secondary>
+</indexterm>
+Performing verification sets up information used by the
+<option>authresults</option> expansion item.
+</para>
+<para>
+<indexterm role="concept">
+<primary>SPF</primary>
+<secondary>ACL condition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ACL</primary>
+<secondary>spf condition</secondary>
+</indexterm>
+The ACL condition "spf" can be used at or after the MAIL ACL.
+It takes as an argument a list of strings giving the outcome of the SPF check,
+and will succeed for any matching outcome.
+Valid strings are:
+</para>
+<variablelist>
+<varlistentry>
+<term><option>pass</option></term>
+<listitem>
+<para>
+The SPF check passed, the sending host is positively verified by SPF.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>fail</option></term>
+<listitem>
+<para>
+The SPF check failed, the sending host is NOT allowed to send mail for the
+domain in the envelope-from address.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>softfail</option></term>
+<listitem>
+<para>
+The SPF check failed, but the queried domain can’t absolutely confirm that this
+is a forgery.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>none</option></term>
+<listitem>
+<para>
+The queried domain does not publish SPF records.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>neutral</option></term>
+<listitem>
+<para>
+The SPF check returned a "neutral" state. This means the queried domain has
+published a SPF record, but wants to allow outside servers to send mail under
+its domain as well. This should be treated like "none".
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>permerror</option></term>
+<listitem>
+<para>
+This indicates a syntax error in the SPF record of the queried domain.
+You may deny messages when this occurs.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><option>temperror</option></term>
+<listitem>
+<para>
+This indicates a temporary error during all processing, including Exim’s
+SPF processing. You may defer messages when this occurs.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+You can prefix each string with an exclamation mark to invert
+its meaning, for example "!fail" will match all results but
+"fail". The string list is evaluated left-to-right, in a
+short-circuit fashion.
+</para>
+<para>
+Example:
+</para>
+<literallayout class="monospaced">
+deny spf = fail
+ message = $sender_host_address is not allowed to send mail from \
+ ${if def:sender_address_domain \
+ {$sender_address_domain}{$sender_helo_name}}. \
+ Please see http://www.open-spf.org/Why;\
+ identity=${if def:sender_address_domain \
+ {$sender_address}{$sender_helo_name}};\
+ ip=$sender_host_address
+</literallayout>
+<para>
+Note: The above mentioned URL may not be as helpful as expected. You are
+encouraged to replace the link with a link to a site with more
+explanations.
+</para>
+<para>
+When the spf condition has run, it sets up several expansion
+variables:
+</para>
+<para>
+<indexterm role="concept">
+<primary>SPF</primary>
+<secondary>verification variables</secondary>
+</indexterm>
+</para>
+<variablelist>
+<varlistentry>
+<term><varname>$spf_header_comment</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$spf_header_comment</varname></primary>
+</indexterm>
+ This contains a human-readable string describing the outcome
+ of the SPF check. You can add it to a custom header or use
+ it for logging purposes.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$spf_received</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$spf_received</varname></primary>
+</indexterm>
+ This contains a complete Received-SPF: header that can be
+ added to the message. Please note that according to the SPF
+ draft, this header must be added at the top of the header
+ list. Please see section 10 on how you can do this.
+</para>
+<para>
+ Note: in case of "Best-guess" (see below), the convention is
+ to put this string in a header called X-SPF-Guess: instead.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$spf_result</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$spf_result</varname></primary>
+</indexterm>
+ This contains the outcome of the SPF check in string form,
+ one of pass, fail, softfail, none, neutral, permerror or
+ temperror.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$spf_result_guessed</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$spf_result_guessed</varname></primary>
+</indexterm>
+ This boolean is true only if a best-guess operation was used
+ and required in order to obtain a result.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$spf_smtp_comment</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$spf_smtp_comment</varname></primary>
+</indexterm>
+<indexterm role="variable">
+<primary><option>spf_smtp_comment_template</option></primary>
+</indexterm>
+ This contains a string that can be used in a SMTP response
+ to the calling party. Useful for "fail".
+</para>
+<para revisionflag="changed">
+ The string is generated by the SPF library from the template configured in the main config
+ option <option>spf_smtp_comment_template</option>.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+<indexterm role="concept">
+<primary>SPF</primary>
+<secondary>ACL condition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ACL</primary>
+<secondary>spf_guess condition</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SPF</primary>
+<secondary>best guess</secondary>
+</indexterm>
+In addition to SPF, you can also perform checks for so-called
+"Best-guess". Strictly speaking, "Best-guess" is not standard
+SPF, but it is supported by the same framework that enables SPF
+capability.
+Refer to <emphasis role="bold"><ulink url="http://www.open-spf.org/FAQ/Best_guess_record">http://www.open-spf.org/FAQ/Best_guess_record</ulink></emphasis>
+for a description of what it means.
+</para>
+<para>
+To access this feature, simply use the spf_guess condition in place
+of the spf one. For example:
+</para>
+<literallayout class="monospaced">
+deny spf_guess = fail
+ message = $sender_host_address doesn't look trustworthy to me
+</literallayout>
+<para>
+In case you decide to reject messages based on this check, you
+should note that although it uses the same framework, "Best-guess"
+is not SPF, and therefore you should not mention SPF at all in your
+reject message.
+</para>
+<para>
+When the spf_guess condition has run, it sets up the same expansion
+variables as when spf condition is run, described above.
+</para>
+<para>
+Additionally, since Best-guess is not standardized, you may redefine
+what "Best-guess" means to you by redefining the main configuration
+<option>spf_guess</option> option.
+For example, the following:
+</para>
+<literallayout class="monospaced">
+spf_guess = v=spf1 a/16 mx/16 ptr ?all
+</literallayout>
+<para>
+would relax host matching rules to a broader network range.
+</para>
+<para>
+<indexterm role="concept">
+<primary>SPF</primary>
+<secondary>lookup expansion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>lookup</primary>
+<secondary>spf</secondary>
+</indexterm>
+A lookup expansion is also available. It takes an email
+address as the key and an IP address
+(v4 or v6)
+as the database:
+</para>
+<literallayout class="monospaced">
+ ${lookup {username@domain} spf {ip.ip.ip.ip}}
+</literallayout>
+<para>
+The lookup will return the same result strings as can appear in
+<varname>$spf_result</varname> (pass,fail,softfail,neutral,none,err_perm,err_temp).
+</para>
+</section>
+<section id="SECDMARC">
+<title>DMARC</title>
+<para>
+<indexterm role="concept">
+<primary>DMARC</primary>
+<secondary>verification</secondary>
+</indexterm>
+</para>
+<para>
+DMARC combines feedback from SPF, DKIM, and header From: in order
+to attempt to provide better indicators of the authenticity of an
+email. This document does not explain the fundamentals; you
+should read and understand how it works by visiting the website at
+<emphasis role="bold"><ulink url="http://www.dmarc.org/">http://www.dmarc.org/</ulink></emphasis>.
+</para>
+<para>
+If Exim is built with DMARC support,
+the libopendmarc library is used.
+</para>
+<para>
+For building Exim yourself, obtain the library from
+<emphasis role="bold"><ulink url="http://sourceforge.net/projects/opendmarc/">http://sourceforge.net/projects/opendmarc/</ulink></emphasis>
+to obtain a copy, or find it in your favorite package
+repository. You will need to attend to the local/Makefile feature
+SUPPORT_DMARC and the associated LDFLAGS addition.
+This description assumes
+that headers will be in /usr/local/include, and that the libraries
+are in /usr/local/lib.
+</para>
+<para>
+There are three main-configuration options:
+<indexterm role="concept">
+<primary>DMARC</primary>
+<secondary>configuration options</secondary>
+</indexterm>
+</para>
+<para>
+The <option>dmarc_tld_file</option> option
+<indexterm role="option">
+<primary><option>dmarc_tld_file</option></primary>
+</indexterm>
+defines the location of a text file of valid
+top level domains the opendmarc library uses
+during domain parsing. Maintained by Mozilla,
+the most current version can be downloaded
+from a link at <emphasis role="bold"><ulink url="https://publicsuffix.org/list/public_suffix_list.dat">https://publicsuffix.org/list/public_suffix_list.dat</ulink></emphasis>.
+See also the util/renew-opendmarc-tlds.sh script.
+</para>
+<para revisionflag="changed">
+The default for the option is unset.
+If not set, DMARC processing is disabled.
+</para>
+<para>
+The <option>dmarc_history_file</option> option, if set
+<indexterm role="option">
+<primary><option>dmarc_history_file</option></primary>
+</indexterm>
+defines the location of a file to log results
+of dmarc verification on inbound emails. The
+contents are importable by the opendmarc tools
+which will manage the data, send out DMARC
+reports, and expire the data. Make sure the
+directory of this file is writable by the user
+exim runs as.
+The default is unset.
+</para>
+<para>
+The <option>dmarc_forensic_sender</option> option
+<indexterm role="option">
+<primary><option>dmarc_forensic_sender</option></primary>
+</indexterm>
+defines an alternate email address to use when sending a
+forensic report detailing alignment failures
+if a sender domain’s dmarc record specifies it
+and you have configured Exim to send them.
+If set, this is expanded and used for the
+From: header line; the address is extracted
+from it and used for the envelope from.
+If not set (the default), the From: header is expanded from
+the dsn_from option, and <> is used for the
+envelope from.
+</para>
+<para>
+<indexterm role="concept">
+<primary>DMARC</primary>
+<secondary>controls</secondary>
+</indexterm>
+By default, the DMARC processing will run for any remote,
+non-authenticated user. It makes sense to only verify DMARC
+status of messages coming from remote, untrusted sources. You can
+use standard conditions such as hosts, senders, etc, to decide that
+DMARC verification should *not* be performed for them and disable
+DMARC with an ACL control modifier:
+</para>
+<literallayout class="monospaced">
+ control = dmarc_disable_verify
+</literallayout>
+<para>
+A DMARC record can also specify a "forensic address", which gives
+exim an email address to submit reports about failed alignment.
+Exim does not do this by default because in certain conditions it
+results in unintended information leakage (what lists a user might
+be subscribed to, etc). You must configure exim to submit forensic
+reports to the owner of the domain. If the DMARC record contains a
+forensic address and you specify the control statement below, then
+exim will send these forensic emails. It is also advised that you
+configure a <option>dmarc_forensic_sender</option> because the default sender address
+construction might be inadequate.
+</para>
+<literallayout class="monospaced">
+ control = dmarc_enable_forensic
+</literallayout>
+<para>
+(AGAIN: You can choose not to send these forensic reports by simply
+not putting the dmarc_enable_forensic control line at any point in
+your exim config. If you don’t tell exim to send them, it will not
+send them.)
+</para>
+<para>
+There are no options to either control. Both must appear before
+the DATA acl.
+</para>
+<para>
+DMARC checks cam be run on incoming SMTP messages by using the
+<quote>dmarc_status</quote> ACL condition in the DATA ACL. You are required to
+call the <quote>spf</quote> condition first in the ACLs, then the <quote>dmarc_status</quote>
+condition. Putting this condition in the ACLs is required in order
+for a DMARC check to actually occur. All of the variables are set
+up before the DATA ACL, but there is no actual DMARC check that
+occurs until a <quote>dmarc_status</quote> condition is encountered in the ACLs.
+</para>
+<para>
+The <quote>dmarc_status</quote> condition takes a list of strings on its
+right-hand side. These strings describe recommended action based
+on the DMARC check. To understand what the policy recommendations
+mean, refer to the DMARC website above. Valid strings are:
+</para>
+<literallayout>
+<emphasis>accept </emphasis> The DMARC check passed and the library recommends accepting the email.
+<emphasis>reject </emphasis> The DMARC check failed and the library recommends rejecting the email.
+<emphasis>quarantine </emphasis> The DMARC check failed and the library recommends keeping it for further inspection.
+<emphasis>none </emphasis> The DMARC check passed and the library recommends no specific action, neutral.
+<emphasis>norecord </emphasis> No policy section in the DMARC record for this sender domain.
+<emphasis>nofrom </emphasis> Unable to determine the domain of the sender.
+<emphasis>temperror </emphasis> Library error or dns error.
+<emphasis>off </emphasis> The DMARC check was disabled for this email.
+</literallayout>
+<para>
+You can prefix each string with an exclamation mark to invert its
+meaning, for example "!accept" will match all results but
+"accept". The string list is evaluated left-to-right in a
+short-circuit fashion. When a string matches the outcome of the
+DMARC check, the condition succeeds. If none of the listed
+strings matches the outcome of the DMARC check, the condition
+fails.
+</para>
+<para>
+Of course, you can also use any other lookup method that Exim
+supports, including LDAP, Postgres, MySQL, etc, as long as the
+result is a list of colon-separated strings.
+</para>
+<para>
+Performing the check sets up information used by the
+<option>authresults</option> expansion item.
+</para>
+<para>
+Several expansion variables are set before the DATA ACL is
+processed, and you can use them in this ACL. The following
+expansion variables are available:
+</para>
+<variablelist>
+<varlistentry>
+<term><varname>$dmarc_status</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$dmarc_status</varname></primary>
+</indexterm>
+<indexterm role="concept">
+<primary>DMARC</primary>
+<secondary>result</secondary>
+</indexterm>
+A one word status indicating what the DMARC library
+thinks of the email. It is a combination of the results of
+DMARC record lookup and the SPF/DKIM/DMARC processing results
+(if a DMARC record was found). The actual policy declared
+in the DMARC record is in a separate expansion variable.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$dmarc_status_text</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$dmarc_status_text</varname></primary>
+</indexterm>
+Slightly longer, human readable status.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$dmarc_used_domain</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$dmarc_used_domain</varname></primary>
+</indexterm>
+The domain which DMARC used to look up the DMARC policy record.
+</para>
+</listitem></varlistentry>
+<varlistentry>
+<term><varname>$dmarc_domain_policy</varname></term>
+<listitem>
+<para>
+<indexterm role="variable">
+<primary><varname>$dmarc_domain_policy</varname></primary>
+</indexterm>
+The policy declared in the DMARC record. Valid values
+are "none", "reject" and "quarantine". It is blank when there
+is any error, including no DMARC record.
+</para>
+</listitem></varlistentry>
+</variablelist>
+<para>
+By default, Exim’s DMARC configuration is intended to be
+non-intrusive and conservative. To facilitate this, Exim will not
+create any type of logging files without explicit configuration by
+you, the admin. Nor will Exim send out any emails/reports about
+DMARC issues without explicit configuration by you, the admin (other
+than typical bounce messages that may come about due to ACL
+processing or failure delivery issues).
+</para>
+<para>
+In order to log statistics suitable to be imported by the opendmarc
+tools, you need to:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Configure the global option <option>dmarc_history_file</option>
+</para>
+</listitem>
+<listitem>
+<para>
+Configure cron jobs to call the appropriate opendmarc history
+import scripts and truncating the dmarc_history_file
+</para>
+</listitem>
+</itemizedlist>
+<para>
+In order to send forensic reports, you need to:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+Configure the global option <option>dmarc_forensic_sender</option>
+</para>
+</listitem>
+<listitem>
+<para>
+Configure, somewhere before the DATA ACL, the control option to
+enable sending DMARC forensic reports
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Example usage:
+</para>
+<literallayout class="monospaced">
+(RCPT ACL)
+ warn domains = +local_domains
+ hosts = +local_hosts
+ control = dmarc_disable_verify
+
+ warn !domains = +screwed_up_dmarc_records
+ control = dmarc_enable_forensic
+
+ warn condition = (lookup if destined to mailing list)
+ set acl_m_mailing_list = 1
+
+(DATA ACL)
+ warn dmarc_status = accept : none : off
+ !authenticated = *
+ log_message = DMARC DEBUG: $dmarc_status $dmarc_used_domain
+
+ warn dmarc_status = !accept
+ !authenticated = *
+ log_message = DMARC DEBUG: '$dmarc_status' for $dmarc_used_domain
+
+ warn dmarc_status = quarantine
+ !authenticated = *
+ set $acl_m_quarantine = 1
+ # Do something in a transport with this flag variable
+
+ deny condition = ${if eq{$dmarc_domain_policy}{reject}}
+ condition = ${if eq{$acl_m_mailing_list}{1}}
+ message = Messages from $dmarc_used_domain break mailing lists
+
+ deny dmarc_status = reject
+ !authenticated = *
+ message = Message from $dmarc_used_domain failed sender's DMARC policy, REJECT
+
+ warn add_header = :at_start:${authresults {$primary_hostname}}
+</literallayout>
+</section>
+</chapter>
+
+<chapter id="CHAPproxies">
+<title>Proxies</title>
+<titleabbrev>Proxy support</titleabbrev>
+<para>
+<indexterm role="concept">
+<primary>proxy support</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>proxy</primary>
+<secondary>access via</secondary>
+</indexterm>
+</para>
+<para>
+A proxy is an intermediate system through which communication is passed.
+Proxies may provide a security, availability or load-distribution function.
+</para>
+<section id="SECTproxyInbound">
+<title>Inbound proxies</title>
+<para>
+<indexterm role="concept">
+<primary>proxy</primary>
+<secondary>inbound</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>proxy</primary>
+<secondary>server side</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>proxy</primary>
+<secondary>Proxy protocol</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>Proxy protocol</primary>
+<secondary>proxy</secondary>
+</indexterm>
+</para>
+<para>
+Exim has support for receiving inbound SMTP connections via a proxy
+that uses <quote>Proxy Protocol</quote> to speak to it.
+To include this support, include <quote>SUPPORT_PROXY=yes</quote>
+in Local/Makefile.
+</para>
+<para>
+It was built on the HAProxy specification, found at
+<emphasis role="bold"><ulink url="https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt">https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt</ulink></emphasis>.
+</para>
+<para>
+The purpose of this facility is so that an application load balancer,
+such as HAProxy, can sit in front of several Exim servers
+to distribute load.
+Exim uses the local protocol communication with the proxy to obtain
+the remote SMTP system IP address and port information.
+There is no logging if a host passes or
+fails Proxy Protocol negotiation, but it can easily be determined and
+recorded in an ACL (example is below).
+</para>
+<para>
+Use of a proxy is enabled by setting the <option>hosts_proxy</option>
+main configuration option to a hostlist; connections from these
+hosts will use Proxy Protocol.
+Exim supports both version 1 and version 2 of the Proxy Protocol and
+automatically determines which version is in use.
+</para>
+<para>
+The Proxy Protocol header is the first data received on a TCP connection
+and is inserted before any TLS-on-connect handshake from the client; Exim
+negotiates TLS between Exim-as-server and the remote client, not between
+Exim and the proxy server.
+</para>
+<para>
+The following expansion variables are usable
+(<quote>internal</quote> and <quote>external</quote> here refer to the interfaces
+of the proxy):
+</para>
+<literallayout>
+<emphasis>proxy_external_address </emphasis> IP of host being proxied or IP of remote interface of proxy
+<emphasis>proxy_external_port </emphasis> Port of host being proxied or Port on remote interface of proxy
+<emphasis>proxy_local_address </emphasis> IP of proxy server inbound or IP of local interface of proxy
+<emphasis>proxy_local_port </emphasis> Port of proxy server inbound or Port on local interface of proxy
+<emphasis>proxy_session </emphasis> boolean: SMTP connection via proxy
+</literallayout>
+<para>
+If <varname>$proxy_session</varname> is set but <varname>$proxy_external_address</varname> is empty
+there was a protocol error.
+The variables <varname>$sender_host_address</varname> and <varname>$sender_host_port</varname>
+will have values for the actual client system, not the proxy.
+</para>
+<para>
+Since the real connections are all coming from the proxy, and the
+per host connection tracking is done before Proxy Protocol is
+evaluated, <option>smtp_accept_max_per_host</option> must be set high enough to
+handle all of the parallel volume you expect per inbound proxy.
+With the option set so high, you lose the ability
+to protect your server from many connections from one IP.
+In order to prevent your server from overload, you
+need to add a per connection ratelimit to your connect ACL.
+A possible solution is:
+</para>
+<literallayout>
+ # Set max number of connections per host
+ LIMIT = 5
+ # Or do some kind of IP lookup in a flat file or database
+ # LIMIT = ${lookup{$sender_host_address}iplsearch{/etc/exim/proxy_limits}}
+
+ defer ratelimit = LIMIT / 5s / per_conn / strict
+ message = Too many connections from this IP right now
+</literallayout>
+</section>
+<section id="SECTproxySOCKS">
+<title>Outbound proxies</title>
+<para>
+<indexterm role="concept">
+<primary>proxy</primary>
+<secondary>outbound</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>proxy</primary>
+<secondary>client side</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>proxy</primary>
+<secondary>SOCKS</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SOCKS</primary>
+<secondary>proxy</secondary>
+</indexterm>
+Exim has support for sending outbound SMTP via a proxy
+using a protocol called SOCKS5 (defined by RFC1928).
+The support can be optionally included by defining SUPPORT_SOCKS=yes in
+Local/Makefile.
+</para>
+<para>
+Use of a proxy is enabled by setting the <option>socks_proxy</option> option
+on an smtp transport.
+The option value is expanded and should then be a list
+(colon-separated by default) of proxy specifiers.
+Each proxy specifier is a list
+(space-separated by default) where the initial element
+is an IP address and any subsequent elements are options.
+</para>
+<para>
+Options are a string <name>=<value>.
+The list of options is in the following table:
+</para>
+<literallayout>
+<emphasis>auth </emphasis> authentication method
+<emphasis>name </emphasis> authentication username
+<emphasis>pass </emphasis> authentication password
+<emphasis>port </emphasis> tcp port
+<emphasis>tmo </emphasis> connection timeout
+<emphasis>pri </emphasis> priority
+<emphasis>weight </emphasis> selection bias
+</literallayout>
+<para>
+More details on each of these options follows:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<indexterm role="concept">
+<primary>authentication</primary>
+<secondary>to proxy</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>proxy</primary>
+<secondary>authentication</secondary>
+</indexterm>
+<option>auth</option>: Either <quote>none</quote> (default) or <quote>name</quote>.
+Using <quote>name</quote> selects username/password authentication per RFC 1929
+for access to the proxy.
+Default is <quote>none</quote>.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>name</option>: sets the username for the <quote>name</quote> authentication method.
+Default is empty.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>pass</option>: sets the password for the <quote>name</quote> authentication method.
+Default is empty.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>port</option>: the TCP port number to use for the connection to the proxy.
+Default is 1080.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>tmo</option>: sets a connection timeout in seconds for this proxy.
+Default is 5.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>pri</option>: specifies a priority for the proxy within the list,
+higher values being tried first.
+The default priority is 1.
+</para>
+</listitem>
+<listitem>
+<para>
+<option>weight</option>: specifies a selection bias.
+Within a priority set servers are queried in a random fashion,
+weighted by this value.
+The default value for selection bias is 1.
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Proxies from the list are tried according to their priority
+and weight settings until one responds. The timeout for the
+overall connection applies to the set of proxied attempts.
+</para>
+</section>
+<section id="SECTproxyLog">
+<title>Logging</title>
+<para>
+To log the (local) IP of a proxy in the incoming or delivery logline,
+add <quote>+proxy</quote> to the <option>log_selector</option> option.
+This will add a component tagged with <quote>PRX=</quote> to the line.
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPi18n">
+<title>Internationalisation</title>
+<titleabbrev>Internationalisation"</titleabbrev>
+<para>
+<indexterm role="concept">
+<primary>internationalisation</primary>
+<secondary>email address</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>EAI</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>i18n</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>utf8</primary>
+<secondary>mail name handling</secondary>
+</indexterm>
+</para>
+<para>
+Exim has support for Internationalised mail names.
+To include this it must be built with SUPPORT_I18N and the libidn library.
+Standards supported are RFCs 2060, 5890, 6530 and 6533.
+</para>
+<para>
+If Exim is built with SUPPORT_I18N_2008 (in addition to SUPPORT_I18N, not
+instead of it) then IDNA2008 is supported; this adds an extra library
+requirement, upon libidn2.
+</para>
+<section id="SECTi18nMTA">
+<title>MTA operations</title>
+<para>
+<indexterm role="concept">
+<primary>SMTPUTF8</primary>
+<secondary>ESMTP option</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>ESMTP extensions</primary>
+<secondary>SMTPUTF8</secondary>
+</indexterm>
+The main configuration option <option>smtputf8_advertise_hosts</option> specifies
+a host list. If this matches the sending host and
+accept_8bitmime is true (the default) then the ESMTP option
+SMTPUTF8 will be advertised.
+</para>
+<para>
+If the sender specifies the SMTPUTF8 option on a MAIL command
+international handling for the message is enabled and
+the expansion variable <varname>$message_smtputf8</varname> will have value TRUE.
+</para>
+<para>
+The option <option>allow_utf8_domains</option> is set to true for this
+message. All DNS lookups are converted to a-label form
+whatever the setting of <option>allow_utf8_domains</option>
+when Exim is built with SUPPORT_I18N.
+</para>
+<para>
+Both localparts and domain are maintained as the original
+UTF-8 form internally; any comparison or regular-expression use will
+require appropriate care. Filenames created, eg. by
+the appendfile transport, will have UTF-8 names.
+</para>
+<para>
+HELO names sent by the smtp transport will have any UTF-8
+components expanded to a-label form,
+and any certificate name checks will be done using the a-label
+form of the name.
+</para>
+<para>
+<indexterm role="concept">
+<primary>log</primary>
+<secondary>protocol</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>SMTPUTF8</primary>
+<secondary>logging</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>i18n</primary>
+<secondary>logging</secondary>
+</indexterm>
+Log lines and Received-by: header lines will acquire a "utf8"
+prefix on the protocol element, eg. utf8esmtp.
+</para>
+<para>
+The following expansion operators can be used:
+</para>
+<literallayout class="monospaced">
+${utf8_domain_to_alabel:str}
+${utf8_domain_from_alabel:str}
+${utf8_localpart_to_alabel:str}
+${utf8_localpart_from_alabel:str}
+</literallayout>
+<para>
+<indexterm role="concept">
+<primary>utf8</primary>
+<secondary>address downconversion</secondary>
+</indexterm>
+<indexterm role="concept">
+<primary>i18n</primary>
+<secondary>utf8 address downconversion</secondary>
+</indexterm>
+The RCPT ACL
+may use the following modifier:
+</para>
+<literallayout>
+control = utf8_downconvert
+control = utf8_downconvert/<value>
+</literallayout>
+<para>
+This sets a flag requiring that envelope addresses are converted to
+a-label form before smtp delivery.
+This is usually for use in a Message Submission Agent context,
+but could be used for any message.
+</para>
+<para>
+If a value is appended it may be:
+</para>
+<literallayout>
+<literal>1 </literal> mandatory downconversion
+<literal>0 </literal> no downconversion
+<literal>-1 </literal> if SMTPUTF8 not supported by destination host
+</literallayout>
+<para>
+If no value is given, 1 is used.
+</para>
+<para>
+If mua_wrapper is set, the utf8_downconvert control
+is initially set to -1.
+</para>
+<para>
+The smtp transport has an option <option>utf8_downconvert</option>.
+If set it must expand to one of the three values described above,
+or an empty string.
+If non-empty it overrides value previously set
+(due to mua_wrapper or by an ACL control).
+</para>
+<para>
+There is no explicit support for VRFY and EXPN.
+Configurations supporting these should inspect
+<varname>$smtp_command_argument</varname> for an SMTPUTF8 argument.
+</para>
+<para>
+There is no support for LMTP on Unix sockets.
+Using the "lmtp" protocol option on an smtp transport,
+for LMTP over TCP, should work as expected.
+</para>
+<para>
+There is no support for DSN unitext handling,
+and no provision for converting logging from or to UTF-8.
+</para>
+</section>
+<section id="SECTi18nMDA">
+<title>MDA operations</title>
+<para>
+To aid in constructing names suitable for IMAP folders
+the following expansion operator can be used:
+</para>
+<literallayout class="monospaced">
+${imapfolder {<string>} {<sep>} {<specials>}}
+</literallayout>
+<para>
+The string is converted from the charset specified by
+the "headers charset" command (in a filter file)
+or <option>headers_charset</option> main configuration option (otherwise),
+to the
+modified UTF-7 encoding specified by RFC 2060,
+with the following exception: All occurrences of <sep>
+(which has to be a single character)
+are replaced with periods ("."), and all periods and slashes that are not
+<sep> and are not in the <specials> string are BASE64 encoded.
+</para>
+<para>
+The third argument can be omitted, defaulting to an empty string.
+The second argument can be omitted, defaulting to "/".
+</para>
+<para>
+This is the encoding used by Courier for Maildir names on disk, and followed
+by many other IMAP servers.
+</para>
+<para>
+Examples:
+</para>
+<literallayout>
+<literal>${imapfolder {Foo/Bar}} </literal> yields <literal>Foo.Bar</literal>
+<literal>${imapfolder {Foo/Bar}{.}{/}} </literal> yields <literal>Foo&AC8-Bar</literal>
+<literal>${imapfolder {Räksmörgås}} </literal> yields <literal>R&AOQ-ksm&APY-rg&AOU-s</literal>
+</literallayout>
+<para>
+Note that the source charset setting is vital, and also that characters
+must be representable in UTF-16.
+</para>
+</section>
+</chapter>
+
+<chapter id="CHAPevents">
+<title>Events</title>
+<titleabbrev>Events</titleabbrev>
+<para>
+<indexterm role="concept">
+<primary>events</primary>
+</indexterm>
+</para>
+<para>
+The events mechanism in Exim can be used to intercept processing at a number
+of points. It was originally invented to give a way to do customised logging
+actions (for example, to a database) but can also be used to modify some
+processing actions.
+</para>
+<para>
+Most installations will never need to use Events.
+The support can be left out of a build by defining DISABLE_EVENT=yes
+in <filename>Local/Makefile</filename>.
+</para>
+<para>
+There are two major classes of events: main and transport.
+The main configuration option <option>event_action</option> controls reception events;
+a transport option <option>event_action</option> controls delivery events.
+</para>
+<para>
+Both options are a string which is expanded when the event fires.
+An example might look like:
+<indexterm role="concept">
+<primary>logging</primary>
+<secondary>custom</secondary>
+</indexterm>
+</para>
+<literallayout class="monospaced">
+event_action = ${if eq {msg:delivery}{$event_name} \
+{${lookup pgsql {SELECT * FROM record_Delivery( \
+ '${quote_pgsql:$sender_address_domain}',\
+ '${quote_pgsql:${lc:$sender_address_local_part}}', \
+ '${quote_pgsql:$domain}', \
+ '${quote_pgsql:${lc:$local_part}}', \
+ '${quote_pgsql:$host_address}', \
+ '${quote_pgsql:${lc:$host}}', \
+ '${quote_pgsql:$message_exim_id}')}} \
+} {}}
+</literallayout>
+<para>
+Events have names which correspond to the point in process at which they fire.
+The name is placed in the variable <varname>$event_name</varname> and the event action
+expansion must check this, as it will be called for every possible event type.
+</para>
+<para revisionflag="changed">
+The current list of events is:
+</para>
+<literallayout>
+<literal>dane:fail after transport </literal> per connection
+<literal>msg:complete after main </literal> per message
+<literal>msg:defer after transport </literal> per message per delivery try
+<literal>msg:delivery after transport </literal> per recipient
+<literal>msg:rcpt:host:defer after transport </literal> per recipient per host
+<literal>msg:rcpt:defer after transport </literal> per recipient
+<literal>msg:host:defer after transport </literal> per host per delivery try; host errors
+<literal>msg:fail:delivery after transport </literal> per recipient
+<literal>msg:fail:internal after main </literal> per recipient
+<literal>tcp:connect before transport </literal> per connection
+<literal>tcp:close after transport </literal> per connection
+<literal>tls:cert before both </literal> per certificate in verification chain
+<literal>smtp:connect after transport </literal> per connection
+<literal>smtp:ehlo after transport </literal> per connection
+</literallayout>
+<para>
+New event types may be added in future.
+</para>
+<para>
+The event name is a colon-separated list, defining the type of
+event in a tree of possibilities. It may be used as a list
+or just matched on as a whole. There will be no spaces in the name.
+</para>
+<para>
+The second column in the table above describes whether the event fires
+before or after the action is associates with. Those which fire before
+can be used to affect that action (more on this below).
+</para>
+<para>
+The third column in the table above says what section of the configuration
+should define the event action.
+</para>
+<para>
+An additional variable, <varname>$event_data</varname>, is filled with information varying
+with the event type:
+</para>
+<literallayout>
+<literal>dane:fail </literal> failure reason
+<literal>msg:defer </literal> error string
+<literal>msg:delivery </literal> smtp confirmation message
+<literal>msg:fail:internal </literal> failure reason
+<literal>msg:fail:delivery </literal> smtp error message
+<literal>msg:host:defer </literal> error string
+<literal>msg:rcpt:host:defer </literal> error string
+<literal>msg:rcpt:defer </literal> error string
+<literal>tls:cert </literal> verification chain depth
+<literal>smtp:connect </literal> smtp banner
+<literal>smtp:ehlo </literal> smtp ehlo response
+</literallayout>
+<para>
+The :defer events populate one extra variable: <varname>$event_defer_errno</varname>.
+</para>
+<para>
+For complex operations an ACL expansion can be used in <option>event_action</option>
+however due to the multiple contexts that Exim operates in during
+the course of its processing:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+variables set in transport events will not be visible outside that
+transport call
+</para>
+</listitem>
+<listitem>
+<para>
+acl_m variables in a server context are lost on a new connection,
+and after smtp helo/ehlo/mail/starttls/rset commands
+</para>
+</listitem>
+</itemizedlist>
+<para>
+Using an ACL expansion with the logwrite modifier can be
+a useful way of writing to the main log.
+</para>
+<para>
+The expansion of the event_action option should normally
+return an empty string. Should it return anything else the
+following will be forced:
+</para>
+<literallayout>
+<literal>tcp:connect </literal> do not connect
+<literal>tls:cert </literal> refuse verification
+<literal>smtp:connect </literal> close connection
+</literallayout>
+<para>
+All other message types ignore the result string, and
+no other use is made of it.
+</para>
+<para>
+For a tcp:connect event, if the connection is being made to a proxy
+then the address and port variables will be that of the proxy and not
+the target system.
+</para>
+<para>
+For tls:cert events, if GnuTLS is in use this will trigger only per
+chain element received on the connection.
+For OpenSSL it will trigger for every chain element including those
+loaded locally.
+</para>
+</chapter>
+
+<chapter id="CHID13">
+<title>Adding new drivers or lookup types</title>
+<titleabbrev>Adding drivers or lookups</titleabbrev>
+<para>
+<indexterm role="concept">
+<primary>adding drivers</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>new drivers, adding</primary>
+</indexterm>
+<indexterm role="concept">
+<primary>drivers</primary>
+<secondary>adding new</secondary>
+</indexterm>
+The following actions have to be taken in order to add a new router, transport,
+authenticator, or lookup type to Exim:
+</para>
+<orderedlist numeration="arabic">
+<listitem>
+<para>
+Choose a name for the driver or lookup type that does not conflict with any
+existing name; I will use <quote>newdriver</quote> in what follows.
+</para>
+</listitem>
+<listitem>
+<para>
+Add to <filename>src/EDITME</filename> the line:
+</para>
+<literallayout>
+<<emphasis>type</emphasis>><literal>_NEWDRIVER=yes</literal>
+</literallayout>
+<para>
+where <<emphasis>type</emphasis>> is ROUTER, TRANSPORT, AUTH, or LOOKUP. If the
+code is not to be included in the binary by default, comment this line out. You
+should also add any relevant comments about the driver or lookup type.
+</para>
+</listitem>
+<listitem>
+<para>
+Add to <filename>src/config.h.defaults</filename> the line:
+</para>
+<literallayout class="monospaced">
+#define <type>_NEWDRIVER
+</literallayout>
+</listitem>
+<listitem>
+<para>
+Edit <filename>src/drtables.c</filename>, adding conditional code to pull in the private header
+and create a table entry as is done for all the other drivers and lookup types.
+</para>
+</listitem>
+<listitem>
+<para>
+Edit <filename>scripts/lookups-Makefile</filename> if this is a new lookup; there is a for-loop
+near the bottom, ranging the <literal>name_mod</literal> variable over a list of all lookups.
+Add your <literal>NEWDRIVER</literal> to that list.
+As long as the dynamic module would be named <filename>newdriver.so</filename>, you can use the
+simple form that most lookups have.
+</para>
+</listitem>
+<listitem>
+<para>
+Edit <filename>Makefile</filename> in the appropriate sub-directory (<filename>src/routers</filename>,
+<filename>src/transports</filename>, <filename>src/auths</filename>, or <filename>src/lookups</filename>); add a line for the new
+driver or lookup type and add it to the definition of OBJ.
+</para>
+</listitem>
+<listitem>
+<para>
+Edit <filename>OS/Makefile-Base</filename> adding a <filename>.o</filename> file for the predefined-macros, to the
+definition of OBJ_MACRO. Add a set of line to do the compile also.
+</para>
+</listitem>
+<listitem>
+<para>
+Create <filename>newdriver.h</filename> and <filename>newdriver.c</filename> in the appropriate sub-directory of
+<filename>src</filename>.
+</para>
+</listitem>
+<listitem>
+<para>
+Edit <filename>scripts/MakeLinks</filename> and add commands to link the <filename>.h</filename> and <filename>.c</filename> files
+as for other drivers and lookups.
+</para>
+</listitem>
+</orderedlist>
+<para>
+Then all you need to do is write the code! A good way to start is to make a
+proforma by copying an existing module of the same type, globally changing all
+occurrences of the name, and cutting out most of the code. Note that any
+options you create must be listed in alphabetical order, because the tables are
+searched using a binary chop procedure.
+</para>
+<para>
+There is a <filename>README</filename> file in each of the sub-directories of <filename>src</filename> describing
+the interface that is expected.
+</para>
+<?sdop
+ format="newpage"
+ foot_right_recto="&chaptertitle;"
+ foot_right_verso="&chaptertitle;"
+?>
+</chapter>
+
+<index role="option">
+<title>Options index</title>
+</index>
+
+<index role="variable">
+<title>Variables index</title>
+</index>
+
+<index role="concept">
+<title>Concept index</title>
+</index>
+
+</book>